get_key_material: skip passphrase validation when loading keys

The restriction that an encryption key must be at least
MIN_PASSPHRASE_LEN characters long make sense when changing the
encryption key, but not when loading: as this restriction is not
enforced in the libraries, it is possible to bypass zfs change-key's
restrictions and end up with a key that becomes impossible to load with
zfs load-key, for example through pam_zfs_key.

Reviewed-by: Felix Dörre <felix@dogcraft.de>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Harald van Dijk <harald@gigawatt.nl>
Closes #12765
This commit is contained in:
Harald van Dijk 2021-10-20 00:32:28 +01:00 committed by Brian Behlendorf
parent 4234812d1a
commit 85638aa870

View File

@ -200,7 +200,7 @@ get_format_prompt_string(zfs_keyformat_t format)
/* do basic validation of the key material */ /* do basic validation of the key material */
static int static int
validate_key(libzfs_handle_t *hdl, zfs_keyformat_t keyformat, validate_key(libzfs_handle_t *hdl, zfs_keyformat_t keyformat,
const char *key, size_t keylen) const char *key, size_t keylen, boolean_t do_verify)
{ {
switch (keyformat) { switch (keyformat) {
case ZFS_KEYFORMAT_RAW: case ZFS_KEYFORMAT_RAW:
@ -245,7 +245,10 @@ validate_key(libzfs_handle_t *hdl, zfs_keyformat_t keyformat,
} }
break; break;
case ZFS_KEYFORMAT_PASSPHRASE: case ZFS_KEYFORMAT_PASSPHRASE:
/* verify the length is within bounds */ /* verify the length is within bounds when setting a new key,
* but not when loading an existing key */
if (!do_verify)
break;
if (keylen > MAX_PASSPHRASE_LEN) { if (keylen > MAX_PASSPHRASE_LEN) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"Passphrase too long (max %u)."), "Passphrase too long (max %u)."),
@ -380,7 +383,8 @@ get_key_interactive(libzfs_handle_t *restrict hdl, const char *fsname,
if (!confirm_key) if (!confirm_key)
goto out; goto out;
if ((ret = validate_key(hdl, keyformat, buf, buflen)) != 0) { if ((ret = validate_key(hdl, keyformat, buf, buflen, confirm_key)) !=
0) {
free(buf); free(buf);
return (ret); return (ret);
} }
@ -740,7 +744,8 @@ get_key_material(libzfs_handle_t *hdl, boolean_t do_verify, boolean_t newkey,
goto error; goto error;
} }
if ((ret = validate_key(hdl, keyformat, (const char *)km, kmlen)) != 0) if ((ret = validate_key(hdl, keyformat, (const char *)km, kmlen,
do_verify)) != 0)
goto error; goto error;
*km_out = km; *km_out = km;