diff options
5 files changed, 303 insertions, 0 deletions
diff --git a/meta/recipes-devtools/rsync/files/CVE-2024-12086-0001.patch b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0001.patch new file mode 100644 index 0000000000..958a25a37b --- /dev/null +++ b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0001.patch | |||
@@ -0,0 +1,42 @@ | |||
1 | From 8ad4b5d912fad1df29717dddaa775724da77d299 Mon Sep 17 00:00:00 2001 | ||
2 | From: Andrew Tridgell <andrew@tridgell.net> | ||
3 | Date: Sat, 23 Nov 2024 11:08:03 +1100 | ||
4 | Subject: [PATCH] refuse fuzzy options when fuzzy not selected | ||
5 | |||
6 | this prevents a malicious server providing a file to compare to when | ||
7 | the user has not given the fuzzy option | ||
8 | |||
9 | CVE: CVE-2024-12086 | ||
10 | |||
11 | Upstream-Status: Backport [https://git.samba.org/?p=rsync.git;a=commit;h=8ad4b5d912fad1df29717dddaa775724da77d299] | ||
12 | |||
13 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
14 | --- | ||
15 | receiver.c | 5 +++++ | ||
16 | 1 file changed, 5 insertions(+) | ||
17 | |||
18 | diff --git a/receiver.c b/receiver.c | ||
19 | index 6b4b369e..2d7f6033 100644 | ||
20 | --- a/receiver.c | ||
21 | +++ b/receiver.c | ||
22 | @@ -66,6 +66,7 @@ extern char sender_file_sum[MAX_DIGEST_LEN]; | ||
23 | extern struct file_list *cur_flist, *first_flist, *dir_flist; | ||
24 | extern filter_rule_list daemon_filter_list; | ||
25 | extern OFF_T preallocated_len; | ||
26 | +extern int fuzzy_basis; | ||
27 | |||
28 | extern struct name_num_item *xfer_sum_nni; | ||
29 | extern int xfer_sum_len; | ||
30 | @@ -716,6 +717,10 @@ int recv_files(int f_in, int f_out, char *local_name) | ||
31 | fnamecmp = get_backup_name(fname); | ||
32 | break; | ||
33 | case FNAMECMP_FUZZY: | ||
34 | + if (fuzzy_basis == 0) { | ||
35 | + rprintf(FERROR_XFER, "rsync: refusing malicious fuzzy operation for %s\n", xname); | ||
36 | + exit_cleanup(RERR_PROTOCOL); | ||
37 | + } | ||
38 | if (file->dirname) { | ||
39 | pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, file->dirname, xname); | ||
40 | fnamecmp = fnamecmpbuf; | ||
41 | -- | ||
42 | 2.40.0 | ||
diff --git a/meta/recipes-devtools/rsync/files/CVE-2024-12086-0002.patch b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0002.patch new file mode 100644 index 0000000000..5d25f12dd8 --- /dev/null +++ b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0002.patch | |||
@@ -0,0 +1,108 @@ | |||
1 | From b4a27ca25d0abb6fcf14f41b7e11f3a6e1d8a4ff Mon Sep 17 00:00:00 2001 | ||
2 | From: Andrew Tridgell <andrew@tridgell.net> | ||
3 | Date: Sat, 23 Nov 2024 12:26:10 +1100 | ||
4 | Subject: [PATCH] added secure_relative_open() | ||
5 | |||
6 | this is an open that enforces no symlink following for all path | ||
7 | components in a relative path | ||
8 | |||
9 | CVE: CVE-2024-12086 | ||
10 | |||
11 | Upstream-Status: Backport [https://git.samba.org/?p=rsync.git;a=commit;h=b4a27ca25d0abb6fcf14f41b7e11f3a6e1d8a4ff] | ||
12 | |||
13 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
14 | --- | ||
15 | syscall.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
16 | 1 file changed, 74 insertions(+) | ||
17 | |||
18 | diff --git a/syscall.c b/syscall.c | ||
19 | index b4b0f1f1..cffc814b 100644 | ||
20 | --- a/syscall.c | ||
21 | +++ b/syscall.c | ||
22 | @@ -33,6 +33,8 @@ | ||
23 | #include <sys/syscall.h> | ||
24 | #endif | ||
25 | |||
26 | +#include "ifuncs.h" | ||
27 | + | ||
28 | extern int dry_run; | ||
29 | extern int am_root; | ||
30 | extern int am_sender; | ||
31 | @@ -707,3 +709,75 @@ int do_open_nofollow(const char *pathname, int flags) | ||
32 | |||
33 | return fd; | ||
34 | } | ||
35 | + | ||
36 | +/* | ||
37 | + open a file relative to a base directory. The basedir can be NULL, | ||
38 | + in which case the current working directory is used. The relpath | ||
39 | + must be a relative path, and the relpath must not contain any | ||
40 | + elements in the path which follow symlinks (ie. like O_NOFOLLOW, but | ||
41 | + applies to all path components, not just the last component) | ||
42 | +*/ | ||
43 | +int secure_relative_open(const char *basedir, const char *relpath, int flags, mode_t mode) | ||
44 | +{ | ||
45 | + if (!relpath || relpath[0] == '/') { | ||
46 | + // must be a relative path | ||
47 | + errno = EINVAL; | ||
48 | + return -1; | ||
49 | + } | ||
50 | + | ||
51 | +#if !defined(O_NOFOLLOW) || !defined(O_DIRECTORY) | ||
52 | + // really old system, all we can do is live with the risks | ||
53 | + if (!basedir) { | ||
54 | + return open(relpath, flags, mode); | ||
55 | + } | ||
56 | + char fullpath[MAXPATHLEN]; | ||
57 | + pathjoin(fullpath, sizeof fullpath, basedir, relpath); | ||
58 | + return open(fullpath, flags, mode); | ||
59 | +#else | ||
60 | + int dirfd = AT_FDCWD; | ||
61 | + if (basedir != NULL) { | ||
62 | + dirfd = openat(AT_FDCWD, basedir, O_RDONLY | O_DIRECTORY); | ||
63 | + if (dirfd == -1) { | ||
64 | + return -1; | ||
65 | + } | ||
66 | + } | ||
67 | + int retfd = -1; | ||
68 | + | ||
69 | + char *path_copy = my_strdup(relpath, __FILE__, __LINE__); | ||
70 | + if (!path_copy) { | ||
71 | + return -1; | ||
72 | + } | ||
73 | + | ||
74 | + for (const char *part = strtok(path_copy, "/"); | ||
75 | + part != NULL; | ||
76 | + part = strtok(NULL, "/")) | ||
77 | + { | ||
78 | + int next_fd = openat(dirfd, part, O_RDONLY | O_DIRECTORY | O_NOFOLLOW); | ||
79 | + if (next_fd == -1 && errno == ENOTDIR) { | ||
80 | + if (strtok(NULL, "/") != NULL) { | ||
81 | + // this is not the last component of the path | ||
82 | + errno = ELOOP; | ||
83 | + goto cleanup; | ||
84 | + } | ||
85 | + // this could be the last component of the path, try as a file | ||
86 | + retfd = openat(dirfd, part, flags | O_NOFOLLOW, mode); | ||
87 | + goto cleanup; | ||
88 | + } | ||
89 | + if (next_fd == -1) { | ||
90 | + goto cleanup; | ||
91 | + } | ||
92 | + if (dirfd != AT_FDCWD) close(dirfd); | ||
93 | + dirfd = next_fd; | ||
94 | + } | ||
95 | + | ||
96 | + // the path must be a directory | ||
97 | + errno = EINVAL; | ||
98 | + | ||
99 | +cleanup: | ||
100 | + free(path_copy); | ||
101 | + if (dirfd != AT_FDCWD) { | ||
102 | + close(dirfd); | ||
103 | + } | ||
104 | + return retfd; | ||
105 | +#endif // O_NOFOLLOW, O_DIRECTORY | ||
106 | +} | ||
107 | -- | ||
108 | 2.40.0 | ||
diff --git a/meta/recipes-devtools/rsync/files/CVE-2024-12086-0003.patch b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0003.patch new file mode 100644 index 0000000000..de1747adf2 --- /dev/null +++ b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0003.patch | |||
@@ -0,0 +1,108 @@ | |||
1 | From c35e28331f10ba6eba370611abd78bde32d54da7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Andrew Tridgell <andrew@tridgell.net> | ||
3 | Date: Sat, 23 Nov 2024 12:28:13 +1100 | ||
4 | Subject: [PATCH] receiver: use secure_relative_open() for basis file | ||
5 | |||
6 | this prevents attacks where the basis file is manipulated by a | ||
7 | malicious sender to gain information about files outside the | ||
8 | destination tree | ||
9 | |||
10 | CVE: CVE-2024-12086 | ||
11 | |||
12 | Upstream-Status: Backport [https://git.samba.org/?p=rsync.git;a=commit;h=c35e28331f10ba6eba370611abd78bde32d54da7] | ||
13 | |||
14 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
15 | --- | ||
16 | receiver.c | 42 ++++++++++++++++++++++++++---------------- | ||
17 | 1 file changed, 26 insertions(+), 16 deletions(-) | ||
18 | |||
19 | diff --git a/receiver.c b/receiver.c | ||
20 | index 2d7f6033..8031b8f4 100644 | ||
21 | --- a/receiver.c | ||
22 | +++ b/receiver.c | ||
23 | @@ -552,6 +552,8 @@ int recv_files(int f_in, int f_out, char *local_name) | ||
24 | progress_init(); | ||
25 | |||
26 | while (1) { | ||
27 | + const char *basedir = NULL; | ||
28 | + | ||
29 | cleanup_disable(); | ||
30 | |||
31 | /* This call also sets cur_flist. */ | ||
32 | @@ -722,27 +724,29 @@ int recv_files(int f_in, int f_out, char *local_name) | ||
33 | exit_cleanup(RERR_PROTOCOL); | ||
34 | } | ||
35 | if (file->dirname) { | ||
36 | - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, file->dirname, xname); | ||
37 | - fnamecmp = fnamecmpbuf; | ||
38 | - } else | ||
39 | - fnamecmp = xname; | ||
40 | + basedir = file->dirname; | ||
41 | + } | ||
42 | + fnamecmp = xname; | ||
43 | break; | ||
44 | default: | ||
45 | if (fnamecmp_type > FNAMECMP_FUZZY && fnamecmp_type-FNAMECMP_FUZZY <= basis_dir_cnt) { | ||
46 | fnamecmp_type -= FNAMECMP_FUZZY + 1; | ||
47 | if (file->dirname) { | ||
48 | - stringjoin(fnamecmpbuf, sizeof fnamecmpbuf, | ||
49 | - basis_dir[fnamecmp_type], "/", file->dirname, "/", xname, NULL); | ||
50 | - } else | ||
51 | - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], xname); | ||
52 | + pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], file->dirname); | ||
53 | + basedir = fnamecmpbuf; | ||
54 | + } else { | ||
55 | + basedir = basis_dir[fnamecmp_type]; | ||
56 | + } | ||
57 | + fnamecmp = xname; | ||
58 | } else if (fnamecmp_type >= basis_dir_cnt) { | ||
59 | rprintf(FERROR, | ||
60 | "invalid basis_dir index: %d.\n", | ||
61 | fnamecmp_type); | ||
62 | exit_cleanup(RERR_PROTOCOL); | ||
63 | - } else | ||
64 | - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basis_dir[fnamecmp_type], fname); | ||
65 | - fnamecmp = fnamecmpbuf; | ||
66 | + } else { | ||
67 | + basedir = basis_dir[fnamecmp_type]; | ||
68 | + fnamecmp = fname; | ||
69 | + } | ||
70 | break; | ||
71 | } | ||
72 | if (!fnamecmp || (daemon_filter_list.head | ||
73 | @@ -765,7 +769,7 @@ int recv_files(int f_in, int f_out, char *local_name) | ||
74 | } | ||
75 | |||
76 | /* open the file */ | ||
77 | - fd1 = do_open(fnamecmp, O_RDONLY, 0); | ||
78 | + fd1 = secure_relative_open(basedir, fnamecmp, O_RDONLY, 0); | ||
79 | |||
80 | if (fd1 == -1 && protocol_version < 29) { | ||
81 | if (fnamecmp != fname) { | ||
82 | @@ -776,14 +780,20 @@ int recv_files(int f_in, int f_out, char *local_name) | ||
83 | |||
84 | if (fd1 == -1 && basis_dir[0]) { | ||
85 | /* pre-29 allowed only one alternate basis */ | ||
86 | - pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, | ||
87 | - basis_dir[0], fname); | ||
88 | - fnamecmp = fnamecmpbuf; | ||
89 | + basedir = basis_dir[0]; | ||
90 | + fnamecmp = fname; | ||
91 | fnamecmp_type = FNAMECMP_BASIS_DIR_LOW; | ||
92 | - fd1 = do_open(fnamecmp, O_RDONLY, 0); | ||
93 | + fd1 = secure_relative_open(basedir, fnamecmp, O_RDONLY, 0); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | + if (basedir) { | ||
98 | + // for the following code we need the full | ||
99 | + // path name as a single string | ||
100 | + pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, basedir, fnamecmp); | ||
101 | + fnamecmp = fnamecmpbuf; | ||
102 | + } | ||
103 | + | ||
104 | one_inplace = inplace_partial && fnamecmp_type == FNAMECMP_PARTIAL_DIR; | ||
105 | updating_basis_or_equiv = one_inplace | ||
106 | || (inplace && (fnamecmp == fname || fnamecmp_type == FNAMECMP_BACKUP)); | ||
107 | -- | ||
108 | 2.40.0 | ||
diff --git a/meta/recipes-devtools/rsync/files/CVE-2024-12086-0004.patch b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0004.patch new file mode 100644 index 0000000000..b85e1dfae4 --- /dev/null +++ b/meta/recipes-devtools/rsync/files/CVE-2024-12086-0004.patch | |||
@@ -0,0 +1,41 @@ | |||
1 | From 9f86ddc9652247233f32b241a79d5aa4fb9d4afa Mon Sep 17 00:00:00 2001 | ||
2 | From: Andrew Tridgell <andrew@tridgell.net> | ||
3 | Date: Tue, 26 Nov 2024 09:16:31 +1100 | ||
4 | Subject: [PATCH] disallow ../ elements in relpath for secure_relative_open | ||
5 | |||
6 | CVE: CVE-2024-12086 | ||
7 | |||
8 | Upstream-Status: Backport [https://git.samba.org/?p=rsync.git;a=commit;h=9f86ddc9652247233f32b241a79d5aa4fb9d4afa] | ||
9 | |||
10 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
11 | --- | ||
12 | syscall.c | 7 +++++++ | ||
13 | 1 file changed, 7 insertions(+) | ||
14 | |||
15 | diff --git a/syscall.c b/syscall.c | ||
16 | index cffc814b..081357bb 100644 | ||
17 | --- a/syscall.c | ||
18 | +++ b/syscall.c | ||
19 | @@ -716,6 +716,8 @@ int do_open_nofollow(const char *pathname, int flags) | ||
20 | must be a relative path, and the relpath must not contain any | ||
21 | elements in the path which follow symlinks (ie. like O_NOFOLLOW, but | ||
22 | applies to all path components, not just the last component) | ||
23 | + | ||
24 | + The relpath must also not contain any ../ elements in the path | ||
25 | */ | ||
26 | int secure_relative_open(const char *basedir, const char *relpath, int flags, mode_t mode) | ||
27 | { | ||
28 | @@ -724,6 +726,11 @@ int secure_relative_open(const char *basedir, const char *relpath, int flags, mo | ||
29 | errno = EINVAL; | ||
30 | return -1; | ||
31 | } | ||
32 | + if (strncmp(relpath, "../", 3) == 0 || strstr(relpath, "/../")) { | ||
33 | + // no ../ elements allowed in the relpath | ||
34 | + errno = EINVAL; | ||
35 | + return -1; | ||
36 | + } | ||
37 | |||
38 | #if !defined(O_NOFOLLOW) || !defined(O_DIRECTORY) | ||
39 | // really old system, all we can do is live with the risks | ||
40 | -- | ||
41 | 2.40.0 | ||
diff --git a/meta/recipes-devtools/rsync/rsync_3.2.7.bb b/meta/recipes-devtools/rsync/rsync_3.2.7.bb index 0d9c68a915..0bde73aad2 100644 --- a/meta/recipes-devtools/rsync/rsync_3.2.7.bb +++ b/meta/recipes-devtools/rsync/rsync_3.2.7.bb | |||
@@ -18,6 +18,10 @@ SRC_URI = "https://download.samba.org/pub/${BPN}/src/${BP}.tar.gz \ | |||
18 | file://CVE-2024-12084-0001.patch \ | 18 | file://CVE-2024-12084-0001.patch \ |
19 | file://CVE-2024-12084-0002.patch \ | 19 | file://CVE-2024-12084-0002.patch \ |
20 | file://CVE-2024-12085.patch \ | 20 | file://CVE-2024-12085.patch \ |
21 | file://CVE-2024-12086-0001.patch \ | ||
22 | file://CVE-2024-12086-0002.patch \ | ||
23 | file://CVE-2024-12086-0003.patch \ | ||
24 | file://CVE-2024-12086-0004.patch \ | ||
21 | " | 25 | " |
22 | SRC_URI[sha256sum] = "4e7d9d3f6ed10878c58c5fb724a67dacf4b6aac7340b13e488fb2dc41346f2bb" | 26 | SRC_URI[sha256sum] = "4e7d9d3f6ed10878c58c5fb724a67dacf4b6aac7340b13e488fb2dc41346f2bb" |
23 | 27 | ||