summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net-misc/rsync/files/3.3.0/rsync-3.3.0-CVE-2024-12747-1.patch')
-rw-r--r--net-misc/rsync/files/3.3.0/rsync-3.3.0-CVE-2024-12747-1.patch166
1 files changed, 166 insertions, 0 deletions
diff --git a/net-misc/rsync/files/3.3.0/rsync-3.3.0-CVE-2024-12747-1.patch b/net-misc/rsync/files/3.3.0/rsync-3.3.0-CVE-2024-12747-1.patch
new file mode 100644
index 000000000000..527da2046125
--- /dev/null
+++ b/net-misc/rsync/files/3.3.0/rsync-3.3.0-CVE-2024-12747-1.patch
@@ -0,0 +1,166 @@
+https://bugs.gentoo.org/948106
+
+Backport provided by Red Hat on the VINCE case.
+diff --git a/checksum.c b/checksum.c
+index cb21882..66e8089 100644
+--- a/checksum.c
++++ b/checksum.c
+@@ -406,7 +406,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
+ 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;
+diff --git a/flist.c b/flist.c
+index 087f9da..1783253 100644
+--- a/flist.c
++++ b/flist.c
+@@ -1390,7 +1390,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist,
+
+ 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);
+diff --git a/generator.c b/generator.c
+index 110db28..3f13bb9 100644
+--- a/generator.c
++++ b/generator.c
+@@ -1798,7 +1798,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+
+ 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, struct file_struct *file, int ndx,
+ }
+
+ /* 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:
+diff --git a/receiver.c b/receiver.c
+index 8031b8f..edfbb21 100644
+--- a/receiver.c
++++ b/receiver.c
+@@ -775,7 +775,7 @@ int recv_files(int f_in, int f_out, char *local_name)
+ 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]) {
+diff --git a/sender.c b/sender.c
+index 2bbff2f..a4d46c3 100644
+--- a/sender.c
++++ b/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;
+diff --git a/syscall.c b/syscall.c
+index 47c5ea5..c55ae5f 100644
+--- a/syscall.c
++++ b/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);
++}
+diff --git a/t_unsafe.c b/t_unsafe.c
+index 010cac5..e10619a 100644
+--- a/t_unsafe.c
++++ b/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
+diff --git a/tls.c b/tls.c
+index e6b0708..858f8f1 100644
+--- a/tls.c
++++ b/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
+
+diff --git a/trimslash.c b/trimslash.c
+index 1ec928c..f2774cd 100644
+--- a/trimslash.c
++++ b/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)
+diff --git a/util1.c b/util1.c
+index f260d39..d84bc41 100644
+--- a/util1.c
++++ b/util1.c
+@@ -365,7 +365,7 @@ int copy_file(const char *source, const char *dest, int tmpfilefd, mode_t mode)
+ 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;