diff --git a/contrib/pam_zfs_key/pam_zfs_key.c b/contrib/pam_zfs_key/pam_zfs_key.c index 4cafc37b9..0856c7534 100644 --- a/contrib/pam_zfs_key/pam_zfs_key.c +++ b/contrib/pam_zfs_key/pam_zfs_key.c @@ -82,7 +82,11 @@ alloc_pw_size(size_t len) return (NULL); } pw->len = len; - pw->value = malloc(len); + /* + * The use of malloc() triggers a spurious gcc 11 -Wmaybe-uninitialized + * warning in the mlock() function call below, so use calloc(). + */ + pw->value = calloc(len, 1); if (!pw->value) { free(pw); return (NULL); @@ -99,7 +103,11 @@ alloc_pw_string(const char *source) return (NULL); } pw->len = strlen(source) + 1; - pw->value = malloc(pw->len); + /* + * The use of malloc() triggers a spurious gcc 11 -Wmaybe-uninitialized + * warning in the mlock() function call below, so use calloc(). + */ + pw->value = calloc(pw->len, 1); if (!pw->value) { free(pw); return (NULL); diff --git a/include/sys/crypto/api.h b/include/sys/crypto/api.h index 7c3c46551..8aecfeaff 100644 --- a/include/sys/crypto/api.h +++ b/include/sys/crypto/api.h @@ -58,7 +58,7 @@ typedef struct { */ #define CRYPTO_MECH_INVALID ((uint64_t)-1) -extern crypto_mech_type_t crypto_mech2id(crypto_mech_name_t name); +extern crypto_mech_type_t crypto_mech2id(char *name); /* * Create and destroy context templates. diff --git a/include/sys/dnode.h b/include/sys/dnode.h index 3208b60f0..de6492bb7 100644 --- a/include/sys/dnode.h +++ b/include/sys/dnode.h @@ -171,7 +171,7 @@ enum dnode_dirtycontext { * example, reading 32 dnodes from a 16k dnode block and all of the spill * blocks could issue 33 separate reads. Now suppose those dnodes have size * 1024 and therefore don't need spill blocks. Then the worst case number - * of blocks read is reduced to from 33 to two--one per dnode block. + * of blocks read is reduced from 33 to two--one per dnode block. * * ZFS-on-Linux systems that make heavy use of extended attributes benefit * from this feature. In particular, ZFS-on-Linux supports the xattr=sa @@ -232,8 +232,8 @@ typedef struct dnode_phys { * Both dn_pad2 and dn_pad3 are protected by the block's MAC. This * allows us to protect any fields that might be added here in the * future. In either case, developers will want to check - * zio_crypt_init_uios_dnode() to ensure the new field is being - * protected properly. + * zio_crypt_init_uios_dnode() and zio_crypt_do_dnode_hmac_updates() + * to ensure the new field is being protected and updated properly. */ uint64_t dn_pad3[4]; diff --git a/module/os/linux/zfs/zio_crypt.c b/module/os/linux/zfs/zio_crypt.c index 94406999c..52e62f4d1 100644 --- a/module/os/linux/zfs/zio_crypt.c +++ b/module/os/linux/zfs/zio_crypt.c @@ -190,7 +190,7 @@ unsigned long zfs_key_max_salt_uses = ZFS_KEY_MAX_SALT_USES_DEFAULT; typedef struct blkptr_auth_buf { uint64_t bab_prop; /* blk_prop - portable mask */ - uint8_t bab_mac[ZIO_DATA_MAC_LEN]; /* MAC from blk_cksum */ + uint8_t bab_mac[ZIO_DATA_MAC_LEN]; /* MAC from blk_cksum */ uint64_t bab_pad; /* reserved for future use */ } blkptr_auth_buf_t; @@ -1045,17 +1045,23 @@ zio_crypt_do_dnode_hmac_updates(crypto_context_t ctx, uint64_t version, boolean_t should_bswap, dnode_phys_t *dnp) { int ret, i; - dnode_phys_t *adnp; + dnode_phys_t *adnp, tmp_dncore; + size_t dn_core_size = offsetof(dnode_phys_t, dn_blkptr); boolean_t le_bswap = (should_bswap == ZFS_HOST_BYTEORDER); crypto_data_t cd; - uint8_t tmp_dncore[offsetof(dnode_phys_t, dn_blkptr)]; cd.cd_format = CRYPTO_DATA_RAW; cd.cd_offset = 0; - /* authenticate the core dnode (masking out non-portable bits) */ - bcopy(dnp, tmp_dncore, sizeof (tmp_dncore)); - adnp = (dnode_phys_t *)tmp_dncore; + /* + * Authenticate the core dnode (masking out non-portable bits). + * We only copy the first 64 bytes we operate on to avoid the overhead + * of copying 512-64 unneeded bytes. The compiler seems to be fine + * with that. + */ + bcopy(dnp, &tmp_dncore, dn_core_size); + adnp = &tmp_dncore; + if (le_bswap) { adnp->dn_datablkszsec = BSWAP_16(adnp->dn_datablkszsec); adnp->dn_bonuslen = BSWAP_16(adnp->dn_bonuslen); @@ -1065,7 +1071,7 @@ zio_crypt_do_dnode_hmac_updates(crypto_context_t ctx, uint64_t version, adnp->dn_flags &= DNODE_CRYPT_PORTABLE_FLAGS_MASK; adnp->dn_used = 0; - cd.cd_length = sizeof (tmp_dncore); + cd.cd_length = dn_core_size; cd.cd_raw.iov_base = (char *)adnp; cd.cd_raw.iov_len = cd.cd_length;