Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -77,6 +79,10 @@ CHECK_OBJS=tls.o testrun.o getgroups.o getfsdev.o t_stub.o t_unsafe.o t_chmod_se
all: Makefile rsync$(EXEEXT) stunnel-rsyncd.conf @MAKE_RRSYNC@ @MAKE_MAN@
.PHONY: all

syscall-no-at-fdcwd.o: syscall.c $(HEADERS)
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) \
-DRSYNC_TEST_NO_AT_FDCWD -c $(srcdir)/syscall.c -o $@

.PHONY: install
install: all
-$(MKDIR_P) $(DESTDIR)$(bindir)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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).
Expand Down
19 changes: 17 additions & 2 deletions syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@

#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_OPENAT2
#undef HAVE_UTIMENSAT
#undef O_RESOLVE_BENEATH
#endif

#if !defined MKNOD_CREATES_SOCKETS && defined HAVE_SYS_UN_H
#include <sys/un.h>
#endif
Expand Down Expand Up @@ -426,7 +436,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;
Expand Down Expand Up @@ -1181,6 +1191,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
}
Expand All @@ -1192,8 +1203,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
Expand Down Expand Up @@ -2007,6 +2020,7 @@ int secure_relative_open(const char *basedir, const char *relpath, int flags, mo
#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). */
Expand All @@ -2027,6 +2041,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.
Expand Down
5 changes: 1 addition & 4 deletions wildtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "lib/wildmatch.c"

#include <popt.h>
#include <stdbool.h>

#ifdef COMPARE_WITH_FNMATCH
#include <fnmatch.h>
Expand All @@ -32,10 +33,6 @@ int fnmatch_errors = 0;

int wildmatch_errors = 0;

#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 202311L
typedef char bool;
#endif

int output_iterations = 0;
int explode_mod = 0;
int empties_mod = 0;
Expand Down
Loading