From e551954defe7f782597a2a96b5be9320c5658999 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 13 Mar 2023 23:28:58 +0900 Subject: [PATCH 1/2] udev: mention that the kernel silently truncates lo_file_name if too long Resolves the confusion in https://github.com/systemd/systemd/pull/26693#discussion_r1131151335. --- src/udev/udev-builtin-blkid.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index 154cf7000f9..2b2205513b1 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -287,12 +287,14 @@ static int read_loopback_backing_inode( if (isempty((char*) info.lo_file_name) || strnlen((char*) info.lo_file_name, sizeof(info.lo_file_name)-1) == sizeof(info.lo_file_name)-1) - /* Don't pick up file name if it is unset or possibly truncated. (Note: we can't really know - * the file file name is truncated if it uses sizeof(info.lo_file_name)-1 as length; it could - * also just mean the string is just that long and wasn't truncated — but the fact is simply - * that we cannot know in that case if it was truncated or not, hence we assume the worst and - * suppress — at least for now. For shorter strings we know for sure it wasn't truncated, - * hence that's always safe.) */ + /* Don't pick up file name if it is unset or possibly truncated. (Note: the kernel silently + * truncates the string passed from userspace by LOOP_SET_STATUS64 ioctl. See + * loop_set_status_from_info() in drivers/block/loop.c. Hence, we can't really know the file + * name is truncated if it uses sizeof(info.lo_file_name)-1 as length; it could also mean the + * string is just that long and wasn't truncated — but the fact is simply that we cannot know + * in that case if it was truncated or not. Thus, we assume the worst and suppress — at least + * for now. For shorter strings we know for sure it wasn't truncated, hence that's always + * safe.) */ fn = NULL; else { fn = memdup_suffix0(info.lo_file_name, sizeof(info.lo_file_name)); From 91ea97356c1799d7ac6b54713eb059c220f66d29 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 13 Mar 2023 23:36:32 +0900 Subject: [PATCH 2/2] test-50-dissect: add test for long reference name --- test/units/testsuite-50.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/units/testsuite-50.sh b/test/units/testsuite-50.sh index 741167a2154..af7d3511546 100755 --- a/test/units/testsuite-50.sh +++ b/test/units/testsuite-50.sh @@ -447,8 +447,28 @@ fi # Detach by loopback device systemd-dissect --detach "$LOOP" +# Test long reference name. +# Note, sizeof_field(struct loop_info64, lo_file_name) == 64, +# and --loop-ref accepts upto 63 characters, and udev creates symlink +# based on the name when it has upto _62_ characters. +name="$(for (( i = 0; i < 62; i++ )); do echo -n 'x'; done)" +LOOP="$(systemd-dissect --attach --loop-ref="$name" "${image}.raw")" +udevadm trigger -w "$LOOP" + +# Check if the /dev/loop/by-ref/$name symlink really references the right device +test "/dev/loop/by-ref/$name" -ef "$LOOP" + +# Detach by the /dev/loop/by-ref symlink +systemd-dissect --detach "/dev/loop/by-ref/$name" + +name="$(for (( i = 0; i < 63; i++ )); do echo -n 'x'; done)" +LOOP="$(systemd-dissect --attach --loop-ref="$name" "${image}.raw")" +udevadm trigger -w "$LOOP" + +# Check if the /dev/loop/by-ref/$name symlink does not exist +test ! -e "/dev/loop/by-ref/$name" + # Detach by backing inode -systemd-dissect --attach --loop-ref=waldo "${image}.raw" systemd-dissect --detach "${image}.raw" (! systemd-dissect --detach "${image}.raw")