* Added rsync-CVE-2024-12747.patch - Security update, fix multiple vulnerabilities: * CVE-2024-12084, bsc#1234100 - Heap Buffer Overflow in Checksum Parsing * CVE-2024-12085, bsc#1234101 - Info Leak via uninitialized Stack contents defeats ASLR * CVE-2024-12086, bsc#1234102 - Server leaks arbitrary client files * CVE-2024-12087, bsc#1234103 - Server can make client write files outside of destination directory using symbolic links * CVE-2024-12088, bsc#1234104 - --safe-links Bypass * Added rsync-CVE-2024-12084-overflow-01.patch * Added rsync-CVE-2024-12084-overflow-02.patch * Added rsync-CVE-2024-12085.patch * Added rsync-CVE-2024-12086_01.patch * Added rsync-CVE-2024-12086_02.patch * Added rsync-CVE-2024-12086_03.patch * Added rsync-CVE-2024-12086_04.patch * Added rsync-CVE-2024-12087_01.patch * Added rsync-CVE-2024-12087_02.patch * Added rsync-CVE-2024-12088.patch OBS-URL: https://build.opensuse.org/package/show/network/rsync?expand=0&rev=129
105 lines
3.3 KiB
Diff
105 lines
3.3 KiB
Diff
From e59ef9939d3f0ccc8f9bab51442989a81be0c914 Mon Sep 17 00:00:00 2001
|
|
From: Andrew Tridgell <andrew@tridgell.net>
|
|
Date: Sat, 23 Nov 2024 12:28:13 +1100
|
|
Subject: [PATCH 3/4] receiver: use secure_relative_open() for basis file
|
|
|
|
this prevents attacks where the basis file is manipulated by a
|
|
malicious sender to gain information about files outside the
|
|
destination tree
|
|
---
|
|
receiver.c | 42 ++++++++++++++++++++++++++----------------
|
|
1 file changed, 26 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/receiver.c b/receiver.c
|
|
index 2d7f6033..8031b8f4 100644
|
|
--- a/receiver.c
|
|
+++ b/receiver.c
|
|
@@ -552,6 +552,8 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|
progress_init();
|
|
|
|
while (1) {
|
|
+ const char *basedir = NULL;
|
|
+
|
|
cleanup_disable();
|
|
|
|
/* This call also sets cur_flist. */
|
|
@@ -722,27 +724,29 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|
exit_cleanup(RERR_PROTOCOL);
|
|
}
|
|
if (file->dirname) {
|
|
- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, file->dirname, xname);
|
|
- fnamecmp = fnamecmpbuf;
|
|
- } else
|
|
- fnamecmp = xname;
|
|
+ basedir = file->dirname;
|
|
+ }
|
|
+ fnamecmp = xname;
|
|
break;
|
|
default:
|
|
if (fnamecmp_type > FNAMECMP_FUZZY && fnamecmp_type-FNAMECMP_FUZZY <= basis_dir_cnt) {
|
|
fnamecmp_type -= FNAMECMP_FUZZY + 1;
|
|
if (file->dirname) {
|
|
- stringjoin(fnamecmpbuf, sizeof fnamecmpbuf,
|
|
- basis_dir[fnamecmp_type], "/", file->dirname, "/", xname, NULL);
|
|
- } else
|
|
- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], xname);
|
|
+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], file->dirname);
|
|
+ basedir = fnamecmpbuf;
|
|
+ } else {
|
|
+ basedir = basis_dir[fnamecmp_type];
|
|
+ }
|
|
+ fnamecmp = xname;
|
|
} else if (fnamecmp_type >= basis_dir_cnt) {
|
|
rprintf(FERROR,
|
|
"invalid basis_dir index: %d.\n",
|
|
fnamecmp_type);
|
|
exit_cleanup(RERR_PROTOCOL);
|
|
- } else
|
|
- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], fname);
|
|
- fnamecmp = fnamecmpbuf;
|
|
+ } else {
|
|
+ basedir = basis_dir[fnamecmp_type];
|
|
+ fnamecmp = fname;
|
|
+ }
|
|
break;
|
|
}
|
|
if (!fnamecmp || (daemon_filter_list.head
|
|
@@ -765,7 +769,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|
}
|
|
|
|
/* open the file */
|
|
- fd1 = do_open(fnamecmp, O_RDONLY, 0);
|
|
+ fd1 = secure_relative_open(basedir, fnamecmp, O_RDONLY, 0);
|
|
|
|
if (fd1 == -1 && protocol_version < 29) {
|
|
if (fnamecmp != fname) {
|
|
@@ -776,14 +780,20 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|
|
|
if (fd1 == -1 && basis_dir[0]) {
|
|
/* pre-29 allowed only one alternate basis */
|
|
- pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
|
|
- basis_dir[0], fname);
|
|
- fnamecmp = fnamecmpbuf;
|
|
+ basedir = basis_dir[0];
|
|
+ fnamecmp = fname;
|
|
fnamecmp_type = FNAMECMP_BASIS_DIR_LOW;
|
|
- fd1 = do_open(fnamecmp, O_RDONLY, 0);
|
|
+ fd1 = secure_relative_open(basedir, fnamecmp, O_RDONLY, 0);
|
|
}
|
|
}
|
|
|
|
+ if (basedir) {
|
|
+ // for the following code we need the full
|
|
+ // path name as a single string
|
|
+ pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basedir, fnamecmp);
|
|
+ fnamecmp = fnamecmpbuf;
|
|
+ }
|
|
+
|
|
one_inplace = inplace_partial && fnamecmp_type == FNAMECMP_PARTIAL_DIR;
|
|
updating_basis_or_equiv = one_inplace
|
|
|| (inplace && (fnamecmp == fname || fnamecmp_type == FNAMECMP_BACKUP));
|
|
--
|
|
2.34.1
|
|
|
|
|