git: 558137064296 - main - net/rsync: Fix the handling of many xattrs on FreeBSD
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 29 Jul 2025 18:50:11 UTC
The branch main has been updated by rodrigo:
URL: https://cgit.FreeBSD.org/ports/commit/?id=558137064296eac74a8b7d9b9a370a43e97bf329
commit 558137064296eac74a8b7d9b9a370a43e97bf329
Author: Rodrigo Osorio <rodrigo@FreeBSD.org>
AuthorDate: 2025-07-12 10:43:16 +0000
Commit: Rodrigo Osorio <rodrigo@FreeBSD.org>
CommitDate: 2025-07-29 18:43:49 +0000
net/rsync: Fix the handling of many xattrs on FreeBSD
Fix sys_llistxattr() for FreeBSD code to request a larger
buffer to store the extended attributes list if the current
one is too small.
I also improve the attribute parsing by reducing to one the memmove
calls when converting FreeBSD attribute list to the format used by
Linux and extend the rsync unit tests for long xattrs lists.
Changes where submitted to upstream as:
https://github.com/RsyncProject/rsync/pull/781
https://github.com/RsyncProject/rsync/pull/766
PR: 286773
Reported by: Peter Eriksson <pen@lysator.liu.se>
Obtained from: Peter Eriksson <pen@lysator.liu.se>
Reviewed by: rodrigo
Tested by: rodrigo
Event: Berlin Hackaton 202507
Relnotes: yes
---
net/rsync/Makefile | 2 +-
net/rsync/files/patch-lib_sysxattrs.c | 42 ++++++++++++++++++
net/rsync/files/patch-testsuite_xattrs.test | 67 +++++++++++++++++++++++++++++
3 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/net/rsync/Makefile b/net/rsync/Makefile
index 5977ac517199..e495116560b8 100644
--- a/net/rsync/Makefile
+++ b/net/rsync/Makefile
@@ -1,6 +1,6 @@
PORTNAME= rsync
DISTVERSION= 3.4.1
-PORTREVISION= 2
+PORTREVISION= 3
CATEGORIES= net
MASTER_SITES= https://www.mirrorservice.org/sites/rsync.samba.org/src/ \
http://rsync.mirror.garr.it/src/ \
diff --git a/net/rsync/files/patch-lib_sysxattrs.c b/net/rsync/files/patch-lib_sysxattrs.c
new file mode 100644
index 000000000000..16a307a83ad6
--- /dev/null
+++ b/net/rsync/files/patch-lib_sysxattrs.c
@@ -0,0 +1,42 @@
+--- a/lib/sysxattrs.c.orig 2022-01-16 01:21:01.000000000 +0000
++++ b/lib/sysxattrs.c 2025-07-28 12:05:43.501532000 +0000
+@@ -126,22 +126,29 @@
+ unsigned char keylen;
+ ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);
+
+- if (len <= 0 || (size_t)len > size)
++ if (len <= 0 || size == 0)
+ return len;
+
++ if ((size_t)len == size) {
++ /* extattr_list_link fills a buffer with a list of file attributes.
++ * If the buffer size is too small the content is truncated and
++ * extattr_list_link returns the number of written bytes and no
++ * error is raised. If size == len assumes the buffer was too small
++ * and behave like Linux requesting a larger buffer. */
++ errno = ERANGE;
++ return -1;
++ }
++
+ /* FreeBSD puts a single-byte length before each string, with no '\0'
+ * terminator. We need to change this into a series of null-terminted
+ * strings. Since the size is the same, we can simply transform the
+ * output in place. */
+- for (off = 0; off < len; off += keylen + 1) {
+- keylen = ((unsigned char*)list)[off];
+- if (off + keylen >= len) {
+- /* Should be impossible, but kernel bugs happen! */
+- errno = EINVAL;
+- return -1;
+- }
+- memmove(list+off, list+off+1, keylen);
+- list[off+keylen] = '\0';
++ keylen = (unsigned char)list[0];
++ memmove(list, list+1, len-1);
++ list[len-1] = '\0';
++ for (off = keylen; off < (len - 1); off += (keylen + 1)) {
++ keylen = (unsigned char)list[off];
++ list[off] = '\0';
+ }
+
+ return len;
diff --git a/net/rsync/files/patch-testsuite_xattrs.test b/net/rsync/files/patch-testsuite_xattrs.test
new file mode 100644
index 000000000000..95a1a285d96b
--- /dev/null
+++ b/net/rsync/files/patch-testsuite_xattrs.test
@@ -0,0 +1,67 @@
+--- a/testsuite/xattrs.test.orig 2022-10-20 16:09:26.000000000 +0000
++++ b/testsuite/xattrs.test 2025-06-29 07:49:45.880992000 +0000
+@@ -10,7 +10,14 @@
+
+ $RSYNC -VV | grep '"xattrs": true' >/dev/null || test_skipped "Rsync is configured without xattr support"
+
++CYGWIN=0
++
+ case "$HOST_OS" in
++cygwin*)
++ CYGWIN=1
++esac
++
++case "$HOST_OS" in
+ darwin*)
+ xset() {
+ xnam="$1"
+@@ -80,6 +87,9 @@
+ echo deep >"$fromdir/foo/file3"
+ echo normal >"$fromdir/file4"
+ echo deeper >"$fromdir/foo/bar/file5"
++if [ $CYGWIN -eq 0 ]; then
++ echo longxattrname >"$fromdir/file7"
++fi
+
+ makepath "$chkdir/foo"
+ echo wow >"$chkdir/file1"
+@@ -87,6 +97,10 @@
+
+ dirs='foo foo/bar'
+ files='file0 file1 file2 foo/file3 file4 foo/bar/file5'
++if [ $CYGWIN -eq 0 ]
++then
++ files="$files file7"
++fi
+
+ uid_gid=`"$TOOLDIR/tls" "$fromdir/foo" | sed 's/^.* \([0-9][0-9]*\)\.\([0-9][0-9]*\) .*/\1:\2/'`
+
+@@ -125,6 +139,16 @@
+ xset user.foo 'old foo' "$chkdir/foo/file3"
+ xset $RUSR.equal 'this long attribute should remain the same and not need to be transferred' "$chkdir/foo/file3"
+
++if [ $CYGWIN -eq 0 ] ; then
++# Generate xattr names
++SEQ=`seq 1 200`
++xset user."`printf -- 'A%0.s' $SEQ`" 'first xattr' file7
++xset user."`printf -- 'B%0.s' $SEQ`" 'second xattr' file7
++xset user."`printf -- 'C%0.s' $SEQ`" 'third xattr' file7
++xset user."`printf -- 'D%0.s' $SEQ`" 'another xattr' file7
++xset user."`printf -- 'E%0.s' $SEQ`" 'final xattr' file7
++fi
++
+ case $0 in
+ *hlink*)
+ ln foo/bar/file5 foo/bar/file6 || test_skipped "Can't create hardlink"
+@@ -234,6 +258,11 @@
+
+ cd "$todir"
+ xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" -
++
++cd "$fromdir"
++rm -rf "$todir"
++mkfifo fifo1
++checktee "$RSYNC -avX --specials $XFILT $dashH --super . '$chkdir/'" "$fromdir" "$chkdir"
+
+ # The script would have aborted on error, so getting here means we've won.
+ exit 0