diff options
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.patch | 166 |
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; |