]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
syscall: build without AT_SYMLINK_NOFOLLOW
authorZen Dodd <mail@steadytao.com>
Sun, 12 Jul 2026 03:00:49 +0000 (13:00 +1000)
committerAndrew Tridgell <andrew@tridgell.net>
Mon, 20 Jul 2026 00:05:43 +0000 (10:05 +1000)
Makefile.in
syscall.c

index 5216fb2f71990cf0d8de7e5df34fee95f294a2aa..ad024132e9332bcd9b99752d73860aaf5ccb9f66 100644 (file)
@@ -65,6 +65,8 @@ CHECK_SYMLINKS = testsuite/chown-fake_test.py testsuite/devices-fake_test.py \
 
 # Objects for CHECK_PROGS to clean
 CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o t_chmod_secure.o t_secure_relpath.o trimslash.o wildtest.o
+# Compile-only feature-shape checks.
+CHECK_COMPILE_OBJS=syscall-no-at-fdcwd.o
 
 # note that the -I. is needed to handle config.h when using VPATH
 .c.o:
@@ -72,6 +74,10 @@ CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o t_chmod_se
        $(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
 @OBJ_RESTORE@
 
+syscall-no-at-fdcwd.o: syscall.c $(HEADERS)
+       $(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) \
+           -DRSYNC_TEST_NO_AT_FDCWD -c $(srcdir)/syscall.c -o $@
+
 # NOTE: consider running "packaging/smart-make" instead of "make" to auto-handle
 # any changes to configure.sh and the main Makefile prior to a "make all".
 all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_RRSYNC@ @MAKE_MAN@
@@ -300,7 +306,7 @@ rrsync.1: support/rrsync.1.md md-convert Makefile
 
 .PHONY: clean
 clean: cleantests
-       rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) @MAKE_RRSYNC@ \
+       rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_COMPILE_OBJS) $(CHECK_SYMLINKS) @MAKE_RRSYNC@ \
                git-version.h rounding rounding.h *.old rsync*.1 rsync*.5 @MAKE_RRSYNC_1@ \
                *.html daemon-parm.h help-*.h default-*.h proto.h proto.h-tstamp
        rm -f *.gcno *.gcda lib/*.gcno lib/*.gcda zlib/*.gcno zlib/*.gcda popt/*.gcno popt/*.gcda
@@ -378,18 +384,18 @@ COVERAGE_EXCLUDE = -e '(^|/)zlib/' -e '(^|/)popt/' \
 # WITHOUT running it. Used by CI jobs that invoke runtests.py directly with
 # custom options (e.g. the version-mix workflow's --rsync-bin2/--expect-result).
 .PHONY: check-progs
-check-progs: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
+check-progs: all $(CHECK_PROGS) $(CHECK_COMPILE_OBJS) $(CHECK_SYMLINKS)
 
 .PHONY: check
-check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
+check: all $(CHECK_PROGS) $(CHECK_COMPILE_OBJS) $(CHECK_SYMLINKS)
        $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J)
 
 .PHONY: check29
-check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
+check29: all $(CHECK_PROGS) $(CHECK_COMPILE_OBJS) $(CHECK_SYMLINKS)
        $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J) --protocol=29
 
 .PHONY: check30
-check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
+check30: all $(CHECK_PROGS) $(CHECK_COMPILE_OBJS) $(CHECK_SYMLINKS)
        $(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) -j $(CHECK_J) --protocol=30
 
 # Whole-suite gcov coverage report (HTML, with branch + decision coverage).
index 243f7f243f3dc73f6e1ab4b1ddd4da503292443c..dfe9ed13dca4fd78ec00c86bda0343340f754b5e 100644 (file)
--- a/syscall.c
+++ b/syscall.c
 
 #include "rsync.h"
 
+/* Exercise the pre-*at() portability tier on modern build hosts. */
+#ifdef RSYNC_TEST_NO_AT_FDCWD
+#undef AT_FDCWD
+#undef AT_SYMLINK_NOFOLLOW
+#undef HAVE_LINKAT
+#undef HAVE_UTIMENSAT
+#endif
+
 #if !defined MKNOD_CREATES_SOCKETS && defined HAVE_SYS_UN_H
 #include <sys/un.h>
 #endif
@@ -426,7 +434,7 @@ int do_lchown(const char *path, uid_t owner, gid_t group)
 */
 int do_lchown_at(const char *fname, uid_t owner, gid_t group)
 {
-#ifdef AT_FDCWD
+#if defined AT_FDCWD && defined AT_SYMLINK_NOFOLLOW
        extern int am_daemon, am_chrooted;
        char dirpath[MAXPATHLEN];
        const char *bname;
@@ -1181,6 +1189,7 @@ static int do_xstat_at(const char *path, STRUCT_STAT *st, int at_flags, int (*fa
        errno = e;
        return ret;
 #else
+       (void)at_flags;
        return fallback(path, st);
 #endif
 }
@@ -1192,8 +1201,10 @@ int do_stat_at(const char *path, STRUCT_STAT *st)
 
 int do_lstat_at(const char *path, STRUCT_STAT *st)
 {
-#ifdef SUPPORT_LINKS
+#if defined SUPPORT_LINKS && defined AT_FDCWD && defined AT_SYMLINK_NOFOLLOW
        return do_xstat_at(path, st, AT_SYMLINK_NOFOLLOW, do_lstat);
+#elif defined SUPPORT_LINKS
+       return do_lstat(path, st);
 #else
        return do_xstat_at(path, st, 0, do_stat);
 #endif
@@ -2007,6 +2018,7 @@ cleanup:
 #endif // O_NOFOLLOW, O_DIRECTORY
 }
 
+#if defined O_NOFOLLOW && defined O_DIRECTORY && defined AT_FDCWD
 /* Fill buf with len random bytes.  Prefers /dev/urandom for cryptographic
  * quality; falls back to rand() if /dev/urandom cannot be opened or read
  * (e.g. inside a chroot or container without /dev populated). */
@@ -2027,6 +2039,7 @@ static void rand_bytes(unsigned char *buf, size_t len)
                buf[i] = (unsigned char)rand();
        }
 }
+#endif
 
 /*
   Secure version of mkstemp that prevents symlink attacks on parent directories.