summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2016-08-05 11:44:06 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2016-08-05 11:44:06 +0000
commit498af06a42ecbb363e60543186de1d11578c8e9a (patch)
tree717c11b965117651f23abfc66e5ef61546589d65
parent171573f2b91f8c975e78e2658c05730e9427467e (diff)
parent0af1cc2c200dcee1cb119ba8e280ebacdbfcf839 (diff)
downloadillumos-joyent-498af06a42ecbb363e60543186de1d11578c8e9a.tar.gz
[illumos-gate merge]
commit 0af1cc2c200dcee1cb119ba8e280ebacdbfcf839 7207 properly document pollhead_clean() commit 2dc235874d66f757a3abf5072f6c3fd4ca7d0979 6005 bootadm update-archive should create/update archive sha-1 hash Conflicts: usr/src/man/man9f/pollhead_clean.9f
-rw-r--r--usr/src/cmd/boot/bootadm/Makefile5
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.c42
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.h3
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm_digest.c243
-rw-r--r--usr/src/cmd/boot/scripts/create_ramdisk.ksh4
-rw-r--r--usr/src/man/man9f/pollhead_clean.9f5
-rw-r--r--usr/src/pkg/manifests/system-kernel.man9f.inc1
7 files changed, 296 insertions, 7 deletions
diff --git a/usr/src/cmd/boot/bootadm/Makefile b/usr/src/cmd/boot/bootadm/Makefile
index be838e34f7..64616469be 100644
--- a/usr/src/cmd/boot/bootadm/Makefile
+++ b/usr/src/cmd/boot/bootadm/Makefile
@@ -23,13 +23,14 @@
# Use is subject to license terms.
#
# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2016 Toomas Soome <tsoome@me.com>
#
PROG= bootadm
SBINLINKS= $(PROG)
-OBJS= bootadm.o bootadm_upgrade.o bootadm_hyper.o
+OBJS= bootadm.o bootadm_upgrade.o bootadm_hyper.o bootadm_digest.o
SRCS = $(OBJS:.o=.c)
include ../Makefile.com
@@ -38,7 +39,7 @@ include ../Makefile.com
.KEEP_STATE:
LDLIBS_i386= -lfdisk
-LDLIBS += -lnvpair -lgen -ladm -lefi -lscf -lz -lbe -lzfs $(LDLIBS_$(MACH))
+LDLIBS += -lpkcs11 -lcryptoutil -lnvpair -lgen -ladm -lefi -lscf -lz -lbe -lzfs $(LDLIBS_$(MACH))
# Writing into string literals is incorrect. We need to match gcc's
# behavior, which causes us to take SIGSEGV on such a write.
diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c
index ba62ba3d7a..a5a1490a72 100644
--- a/usr/src/cmd/boot/bootadm/bootadm.c
+++ b/usr/src/cmd/boot/bootadm/bootadm.c
@@ -26,6 +26,7 @@
* Copyright 2012 Milan Jurik. All rights reserved.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2015 by Delphix. All rights reserved.
+ * Copyright 2016 Toomas Soome <tsoome@me.com>
*/
/*
@@ -3363,6 +3364,40 @@ to_733(unsigned char *s, unsigned int val)
}
/*
+ * creates sha1 hash of archive
+ */
+static int
+digest_archive(const char *archive)
+{
+ char *archive_hash;
+ char *hash;
+ int ret;
+ FILE *fp;
+
+ (void) asprintf(&archive_hash, "%s.hash", archive);
+ if (archive_hash == NULL)
+ return (BAM_ERROR);
+
+ if ((ret = bootadm_digest(archive, &hash)) == BAM_ERROR) {
+ free(archive_hash);
+ return (ret);
+ }
+
+ fp = fopen(archive_hash, "w");
+ if (fp == NULL) {
+ free(archive_hash);
+ free(hash);
+ return (BAM_ERROR);
+ }
+
+ (void) fprintf(fp, "%s\n", hash);
+ (void) fclose(fp);
+ free(hash);
+ free(archive_hash);
+ return (BAM_SUCCESS);
+}
+
+/*
* Extends the current boot archive without recreating it from scratch
*/
static int
@@ -3495,6 +3530,9 @@ extend_iso_archive(char *archive, char *tempname, char *update_dir)
(void) unlink(tempname);
+ if (digest_archive(archive) == BAM_ERROR && bam_verbose)
+ bam_print("boot archive hashing failed\n");
+
if (flushfs(bam_root) != 0)
sync();
@@ -3623,6 +3661,9 @@ mkisofs_archive(char *root, int what)
get_cachedir(what));
}
+ if (digest_archive(boot_archive) == BAM_ERROR && bam_verbose)
+ bam_print("boot archive hashing failed\n");
+
if (ret == BAM_SUCCESS && bam_verbose)
bam_print("Successfully created %s\n", boot_archive);
@@ -3656,6 +3697,7 @@ create_ramdisk(char *root)
/*
* Else setup command args for create_ramdisk.ksh for the UFS archives
+ * Note: we will not create hash here, CREATE_RAMDISK should create it.
*/
if (bam_verbose)
bam_print("mkisofs not found, creating UFS archive\n");
diff --git a/usr/src/cmd/boot/bootadm/bootadm.h b/usr/src/cmd/boot/bootadm/bootadm.h
index 6d5c5c73ca..b59d860e4e 100644
--- a/usr/src/cmd/boot/bootadm/bootadm.h
+++ b/usr/src/cmd/boot/bootadm/bootadm.h
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2016 Toomas Soome <tsoome@me.com>.
*/
#ifndef _BOOTADM_H
@@ -188,6 +190,7 @@ extern void unlink_line(menu_t *mp, line_t *lp);
extern void line_free(line_t *lp);
extern char *s_strdup(char *);
extern int is_sparc(void);
+extern int bootadm_digest(const char *, char **);
#define BAM_MAXLINE 8192
diff --git a/usr/src/cmd/boot/bootadm/bootadm_digest.c b/usr/src/cmd/boot/bootadm/bootadm_digest.c
new file mode 100644
index 0000000000..ea95c686e8
--- /dev/null
+++ b/usr/src/cmd/boot/bootadm/bootadm_digest.c
@@ -0,0 +1,243 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
+ * Copyright 2016 Toomas Soome <tsoome@me.com>
+ */
+
+/*
+ * Create sha1 hash for file.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <security/cryptoki.h>
+#include <cryptoutil.h>
+#include <locale.h>
+#include "bootadm.h"
+
+#define BUFFERSIZE (1024 * 64)
+#define RESULTLEN (512)
+static CK_BYTE buf[BUFFERSIZE];
+
+/*
+ * do_digest - Compute digest of a file. Borrowed from digest.
+ *
+ * hSession - session
+ * pmech - ptr to mechanism to be used for digest
+ * fd - file descriptor
+ * pdigest - buffer where digest result is returned
+ * pdigestlen - length of digest buffer on input,
+ * length of result on output
+ */
+static CK_RV
+do_digest(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pmech,
+ int fd, CK_BYTE_PTR *pdigest, CK_ULONG_PTR pdigestlen)
+{
+ CK_RV rv;
+ ssize_t nread;
+ int err;
+
+ if ((rv = C_DigestInit(hSession, pmech)) != CKR_OK) {
+ return (rv);
+ }
+
+ while ((nread = read(fd, buf, sizeof (buf))) > 0) {
+ /* Get the digest */
+ rv = C_DigestUpdate(hSession, buf, (CK_ULONG)nread);
+ if (rv != CKR_OK)
+ return (rv);
+ }
+
+ /* There was a read error */
+ if (nread == -1) {
+ err = errno;
+ bam_print(gettext("error reading file: %s\n"), strerror(err));
+ return (CKR_GENERAL_ERROR);
+ }
+
+ rv = C_DigestFinal(hSession, *pdigest, pdigestlen);
+
+ /* result too big to fit? Allocate a bigger buffer */
+ if (rv == CKR_BUFFER_TOO_SMALL) {
+ *pdigest = realloc(*pdigest, *pdigestlen);
+
+ if (*pdigest == NULL) {
+ err = errno;
+ bam_print(gettext("realloc: %s\n"), strerror(err));
+ return (CKR_HOST_MEMORY);
+ }
+
+ rv = C_DigestFinal(hSession, *pdigest, pdigestlen);
+ }
+
+ return (rv);
+}
+
+int
+bootadm_digest(const char *filename, char **result)
+{
+ int fd;
+ CK_RV rv;
+ CK_ULONG slotcount;
+ CK_SLOT_ID slotID;
+ CK_SLOT_ID_PTR pSlotList = NULL;
+ CK_MECHANISM_TYPE mech_type = CKM_SHA_1;
+ CK_MECHANISM_INFO info;
+ CK_MECHANISM mech;
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
+ CK_BYTE_PTR resultbuf = NULL;
+ CK_ULONG resultlen;
+ char *resultstr = NULL;
+ int resultstrlen;
+ int i, exitcode;
+
+ /* Initialize, and get list of slots */
+ rv = C_Initialize(NULL);
+ if (rv != CKR_OK && rv != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
+ bam_print(gettext(
+ "failed to initialize PKCS #11 framework: %s\n"),
+ pkcs11_strerror(rv));
+ return (BAM_ERROR);
+ }
+
+ /* Get slot count */
+ rv = C_GetSlotList(0, NULL, &slotcount);
+ if (rv != CKR_OK || slotcount == 0) {
+ bam_print(gettext(
+ "failed to find any cryptographic provider: %s\n"),
+ pkcs11_strerror(rv));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ /* Found at least one slot, allocate memory for slot list */
+ pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
+ if (pSlotList == NULL) {
+ bam_print(gettext("out of memory\n"));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ /* Get the list of slots */
+ if ((rv = C_GetSlotList(0, pSlotList, &slotcount)) != CKR_OK) {
+ bam_print(gettext(
+ "failed to find any cryptographic provider; "
+ "please check with your system administrator: %s\n"),
+ pkcs11_strerror(rv));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ /* Find a slot with matching mechanism */
+ for (i = 0; i < slotcount; i++) {
+ slotID = pSlotList[i];
+ rv = C_GetMechanismInfo(slotID, mech_type, &info);
+ if (rv != CKR_OK) {
+ continue; /* to the next slot */
+ } else {
+ if (info.flags & CKF_DIGEST)
+ break;
+ }
+ }
+
+ /* Show error if no matching mechanism found */
+ if (i == slotcount) {
+ bam_print(gettext("no cryptographic provider was "
+ "found for sha1\n"));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ /* Mechanism is supported. Go ahead & open a session */
+ rv = C_OpenSession(slotID, CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+
+ if (rv != CKR_OK) {
+ bam_print(gettext("can not open PKCS#11 session: %s\n"),
+ pkcs11_strerror(rv));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ /* Allocate a buffer to store result. */
+ resultlen = RESULTLEN;
+ if ((resultbuf = malloc(resultlen)) == NULL) {
+ bam_print(gettext("out of memory\n"));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ mech.mechanism = mech_type;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+ exitcode = BAM_SUCCESS;
+
+ if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) == -1) {
+ bam_print(gettext("can not open input file %s\n"), filename);
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ rv = do_digest(hSession, &mech, fd, &resultbuf, &resultlen);
+
+ if (rv != CKR_OK) {
+ bam_print(gettext("crypto operation failed for "
+ "file %s: %s\n"), filename, pkcs11_strerror(rv));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ /* Allocate a buffer to store result string */
+ resultstrlen = 2 * resultlen + 1;
+ if ((resultstr = malloc(resultstrlen)) == NULL) {
+ bam_print(gettext("out of memory\n"));
+ exitcode = BAM_ERROR;
+ goto cleanup;
+ }
+
+ tohexstr(resultbuf, resultlen, resultstr, resultstrlen);
+
+ (void) close(fd);
+cleanup:
+ if (exitcode == BAM_ERROR) {
+ free(resultstr);
+ resultstr = NULL;
+ }
+
+ free(resultbuf);
+ free(pSlotList);
+
+ if (hSession != CK_INVALID_HANDLE)
+ (void) C_CloseSession(hSession);
+
+ (void) C_Finalize(NULL);
+
+ *result = resultstr;
+ return (exitcode);
+}
diff --git a/usr/src/cmd/boot/scripts/create_ramdisk.ksh b/usr/src/cmd/boot/scripts/create_ramdisk.ksh
index abcad516a0..4fec8809a2 100644
--- a/usr/src/cmd/boot/scripts/create_ramdisk.ksh
+++ b/usr/src/cmd/boot/scripts/create_ramdisk.ksh
@@ -20,8 +20,10 @@
# CDDL HEADER END
#
+# Copyright 2016 Toomas Soome <tsoome@me.com>
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+#
#
# Copyright (c) 2014 by Delphix. All rights reserved.
@@ -427,6 +429,8 @@ function create_archive
else
lockfs -f "/$ALT_ROOT" 2>/dev/null
mv "${archive}-new" "$archive"
+ rm -f "$archive.hash"
+ digest -a sha1 "$archive" > "$archive.hash"
lockfs -f "/$ALT_ROOT" 2>/dev/null
fi
diff --git a/usr/src/man/man9f/pollhead_clean.9f b/usr/src/man/man9f/pollhead_clean.9f
index a163a65a51..2823bd71aa 100644
--- a/usr/src/man/man9f/pollhead_clean.9f
+++ b/usr/src/man/man9f/pollhead_clean.9f
@@ -30,11 +30,9 @@ pollhead_clean \- inform the kernel that a pollhead is being deallocated
.fi
.SH INTERFACE LEVEL
-.sp
.LP
Architecture independent level 1 (DDI/DKI).
.SH PARAMETERS
-.sp
.ne 2
.na
\fB\fIphp\fR\fR
@@ -44,7 +42,6 @@ Pointer to a \fBpollhead\fR structure.
.RE
.SH DESCRIPTION
-.sp
.LP
The \fBpollhead_clean()\fR function informs the kernel that a driver's
\fBpollhead\fR structure is about to be deallocated, usually as part of
@@ -52,13 +49,11 @@ the driver's \fBclose\fR(9E) entry point before the software state that
contains the \fBpollhead\fR is deallocated via \fBddi_soft_state_free\fR(9F).
See \fBchpoll\fR(9E), \fBpollwakeup\fR(9E) and \fBpoll\fR(2) for more detail.
.SH CONTEXT
-.sp
.LP
The \fBpollhead_clean()\fR function is generally called from the context
of a \fBclose\fR(9E) entry point, but may be called from user or kernel
context.
.SH SEE ALSO
-.sp
.LP
\fBpoll\fR(2), \fBchpoll\fR(9E), \fBpollwakeup\fR(9E)
diff --git a/usr/src/pkg/manifests/system-kernel.man9f.inc b/usr/src/pkg/manifests/system-kernel.man9f.inc
index a9046569c0..1d5056b298 100644
--- a/usr/src/pkg/manifests/system-kernel.man9f.inc
+++ b/usr/src/pkg/manifests/system-kernel.man9f.inc
@@ -390,6 +390,7 @@ file path=usr/share/man/man9f/pm_busy_component.9f
file path=usr/share/man/man9f/pm_power_has_changed.9f
file path=usr/share/man/man9f/pm_raise_power.9f
file path=usr/share/man/man9f/pm_trans_check.9f
+file path=usr/share/man/man9f/pollhead_clean.9f
file path=usr/share/man/man9f/pollwakeup.9f
file path=usr/share/man/man9f/priv_getbyname.9f
file path=usr/share/man/man9f/priv_policy.9f