mirror of
https://git.yoctoproject.org/poky
synced 2026-03-09 16:59:40 +01:00
A flaw was found in rsync. It could allow a server to enumerate the contents of an arbitrary file from the client's machine. This issue occurs when files are being copied from a client to a server. During this process, the rsync server will send checksums of local data to the client to compare with in order to determine what data needs to be sent to the server. By sending specially constructed checksum values for arbitrary files, an attacker may be able to reconstruct the data of those files byte-by-byte based on the responses from the client. (From OE-Core rev: b49c8f58c20d7deb354a86a34488cb798c49eba3) Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
109 lines
3.5 KiB
Diff
109 lines
3.5 KiB
Diff
From c35e28331f10ba6eba370611abd78bde32d54da7 Mon Sep 17 00:00:00 2001
|
|
From: Andrew Tridgell <andrew@tridgell.net>
|
|
Date: Sat, 23 Nov 2024 12:28:13 +1100
|
|
Subject: [PATCH] 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
|
|
|
|
CVE: CVE-2024-12086
|
|
|
|
Upstream-Status: Backport [https://git.samba.org/?p=rsync.git;a=commit;h=c35e28331f10ba6eba370611abd78bde32d54da7]
|
|
|
|
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
|
---
|
|
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.40.0
|