summaryrefslogtreecommitdiffstats
path: root/debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2025-01-19 18:40:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2025-01-19 18:40:22 +0000
commitf3262cc6aeed05b753fce4aa16615758fd788ea7 (patch)
treed00a9107f9a05ad12aaffa516ad50ba69b71b5af /debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch
parentMerging upstream version 3.3.0+ds1. (diff)
downloadrsync-f3262cc6aeed05b753fce4aa16615758fd788ea7.tar.xz
rsync-f3262cc6aeed05b753fce4aa16615758fd788ea7.zip
Merging debian version 3.3.0+ds1-4.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch')
-rw-r--r--debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch188
1 files changed, 188 insertions, 0 deletions
diff --git a/debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch b/debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch
new file mode 100644
index 0000000..0c2e92b
--- /dev/null
+++ b/debian/patches/rsync-upstream-CVE-patches-v3/CVE-2024-12747/0001-fixed-symlink-race-condition-in-sender.patch
@@ -0,0 +1,188 @@
+From f45f48055e548851bc7230f454dfeba139be6c04 Mon Sep 17 00:00:00 2001
+From: Andrew Tridgell <andrew@tridgell.net>
+Date: Wed, 18 Dec 2024 08:59:42 +1100
+Subject: [PATCH] fixed symlink race condition in sender
+
+when we open a file that we don't expect to be a symlink use
+O_NOFOLLOW to prevent a race condition where an attacker could change
+a file between being a normal file and a symlink
+
+Backported-By: Samuel Henrique <samueloph@debian.org>
+* Refresh patch to remove offset.
+
+---
+ checksum.c | 2 +-
+ flist.c | 2 +-
+ generator.c | 4 ++--
+ receiver.c | 2 +-
+ sender.c | 2 +-
+ syscall.c | 20 ++++++++++++++++++++
+ t_unsafe.c | 3 +++
+ tls.c | 3 +++
+ trimslash.c | 2 ++
+ util1.c | 2 +-
+ 10 files changed, 35 insertions(+), 7 deletions(-)
+
+Index: rsync/checksum.c
+===================================================================
+--- rsync.orig/checksum.c
++++ rsync/checksum.c
+@@ -406,7 +406,7 @@ void file_checksum(const char *fname, co
+ int32 remainder;
+ int fd;
+
+- fd = do_open(fname, O_RDONLY, 0);
++ fd = do_open_checklinks(fname);
+ if (fd == -1) {
+ memset(sum, 0, file_sum_len);
+ return;
+Index: rsync/flist.c
+===================================================================
+--- rsync.orig/flist.c
++++ rsync/flist.c
+@@ -1390,7 +1390,7 @@ struct file_struct *make_file(const char
+
+ if (copy_devices && am_sender && IS_DEVICE(st.st_mode)) {
+ if (st.st_size == 0) {
+- int fd = do_open(fname, O_RDONLY, 0);
++ int fd = do_open_checklinks(fname);
+ if (fd >= 0) {
+ st.st_size = get_device_size(fd, fname);
+ close(fd);
+Index: rsync/generator.c
+===================================================================
+--- rsync.orig/generator.c
++++ rsync/generator.c
+@@ -1798,7 +1798,7 @@ static void recv_generator(char *fname,
+
+ if (write_devices && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) {
+ /* This early open into fd skips the regular open below. */
+- if ((fd = do_open(fnamecmp, O_RDONLY, 0)) >= 0)
++ if ((fd = do_open_nofollow(fnamecmp, O_RDONLY)) >= 0)
+ real_sx.st.st_size = sx.st.st_size = get_device_size(fd, fnamecmp);
+ }
+
+@@ -1867,7 +1867,7 @@ static void recv_generator(char *fname,
+ }
+
+ /* open the file */
+- if (fd < 0 && (fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
++ if (fd < 0 && (fd = do_open_checklinks(fnamecmp)) < 0) {
+ rsyserr(FERROR, errno, "failed to open %s, continuing",
+ full_fname(fnamecmp));
+ pretend_missing:
+Index: rsync/receiver.c
+===================================================================
+--- rsync.orig/receiver.c
++++ rsync/receiver.c
+@@ -775,7 +775,7 @@ int recv_files(int f_in, int f_out, char
+ if (fnamecmp != fname) {
+ fnamecmp = fname;
+ fnamecmp_type = FNAMECMP_FNAME;
+- fd1 = do_open(fnamecmp, O_RDONLY, 0);
++ fd1 = do_open_nofollow(fnamecmp, O_RDONLY);
+ }
+
+ if (fd1 == -1 && basis_dir[0]) {
+Index: rsync/sender.c
+===================================================================
+--- rsync.orig/sender.c
++++ rsync/sender.c
+@@ -350,7 +350,7 @@ void send_files(int f_in, int f_out)
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+- fd = do_open(fname, O_RDONLY, 0);
++ fd = do_open_checklinks(fname);
+ if (fd == -1) {
+ if (errno == ENOENT) {
+ enum logcode c = am_daemon && protocol_version < 28 ? FERROR : FWARNING;
+Index: rsync/syscall.c
+===================================================================
+--- rsync.orig/syscall.c
++++ rsync/syscall.c
+@@ -45,6 +45,8 @@ extern int preallocate_files;
+ extern int preserve_perms;
+ extern int preserve_executability;
+ extern int open_noatime;
++extern int copy_links;
++extern int copy_unsafe_links;
+
+ #ifndef S_BLKSIZE
+ # if defined hpux || defined __hpux__ || defined __hpux
+@@ -793,3 +795,21 @@ cleanup:
+ return retfd;
+ #endif // O_NOFOLLOW, O_DIRECTORY
+ }
++
++/*
++ varient of do_open/do_open_nofollow which does do_open() if the
++ copy_links or copy_unsafe_links options are set and does
++ do_open_nofollow() otherwise
++
++ This is used to prevent a race condition where an attacker could be
++ switching a file between being a symlink and being a normal file
++
++ The open is always done with O_RDONLY flags
++ */
++int do_open_checklinks(const char *pathname)
++{
++ if (copy_links || copy_unsafe_links) {
++ return do_open(pathname, O_RDONLY, 0);
++ }
++ return do_open_nofollow(pathname, O_RDONLY);
++}
+Index: rsync/t_unsafe.c
+===================================================================
+--- rsync.orig/t_unsafe.c
++++ rsync/t_unsafe.c
+@@ -28,6 +28,9 @@ int am_root = 0;
+ int am_sender = 1;
+ int read_only = 0;
+ int list_only = 0;
++int copy_links = 0;
++int copy_unsafe_links = 0;
++
+ short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG];
+
+ int
+Index: rsync/tls.c
+===================================================================
+--- rsync.orig/tls.c
++++ rsync/tls.c
+@@ -49,6 +49,9 @@ int list_only = 0;
+ int link_times = 0;
+ int link_owner = 0;
+ int nsec_times = 0;
++int safe_symlinks = 0;
++int copy_links = 0;
++int copy_unsafe_links = 0;
+
+ #ifdef SUPPORT_XATTRS
+
+Index: rsync/trimslash.c
+===================================================================
+--- rsync.orig/trimslash.c
++++ rsync/trimslash.c
+@@ -26,6 +26,8 @@ int am_root = 0;
+ int am_sender = 1;
+ int read_only = 1;
+ int list_only = 0;
++int copy_links = 0;
++int copy_unsafe_links = 0;
+
+ int
+ main(int argc, char **argv)
+Index: rsync/util1.c
+===================================================================
+--- rsync.orig/util1.c
++++ rsync/util1.c
+@@ -365,7 +365,7 @@ int copy_file(const char *source, const
+ int len; /* Number of bytes read into `buf'. */
+ OFF_T prealloc_len = 0, offset = 0;
+
+- if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
++ if ((ifd = do_open_nofollow(source, O_RDONLY)) < 0) {
+ int save_errno = errno;
+ rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
+ errno = save_errno;