libzfs.h: Set ZFS_MAXPROPLEN and ZPOOL_MAXPROPLEN to ZAP_MAXVALUELEN

So far, the values of ZFS_MAXPROPLEN and ZPOOL_MAXPROPLEN were equal to
MAXPATHLEN, which is 1024 on FreeBSD and 4096 on Linux. This wasn't
ideal. Some of the surprising outcomes of this implementation are:

1. When creating a pool user property with zpool-set(8), libzfs makes
   sure that the length of the property's value is less than
   ZFS_MAXPROPLEN. However, the ZFS kernel module does not do that.
   Instead, it checks the length against ZAP_MAXVALUELEN. As a result,
   it is possible to create a property the length of which is going to
   be larger than zpool(8) is ready to read.
2. A pool user property created on Linux is too big to be read on
   FreeBSD.

This change sets both ZFS_MAXPROPLEN and ZPOOL_MAXPROPLEN to
ZAP_MAXVALUELEN, which is 8192 at the moment.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Mateusz Piotrowski <0mp@FreeBSD.org>
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Closes #16248
This commit is contained in:
Mateusz Piotrowski 2024-06-05 11:59:11 +02:00 committed by Brian Behlendorf
parent 2558518c5d
commit 24e6585e76
4 changed files with 10 additions and 26 deletions

View File

@ -51,8 +51,8 @@ extern "C" {
/*
* Miscellaneous ZFS constants
*/
#define ZFS_MAXPROPLEN MAXPATHLEN
#define ZPOOL_MAXPROPLEN MAXPATHLEN
#define ZFS_MAXPROPLEN ZAP_MAXVALUELEN
#define ZPOOL_MAXPROPLEN ZAP_MAXVALUELEN
/*
* libzfs errors

View File

@ -210,19 +210,15 @@ log_must local_cleanup
log_note "verify clone list truncated correctly"
fs=$TESTPOOL/$TESTFS1
xs=""; for i in {1..200}; do xs+="x"; done
if is_linux; then
ZFS_MAXPROPLEN=4096
else
ZFS_MAXPROPLEN=1024
fi
maxproplen=8192
log_must zfs create $fs
log_must zfs snapshot $fs@snap
for (( i = 1; i <= (ZFS_MAXPROPLEN / 200 + 1); i++ )); do
for (( i = 1; i <= (maxproplen / 200 + 1); i++ )); do
log_must zfs clone ${fs}@snap ${fs}/${TESTCLONE}${xs}.${i}
done
clone_list=$(zfs list -o clones $fs@snap)
char_count=$(echo "$clone_list" | tail -1 | wc -c)
[[ $char_count -eq $ZFS_MAXPROPLEN ]] || \
[[ $char_count -eq $maxproplen ]] || \
log_fail "Clone list not truncated correctly. Unexpected character count" \
"$char_count"

View File

@ -56,16 +56,10 @@ typeset -a values=()
# for the null byte)
names+=("$(awk 'BEGIN { printf "x:"; while (c++ < (256 - 2 - 1)) printf "a" }')")
values+=("long-property-name")
# Longest property value (the limits are 1024 on FreeBSD and 4096 on Linux, so
# pick the right one; the longest value can use limit minus 1 bytes for the
# null byte)
if is_linux; then
typeset ZFS_MAXPROPLEN=4096
else
typeset ZFS_MAXPROPLEN=1024
fi
# Longest property value (8191 bytes, which is the 8192-byte limit minus 1 byte
# for the null byte).
names+=("long:property:value")
values+=("$(awk -v max="$ZFS_MAXPROPLEN" 'BEGIN { while (c++ < (max - 1)) printf "A" }')")
values+=("$(awk 'BEGIN { while (c++ < (8192 - 1)) printf "A" }')")
# Valid property names
for i in {1..10}; do
typeset -i len

View File

@ -64,17 +64,11 @@ names+=("$(awk '
}'
)")
values+=("too-long-property-name")
# A property value that is too long consists of at least 1024 bytes on FreeBSD
# and 4096 bytes on Linux.
# A property value that is too long consists of at least 8192 bytes.
# The smallest too-long value is (1) the limit (2) minus 1 byte for the null
# byte (2) plus 1 byte to reach back over the limit).
if is_linux; then
typeset ZFS_MAXPROPLEN=4096
else
typeset ZFS_MAXPROPLEN=1024
fi
names+=("too:long:property:value")
values+=("$(awk -v max="$ZFS_MAXPROPLEN" 'BEGIN { while (c++ < (max - 1 + 1)) printf "A" }')")
values+=("$(awk 'BEGIN { while (c++ < (8192 - 1 + 1)) printf "A" }')")
# Invalid property names
for i in {1..10}; do
typeset -i len