Skip to content

Commit 21a932b

Browse files
authored
Post-Encryption Followup
This PR includes fixes for bugs and documentation issues found after the encryption patch was merged and general code improvements for long-term maintainability. Reviewed-by: Jorgen Lundman <lundman@lundman.net> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tom Caputi <tcaputi@datto.com> Issue #6526 Closes #6639 Closes #6703 Cloese #6706 Closes #6714 Closes #6595
2 parents cdc15a7 + 9bae371 commit 21a932b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1299
-547
lines changed

COPYRIGHT

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@ approved for release under LLNL-CODE-403049.
2323

2424
Unless otherwise noted, all files in this distribution are released
2525
under the Common Development and Distribution License (CDDL).
26-
Exceptions are noted within the associated source files. See the file
27-
OPENSOLARIS.LICENSE for more information.
26+
Exceptions are noted within the associated source files. A few notable
27+
exceptions and their respective licenses include:
28+
29+
Skein Checksum Implementation: module/icp/algs/skein/THIRDPARTYLICENSE
30+
AES Implementation: module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.gladman
31+
AES Implementation: module/icp/asm-x86_64/aes/THIRDPARTYLICENSE.openssl
32+
PBKDF2 Implementation: lib/libzfs/THIRDPARTYLICENSE.openssl
33+
34+
This product includes software developed by the OpenSSL Project for use
35+
in the OpenSSL Toolkit (http://www.openssl.org/)
36+
37+
See the file OPENSOLARIS.LICENSE for more information.
2838

2939
Refer to the git commit log for authoritative copyright attribution.

cmd/zfs/zfs_main.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7267,28 +7267,27 @@ zfs_do_change_key(int argc, char **argv)
72677267
keystatus = zfs_prop_get_int(zhp, ZFS_PROP_KEYSTATUS);
72687268
if (keystatus != ZFS_KEYSTATUS_AVAILABLE) {
72697269
ret = zfs_crypto_load_key(zhp, B_FALSE, NULL);
7270-
if (ret != 0)
7271-
goto error;
7270+
if (ret != 0) {
7271+
nvlist_free(props);
7272+
zfs_close(zhp);
7273+
return (-1);
7274+
}
72727275
}
72737276

7274-
/* refresh the properties so the new keystatus is visable */
7277+
/* refresh the properties so the new keystatus is visible */
72757278
zfs_refresh_properties(zhp);
72767279
}
72777280

72787281
ret = zfs_crypto_rewrap(zhp, props, inheritkey);
7279-
if (ret != 0)
7280-
goto error;
7282+
if (ret != 0) {
7283+
nvlist_free(props);
7284+
zfs_close(zhp);
7285+
return (-1);
7286+
}
72817287

72827288
nvlist_free(props);
72837289
zfs_close(zhp);
72847290
return (0);
7285-
7286-
error:
7287-
if (props != NULL)
7288-
nvlist_free(props);
7289-
if (zhp != NULL)
7290-
zfs_close(zhp);
7291-
return (-1);
72927291
}
72937292

72947293
int

cmd/zpool/zpool_main.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8049,10 +8049,17 @@ main(int argc, char **argv)
80498049
* 'freeze' is a vile debugging abomination, so we treat
80508050
* it as such.
80518051
*/
8052-
char buf[16384];
8053-
int fd = open(ZFS_DEV, O_RDWR);
8054-
(void) strlcpy((void *)buf, argv[2], sizeof (buf));
8055-
return (!!ioctl(fd, ZFS_IOC_POOL_FREEZE, buf));
8052+
zfs_cmd_t zc = {"\0"};
8053+
8054+
(void) strlcpy(zc.zc_name, argv[2], sizeof (zc.zc_name));
8055+
ret = zfs_ioctl(g_zfs, ZFS_IOC_POOL_FREEZE, &zc);
8056+
if (ret != 0) {
8057+
(void) fprintf(stderr,
8058+
gettext("failed to freeze pool: %d\n"), errno);
8059+
ret = 1;
8060+
}
8061+
8062+
log_history = 0;
80568063
} else {
80578064
(void) fprintf(stderr, gettext("unrecognized "
80588065
"command '%s'\n"), cmdname);

cmd/ztest/ztest.c

Lines changed: 110 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ extern int zfs_abd_scatter_enabled;
201201

202202
static ztest_shared_opts_t *ztest_shared_opts;
203203
static ztest_shared_opts_t ztest_opts;
204+
static char *ztest_wkeydata = "abcdefghijklmnopqrstuvwxyz012345";
204205

205206
typedef struct ztest_shared_ds {
206207
uint64_t zd_seq;
@@ -1180,6 +1181,42 @@ ztest_spa_prop_set_uint64(zpool_prop_t prop, uint64_t value)
11801181
return (error);
11811182
}
11821183

1184+
static int
1185+
ztest_dmu_objset_own(const char *name, dmu_objset_type_t type,
1186+
boolean_t readonly, boolean_t decrypt, void *tag, objset_t **osp)
1187+
{
1188+
int err;
1189+
1190+
err = dmu_objset_own(name, type, readonly, decrypt, tag, osp);
1191+
if (decrypt && err == EACCES) {
1192+
char ddname[ZFS_MAX_DATASET_NAME_LEN];
1193+
dsl_crypto_params_t *dcp;
1194+
nvlist_t *crypto_args = fnvlist_alloc();
1195+
char *cp = NULL;
1196+
1197+
/* spa_keystore_load_wkey() expects a dsl dir name */
1198+
strcpy(ddname, name);
1199+
cp = strchr(ddname, '@');
1200+
if (cp != NULL)
1201+
*cp = '\0';
1202+
1203+
fnvlist_add_uint8_array(crypto_args, "wkeydata",
1204+
(uint8_t *)ztest_wkeydata, WRAPPING_KEY_LEN);
1205+
VERIFY0(dsl_crypto_params_create_nvlist(DCP_CMD_NONE, NULL,
1206+
crypto_args, &dcp));
1207+
err = spa_keystore_load_wkey(ddname, dcp, B_FALSE);
1208+
dsl_crypto_params_free(dcp, B_FALSE);
1209+
fnvlist_free(crypto_args);
1210+
1211+
if (err != 0)
1212+
return (err);
1213+
1214+
err = dmu_objset_own(name, type, readonly, decrypt, tag, osp);
1215+
}
1216+
1217+
return (err);
1218+
}
1219+
11831220

11841221
/*
11851222
* Object and range lock mechanics
@@ -1921,7 +1958,7 @@ ztest_replay_write(ztest_ds_t *zd, lr_write_t *lr, boolean_t byteswap)
19211958
dmu_write(os, lr->lr_foid, offset, length, data, tx);
19221959
} else {
19231960
bcopy(data, abuf->b_data, length);
1924-
dmu_assign_arcbuf(db, offset, abuf, tx);
1961+
dmu_assign_arcbuf_by_dbuf(db, offset, abuf, tx);
19251962
}
19261963

19271964
(void) ztest_log_write(zd, tx, lr);
@@ -3532,11 +3569,57 @@ ztest_objset_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
35323569
static int
35333570
ztest_dataset_create(char *dsname)
35343571
{
3535-
uint64_t zilset = ztest_random(100);
3536-
int err = dmu_objset_create(dsname, DMU_OST_OTHER, 0, NULL,
3572+
int err;
3573+
uint64_t rand;
3574+
dsl_crypto_params_t *dcp = NULL;
3575+
3576+
/*
3577+
* 50% of the time, we create encrypted datasets
3578+
* using a random cipher suite and a hard-coded
3579+
* wrapping key.
3580+
*/
3581+
rand = ztest_random(2);
3582+
if (rand != 0) {
3583+
nvlist_t *crypto_args = fnvlist_alloc();
3584+
nvlist_t *props = fnvlist_alloc();
3585+
3586+
/* slight bias towards the default cipher suite */
3587+
rand = ztest_random(ZIO_CRYPT_FUNCTIONS);
3588+
if (rand < ZIO_CRYPT_AES_128_CCM)
3589+
rand = ZIO_CRYPT_ON;
3590+
3591+
fnvlist_add_uint64(props,
3592+
zfs_prop_to_name(ZFS_PROP_ENCRYPTION), rand);
3593+
fnvlist_add_uint8_array(crypto_args, "wkeydata",
3594+
(uint8_t *)ztest_wkeydata, WRAPPING_KEY_LEN);
3595+
3596+
/*
3597+
* These parameters aren't really used by the kernel. They
3598+
* are simply stored so that userspace knows how to load
3599+
* the wrapping key.
3600+
*/
3601+
fnvlist_add_uint64(props,
3602+
zfs_prop_to_name(ZFS_PROP_KEYFORMAT), ZFS_KEYFORMAT_RAW);
3603+
fnvlist_add_string(props,
3604+
zfs_prop_to_name(ZFS_PROP_KEYLOCATION), "prompt");
3605+
fnvlist_add_uint64(props,
3606+
zfs_prop_to_name(ZFS_PROP_PBKDF2_SALT), 0ULL);
3607+
fnvlist_add_uint64(props,
3608+
zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS), 0ULL);
3609+
3610+
VERIFY0(dsl_crypto_params_create_nvlist(DCP_CMD_NONE, props,
3611+
crypto_args, &dcp));
3612+
3613+
fnvlist_free(crypto_args);
3614+
fnvlist_free(props);
3615+
}
3616+
3617+
err = dmu_objset_create(dsname, DMU_OST_OTHER, 0, dcp,
35373618
ztest_objset_create_cb, NULL);
3619+
dsl_crypto_params_free(dcp, !!err);
35383620

3539-
if (err || zilset < 80)
3621+
rand = ztest_random(100);
3622+
if (err || rand < 80)
35403623
return (err);
35413624

35423625
if (ztest_opts.zo_verbose >= 5)
@@ -3556,7 +3639,8 @@ ztest_objset_destroy_cb(const char *name, void *arg)
35563639
/*
35573640
* Verify that the dataset contains a directory object.
35583641
*/
3559-
VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, B_TRUE, FTAG, &os));
3642+
VERIFY0(ztest_dmu_objset_own(name, DMU_OST_OTHER, B_TRUE,
3643+
B_TRUE, FTAG, &os));
35603644
error = dmu_object_info(os, ZTEST_DIROBJ, &doi);
35613645
if (error != ENOENT) {
35623646
/* We could have crashed in the middle of destroying it */
@@ -3640,11 +3724,12 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
36403724
* (invoked from ztest_objset_destroy_cb()) should just throw it away.
36413725
*/
36423726
if (ztest_random(2) == 0 &&
3643-
dmu_objset_own(name, DMU_OST_OTHER, B_FALSE,
3727+
ztest_dmu_objset_own(name, DMU_OST_OTHER, B_FALSE,
36443728
B_TRUE, FTAG, &os) == 0) {
36453729
ztest_zd_init(zdtmp, NULL, os);
36463730
zil_replay(os, zdtmp, ztest_replay_vector);
36473731
ztest_zd_fini(zdtmp);
3732+
txg_wait_synced(dmu_objset_pool(os), 0);
36483733
dmu_objset_disown(os, B_TRUE, FTAG);
36493734
}
36503735

@@ -3659,8 +3744,8 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
36593744
/*
36603745
* Verify that the destroyed dataset is no longer in the namespace.
36613746
*/
3662-
VERIFY3U(ENOENT, ==, dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, B_TRUE,
3663-
FTAG, &os));
3747+
VERIFY3U(ENOENT, ==, ztest_dmu_objset_own(name, DMU_OST_OTHER, B_TRUE,
3748+
B_TRUE, FTAG, &os));
36643749

36653750
/*
36663751
* Verify that we can create a new dataset.
@@ -3674,7 +3759,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
36743759
fatal(0, "dmu_objset_create(%s) = %d", name, error);
36753760
}
36763761

3677-
VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, B_TRUE,
3762+
VERIFY0(ztest_dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, B_TRUE,
36783763
FTAG, &os));
36793764

36803765
ztest_zd_init(zdtmp, NULL, os);
@@ -3710,10 +3795,11 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
37103795
/*
37113796
* Verify that we cannot own an objset that is already owned.
37123797
*/
3713-
VERIFY3U(EBUSY, ==,
3714-
dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, B_TRUE, FTAG, &os2));
3798+
VERIFY3U(EBUSY, ==, ztest_dmu_objset_own(name, DMU_OST_OTHER,
3799+
B_FALSE, B_TRUE, FTAG, &os2));
37153800

37163801
zil_close(zilog);
3802+
txg_wait_synced(spa_get_dsl(os->os_spa), 0);
37173803
dmu_objset_disown(os, B_TRUE, FTAG);
37183804
ztest_zd_fini(zdtmp);
37193805
out:
@@ -3868,7 +3954,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
38683954
fatal(0, "dmu_objset_create(%s) = %d", clone2name, error);
38693955
}
38703956

3871-
error = dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, B_TRUE,
3957+
error = ztest_dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, B_TRUE,
38723958
FTAG, &os);
38733959
if (error)
38743960
fatal(0, "dmu_objset_own(%s) = %d", snap2name, error);
@@ -4260,7 +4346,7 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
42604346
* bigobj, at the tail of the nth chunk
42614347
*
42624348
* The chunk size is set equal to bigobj block size so that
4263-
* dmu_assign_arcbuf() can be tested for object updates.
4349+
* dmu_assign_arcbuf_by_dbuf() can be tested for object updates.
42644350
*/
42654351

42664352
/*
@@ -4322,7 +4408,7 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
43224408
/*
43234409
* In iteration 5 (i == 5) use arcbufs
43244410
* that don't match bigobj blksz to test
4325-
* dmu_assign_arcbuf() when it can't directly
4411+
* dmu_assign_arcbuf_by_dbuf() when it can't directly
43264412
* assign an arcbuf to a dbuf.
43274413
*/
43284414
for (j = 0; j < s; j++) {
@@ -4368,8 +4454,8 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
43684454

43694455
/*
43704456
* 50% of the time don't read objects in the 1st iteration to
4371-
* test dmu_assign_arcbuf() for the case when there're no
4372-
* existing dbufs for the specified offsets.
4457+
* test dmu_assign_arcbuf_by_dbuf() for the case when there are
4458+
* no existing dbufs for the specified offsets.
43734459
*/
43744460
if (i != 0 || ztest_random(2) != 0) {
43754461
error = dmu_read(os, packobj, packoff,
@@ -4414,12 +4500,12 @@ ztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
44144500
FTAG, &dbt, DMU_READ_NO_PREFETCH) == 0);
44154501
}
44164502
if (i != 5 || chunksize < (SPA_MINBLOCKSIZE * 2)) {
4417-
dmu_assign_arcbuf(bonus_db, off,
4503+
dmu_assign_arcbuf_by_dbuf(bonus_db, off,
44184504
bigbuf_arcbufs[j], tx);
44194505
} else {
4420-
dmu_assign_arcbuf(bonus_db, off,
4506+
dmu_assign_arcbuf_by_dbuf(bonus_db, off,
44214507
bigbuf_arcbufs[2 * j], tx);
4422-
dmu_assign_arcbuf(bonus_db,
4508+
dmu_assign_arcbuf_by_dbuf(bonus_db,
44234509
off + chunksize / 2,
44244510
bigbuf_arcbufs[2 * j + 1], tx);
44254511
}
@@ -6262,7 +6348,8 @@ ztest_dataset_open(int d)
62626348
}
62636349
ASSERT(error == 0 || error == EEXIST);
62646350

6265-
VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, B_TRUE, zd, &os));
6351+
VERIFY0(ztest_dmu_objset_own(name, DMU_OST_OTHER, B_FALSE,
6352+
B_TRUE, zd, &os));
62666353
(void) rw_unlock(&ztest_name_lock);
62676354

62686355
ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os);
@@ -6303,6 +6390,7 @@ ztest_dataset_close(int d)
63036390
ztest_ds_t *zd = &ztest_ds[d];
63046391

63056392
zil_close(zd->zd_zilog);
6393+
txg_wait_synced(spa_get_dsl(zd->zd_os->os_spa), 0);
63066394
dmu_objset_disown(zd->zd_os, B_TRUE, zd);
63076395

63086396
ztest_zd_fini(zd);
@@ -6355,7 +6443,7 @@ ztest_run(ztest_shared_t *zs)
63556443
ztest_spa = spa;
63566444

63576445
dmu_objset_stats_t dds;
6358-
VERIFY0(dmu_objset_own(ztest_opts.zo_pool,
6446+
VERIFY0(ztest_dmu_objset_own(ztest_opts.zo_pool,
63596447
DMU_OST_ANY, B_TRUE, B_TRUE, FTAG, &os));
63606448
dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
63616449
dmu_objset_fast_stat(os, &dds);
@@ -6582,11 +6670,10 @@ ztest_freeze(void)
65826670
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
65836671
ASSERT(spa_freeze_txg(spa) == UINT64_MAX);
65846672
VERIFY3U(0, ==, ztest_dataset_open(0));
6585-
ztest_dataset_close(0);
6586-
65876673
spa->spa_debug = B_TRUE;
65886674
ztest_spa = spa;
65896675
txg_wait_synced(spa_get_dsl(spa), 0);
6676+
ztest_dataset_close(0);
65906677
ztest_reguid(NULL, 0);
65916678

65926679
spa_close(spa, FTAG);

config/user-libssl.m4

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
dnl #
2+
dnl # Check for libssl. Used for userspace password derivation via PBKDF2.
3+
dnl #
4+
AC_DEFUN([ZFS_AC_CONFIG_USER_LIBSSL], [
5+
LIBSSL=
6+
7+
AC_CHECK_HEADER([openssl/evp.h], [], [AC_MSG_FAILURE([
8+
*** evp.h missing, libssl-devel package required])])
9+
10+
AC_SUBST([LIBSSL], ["-lssl -lcrypto"])
11+
AC_DEFINE([HAVE_LIBSSL], 1, [Define if you have libssl])
12+
])

config/user.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
1313
ZFS_AC_CONFIG_USER_LIBBLKID
1414
ZFS_AC_CONFIG_USER_LIBATTR
1515
ZFS_AC_CONFIG_USER_LIBUDEV
16+
ZFS_AC_CONFIG_USER_LIBSSL
1617
ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
1718
ZFS_AC_CONFIG_USER_RUNSTATEDIR
1819
ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ AC_CONFIG_FILES([
248248
tests/zfs-tests/tests/functional/grow_pool/Makefile
249249
tests/zfs-tests/tests/functional/grow_replicas/Makefile
250250
tests/zfs-tests/tests/functional/history/Makefile
251+
tests/zfs-tests/tests/functional/hkdf/Makefile
251252
tests/zfs-tests/tests/functional/inheritance/Makefile
252253
tests/zfs-tests/tests/functional/inuse/Makefile
253254
tests/zfs-tests/tests/functional/large_files/Makefile

contrib/dracut/90zfs/module-setup.sh.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ installkernel() {
2525
instmods znvpair
2626
instmods zavl
2727
instmods zunicode
28+
instmods icp
2829
instmods spl
2930
instmods zlib_deflate
3031
instmods zlib_inflate

include/sys/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ COMMON_H = \
3535
$(top_srcdir)/include/sys/dsl_userhold.h \
3636
$(top_srcdir)/include/sys/edonr.h \
3737
$(top_srcdir)/include/sys/efi_partition.h \
38+
$(top_srcdir)/include/sys/hkdf.h \
3839
$(top_srcdir)/include/sys/metaslab.h \
3940
$(top_srcdir)/include/sys/metaslab_impl.h \
4041
$(top_srcdir)/include/sys/mmp.h \

0 commit comments

Comments
 (0)