Resolves: RHEL-70158 - Info Leak via Uninitialized Stack Contents
Resolves: RHEL-70208 - Path traversal vulnerability in rsync Resolves: RHEL-70210 - --safe-links option bypass leads to path traversal Resolves: RHEL-71657 - Race Condition in rsync Handling Symbolic Links
This commit is contained in:
parent
cd54d1b96b
commit
803ba84686
14
rsync-3.2.5-cve-2024-12085.patch
Normal file
14
rsync-3.2.5-cve-2024-12085.patch
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
diff --git a/match.c b/match.c
|
||||||
|
index 36e78ed..dfd6af2 100644
|
||||||
|
--- a/match.c
|
||||||
|
+++ b/match.c
|
||||||
|
@@ -147,6 +147,9 @@ static void hash_search(int f,struct sum_struct *s,
|
||||||
|
int more;
|
||||||
|
schar *map;
|
||||||
|
|
||||||
|
+ // prevent possible memory leaks
|
||||||
|
+ memset(sum2, 0, sizeof sum2);
|
||||||
|
+
|
||||||
|
/* want_i is used to encourage adjacent matches, allowing the RLL
|
||||||
|
* coding of the output to work more efficiently. */
|
||||||
|
want_i = 0;
|
36
rsync-3.2.5-cve-2024-12087.patch
Normal file
36
rsync-3.2.5-cve-2024-12087.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
diff --git a/flist.c b/flist.c
|
||||||
|
index 464d556..087f9da 100644
|
||||||
|
--- a/flist.c
|
||||||
|
+++ b/flist.c
|
||||||
|
@@ -2584,6 +2584,19 @@ struct file_list *recv_file_list(int f, int dir_ndx)
|
||||||
|
init_hard_links();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ if (inc_recurse && dir_ndx >= 0) {
|
||||||
|
+ if (dir_ndx >= dir_flist->used) {
|
||||||
|
+ rprintf(FERROR_XFER, "rsync: refusing invalid dir_ndx %u >= %u\n", dir_ndx, dir_flist->used);
|
||||||
|
+ exit_cleanup(RERR_PROTOCOL);
|
||||||
|
+ }
|
||||||
|
+ struct file_struct *file = dir_flist->files[dir_ndx];
|
||||||
|
+ if (file->flags & FLAG_GOT_DIR_FLIST) {
|
||||||
|
+ rprintf(FERROR_XFER, "rsync: refusing malicious duplicate flist for dir %d\n", dir_ndx);
|
||||||
|
+ exit_cleanup(RERR_PROTOCOL);
|
||||||
|
+ }
|
||||||
|
+ file->flags |= FLAG_GOT_DIR_FLIST;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
flist = flist_new(0, "recv_file_list");
|
||||||
|
flist_expand(flist, FLIST_START_LARGE);
|
||||||
|
|
||||||
|
diff --git a/rsync.h b/rsync.h
|
||||||
|
index f8bd024..fbaf312 100644
|
||||||
|
--- a/rsync.h
|
||||||
|
+++ b/rsync.h
|
||||||
|
@@ -92,6 +92,7 @@
|
||||||
|
#define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */
|
||||||
|
#define FLAG_TIME_FAILED (1<<11)/* generator */
|
||||||
|
#define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */
|
||||||
|
+#define FLAG_GOT_DIR_FLIST (1<<13)/* sender/receiver/generator - dir_flist only */
|
||||||
|
|
||||||
|
/* These flags are passed to functions but not stored. */
|
||||||
|
|
57
rsync-3.2.5-cve-2024-12088.patch
Normal file
57
rsync-3.2.5-cve-2024-12088.patch
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
diff --git a/testsuite/unsafe-byname.test b/testsuite/unsafe-byname.test
|
||||||
|
index 75e7201..d2e318e 100644
|
||||||
|
--- a/testsuite/unsafe-byname.test
|
||||||
|
+++ b/testsuite/unsafe-byname.test
|
||||||
|
@@ -40,7 +40,7 @@ test_unsafe ..//../dest from/dir unsafe
|
||||||
|
test_unsafe .. from/file safe
|
||||||
|
test_unsafe ../.. from/file unsafe
|
||||||
|
test_unsafe ..//.. from//file unsafe
|
||||||
|
-test_unsafe dir/.. from safe
|
||||||
|
+test_unsafe dir/.. from unsafe
|
||||||
|
test_unsafe dir/../.. from unsafe
|
||||||
|
test_unsafe dir/..//.. from unsafe
|
||||||
|
|
||||||
|
diff --git a/util1.c b/util1.c
|
||||||
|
index da50ff1..f260d39 100644
|
||||||
|
--- a/util1.c
|
||||||
|
+++ b/util1.c
|
||||||
|
@@ -1318,7 +1318,14 @@ int handle_partial_dir(const char *fname, int create)
|
||||||
|
*
|
||||||
|
* "src" is the top source directory currently applicable at the level
|
||||||
|
* of the referenced symlink. This is usually the symlink's full path
|
||||||
|
- * (including its name), as referenced from the root of the transfer. */
|
||||||
|
+ * (including its name), as referenced from the root of the transfer.
|
||||||
|
+ *
|
||||||
|
+ * NOTE: this also rejects dest names with a .. component in other
|
||||||
|
+ * than the first component of the name ie. it rejects names such as
|
||||||
|
+ * a/b/../x/y. This needs to be done as the leading subpaths 'a' or
|
||||||
|
+ * 'b' could later be replaced with symlinks such as a link to '.'
|
||||||
|
+ * resulting in the link being transferred now becoming unsafe
|
||||||
|
+ */
|
||||||
|
int unsafe_symlink(const char *dest, const char *src)
|
||||||
|
{
|
||||||
|
const char *name, *slash;
|
||||||
|
@@ -1328,6 +1335,23 @@ int unsafe_symlink(const char *dest, const char *src)
|
||||||
|
if (!dest || !*dest || *dest == '/')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
+ // reject destinations with /../ in the name other than at the start of the name
|
||||||
|
+ const char *dest2 = dest;
|
||||||
|
+ while (strncmp(dest2, "../", 3) == 0) {
|
||||||
|
+ dest2 += 3;
|
||||||
|
+ while (*dest2 == '/') {
|
||||||
|
+ // allow for ..//..///../foo
|
||||||
|
+ dest2++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (strstr(dest2, "/../"))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ // reject if the destination ends in /..
|
||||||
|
+ const size_t dlen = strlen(dest);
|
||||||
|
+ if (dlen > 3 && strcmp(&dest[dlen-3], "/..") == 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
/* find out what our safety margin is */
|
||||||
|
for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
|
||||||
|
/* ".." segment starts the count over. "." segment is ignored. */
|
163
rsync-3.2.5-cve-2024-12747.patch
Normal file
163
rsync-3.2.5-cve-2024-12747.patch
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
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)
|
||||||
|
|
||||||
|
memset(sum, 0, MAX_DIGEST_LEN);
|
||||||
|
|
||||||
|
- fd = do_open(fname, O_RDONLY, 0);
|
||||||
|
+ fd = do_open_checklinks(fname);
|
||||||
|
if (fd == -1)
|
||||||
|
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
|
||||||
|
@@ -714,3 +714,21 @@ int do_open_nofollow(const char *pathname, int flags)
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ 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;
|
31
rsync.spec
31
rsync.spec
@ -10,7 +10,7 @@
|
|||||||
Summary: A program for synchronizing files over a network
|
Summary: A program for synchronizing files over a network
|
||||||
Name: rsync
|
Name: rsync
|
||||||
Version: 3.2.5
|
Version: 3.2.5
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
URL: https://rsync.samba.org/
|
URL: https://rsync.samba.org/
|
||||||
|
|
||||||
Source0: https://download.samba.org/pub/rsync/src/rsync-%{version}%{?prerelease}.tar.gz
|
Source0: https://download.samba.org/pub/rsync/src/rsync-%{version}%{?prerelease}.tar.gz
|
||||||
@ -42,6 +42,10 @@ Patch1: rsync-3.2.2-runtests.patch
|
|||||||
Patch2: rsync-3.2.5-rrsync-man.patch
|
Patch2: rsync-3.2.5-rrsync-man.patch
|
||||||
#A couple of fixes for the new filtering code
|
#A couple of fixes for the new filtering code
|
||||||
Patch3: rsync-3.2.3-filtering-rules.patch
|
Patch3: rsync-3.2.3-filtering-rules.patch
|
||||||
|
Patch4: rsync-3.2.5-cve-2024-12085.patch
|
||||||
|
Patch5: rsync-3.2.5-cve-2024-12087.patch
|
||||||
|
Patch6: rsync-3.2.5-cve-2024-12088.patch
|
||||||
|
Patch7: rsync-3.2.5-cve-2024-12747.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Rsync uses a reliable algorithm to bring remote and host files into
|
Rsync uses a reliable algorithm to bring remote and host files into
|
||||||
@ -61,6 +65,15 @@ Requires: %{name} = %{version}-%{release}
|
|||||||
Rsync can be used to offer read only access to anonymous clients. This
|
Rsync can be used to offer read only access to anonymous clients. This
|
||||||
package provides the anonymous rsync service.
|
package provides the anonymous rsync service.
|
||||||
|
|
||||||
|
%package rrsync
|
||||||
|
Summary: A script to setup restricted rsync users via ssh logins
|
||||||
|
BuildArch: noarch
|
||||||
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
Requires: %{__python3}
|
||||||
|
%description rrsync
|
||||||
|
This subpackage provides rrsync script and its manpage. rrsync
|
||||||
|
may be used to setup a restricted rsync users via ssh logins.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
# TAG: for pre versions use
|
# TAG: for pre versions use
|
||||||
|
|
||||||
@ -75,6 +88,10 @@ package provides the anonymous rsync service.
|
|||||||
%patch1 -p1 -b .runtests
|
%patch1 -p1 -b .runtests
|
||||||
%patch2 -p1 -b .rrsync-man
|
%patch2 -p1 -b .rrsync-man
|
||||||
%patch3 -p1 -b .filtering-rules
|
%patch3 -p1 -b .filtering-rules
|
||||||
|
%patch4 -p1 -b .cve-2024-12085
|
||||||
|
%patch5 -p1 -b .cve-2024-12087
|
||||||
|
%patch6 -p1 -b .cve-2024-12088
|
||||||
|
%patch7 -p1 -b .cve-2024-12747
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure --disable-xxhash --with-rrsync
|
%configure --disable-xxhash --with-rrsync
|
||||||
@ -99,10 +116,8 @@ install -D -m644 %{SOURCE6} $RPM_BUILD_ROOT/%{_unitdir}/rsyncd@.service
|
|||||||
%license COPYING
|
%license COPYING
|
||||||
%doc support/ tech_report.tex
|
%doc support/ tech_report.tex
|
||||||
%{_bindir}/%{name}
|
%{_bindir}/%{name}
|
||||||
%{_bindir}/r%{name}
|
|
||||||
%{_bindir}/%{name}-ssl
|
%{_bindir}/%{name}-ssl
|
||||||
%{_mandir}/man1/%{name}.1*
|
%{_mandir}/man1/%{name}.1*
|
||||||
%{_mandir}/man1/r%{name}.1*
|
|
||||||
%{_mandir}/man1/%{name}-ssl.1*
|
%{_mandir}/man1/%{name}-ssl.1*
|
||||||
%{_mandir}/man5/rsyncd.conf.5*
|
%{_mandir}/man5/rsyncd.conf.5*
|
||||||
%config(noreplace) %{_sysconfdir}/rsyncd.conf
|
%config(noreplace) %{_sysconfdir}/rsyncd.conf
|
||||||
@ -113,6 +128,10 @@ install -D -m644 %{SOURCE6} $RPM_BUILD_ROOT/%{_unitdir}/rsyncd@.service
|
|||||||
%{_unitdir}/rsyncd.service
|
%{_unitdir}/rsyncd.service
|
||||||
%{_unitdir}/rsyncd@.service
|
%{_unitdir}/rsyncd@.service
|
||||||
|
|
||||||
|
%files rrsync
|
||||||
|
%{_bindir}/r%{name}
|
||||||
|
%{_mandir}/man1/r%{name}.1*
|
||||||
|
|
||||||
%post daemon
|
%post daemon
|
||||||
%systemd_post rsyncd.service
|
%systemd_post rsyncd.service
|
||||||
|
|
||||||
@ -123,6 +142,12 @@ install -D -m644 %{SOURCE6} $RPM_BUILD_ROOT/%{_unitdir}/rsyncd@.service
|
|||||||
%systemd_postun_with_restart rsyncd.service
|
%systemd_postun_with_restart rsyncd.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jan 29 2025 Michal Ruprich <mruprich@redhat.com> - 3.2.5-2
|
||||||
|
- Resolves: RHEL-70158 - Info Leak via Uninitialized Stack Contents
|
||||||
|
- Resolves: RHEL-70208 - Path traversal vulnerability in rsync
|
||||||
|
- Resolves: RHEL-70210 - --safe-links option bypass leads to path traversal
|
||||||
|
- Resolves: RHEL-71657 - Race Condition in rsync Handling Symbolic Links
|
||||||
|
|
||||||
* Mon Dec 09 2024 Michal Ruprich <mruprich@redhat.com> - 3.2.3-21
|
* Mon Dec 09 2024 Michal Ruprich <mruprich@redhat.com> - 3.2.3-21
|
||||||
- Resolves: RHEL-70265 - Rebase rsync to 3.2.5
|
- Resolves: RHEL-70265 - Rebase rsync to 3.2.5
|
||||||
- Resolves: RHEL-67142 - Wrong progress reported by rsync when using copy-devices
|
- Resolves: RHEL-67142 - Wrong progress reported by rsync when using copy-devices
|
||||||
|
Loading…
Reference in New Issue
Block a user