diff options
| -rw-r--r-- | meta/recipes-devtools/rsync/files/CVE-2024-12747.patch | 192 | ||||
| -rw-r--r-- | meta/recipes-devtools/rsync/rsync_3.2.7.bb | 1 |
2 files changed, 193 insertions, 0 deletions
diff --git a/meta/recipes-devtools/rsync/files/CVE-2024-12747.patch b/meta/recipes-devtools/rsync/files/CVE-2024-12747.patch new file mode 100644 index 0000000000..b1dd0a03b9 --- /dev/null +++ b/meta/recipes-devtools/rsync/files/CVE-2024-12747.patch | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | From 0590b09d9a34ae72741b91ec0708a820650198b0 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Andrew Tridgell <andrew@tridgell.net> | ||
| 3 | Date: Wed, 18 Dec 2024 08:59:42 +1100 | ||
| 4 | Subject: [PATCH] fixed symlink race condition in sender | ||
| 5 | |||
| 6 | when we open a file that we don't expect to be a symlink use | ||
| 7 | O_NOFOLLOW to prevent a race condition where an attacker could change | ||
| 8 | a file between being a normal file and a symlink | ||
| 9 | |||
| 10 | CVE: CVE-2024-12747 | ||
| 11 | |||
| 12 | Upstream-Status: Backport [https://git.samba.org/?p=rsync.git;a=commit;h=0590b09d9a34ae72741b91ec0708a820650198b0] | ||
| 13 | |||
| 14 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
| 15 | --- | ||
| 16 | checksum.c | 2 +- | ||
| 17 | flist.c | 2 +- | ||
| 18 | generator.c | 4 ++-- | ||
| 19 | receiver.c | 2 +- | ||
| 20 | sender.c | 2 +- | ||
| 21 | syscall.c | 20 ++++++++++++++++++++ | ||
| 22 | t_unsafe.c | 3 +++ | ||
| 23 | tls.c | 3 +++ | ||
| 24 | trimslash.c | 2 ++ | ||
| 25 | util1.c | 2 +- | ||
| 26 | 10 files changed, 35 insertions(+), 7 deletions(-) | ||
| 27 | |||
| 28 | diff --git a/checksum.c b/checksum.c | ||
| 29 | index cb21882c..66e80896 100644 | ||
| 30 | --- a/checksum.c | ||
| 31 | +++ b/checksum.c | ||
| 32 | @@ -406,7 +406,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum) | ||
| 33 | int32 remainder; | ||
| 34 | int fd; | ||
| 35 | |||
| 36 | - fd = do_open(fname, O_RDONLY, 0); | ||
| 37 | + fd = do_open_checklinks(fname); | ||
| 38 | if (fd == -1) { | ||
| 39 | memset(sum, 0, file_sum_len); | ||
| 40 | return; | ||
| 41 | diff --git a/flist.c b/flist.c | ||
| 42 | index 087f9da6..17832533 100644 | ||
| 43 | --- a/flist.c | ||
| 44 | +++ b/flist.c | ||
| 45 | @@ -1390,7 +1390,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, | ||
| 46 | |||
| 47 | if (copy_devices && am_sender && IS_DEVICE(st.st_mode)) { | ||
| 48 | if (st.st_size == 0) { | ||
| 49 | - int fd = do_open(fname, O_RDONLY, 0); | ||
| 50 | + int fd = do_open_checklinks(fname); | ||
| 51 | if (fd >= 0) { | ||
| 52 | st.st_size = get_device_size(fd, fname); | ||
| 53 | close(fd); | ||
| 54 | diff --git a/generator.c b/generator.c | ||
| 55 | index 110db28f..3f13bb95 100644 | ||
| 56 | --- a/generator.c | ||
| 57 | +++ b/generator.c | ||
| 58 | @@ -1798,7 +1798,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, | ||
| 59 | |||
| 60 | if (write_devices && IS_DEVICE(sx.st.st_mode) && sx.st.st_size == 0) { | ||
| 61 | /* This early open into fd skips the regular open below. */ | ||
| 62 | - if ((fd = do_open(fnamecmp, O_RDONLY, 0)) >= 0) | ||
| 63 | + if ((fd = do_open_nofollow(fnamecmp, O_RDONLY)) >= 0) | ||
| 64 | real_sx.st.st_size = sx.st.st_size = get_device_size(fd, fnamecmp); | ||
| 65 | } | ||
| 66 | |||
| 67 | @@ -1867,7 +1867,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, | ||
| 68 | } | ||
| 69 | |||
| 70 | /* open the file */ | ||
| 71 | - if (fd < 0 && (fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) { | ||
| 72 | + if (fd < 0 && (fd = do_open_checklinks(fnamecmp)) < 0) { | ||
| 73 | rsyserr(FERROR, errno, "failed to open %s, continuing", | ||
| 74 | full_fname(fnamecmp)); | ||
| 75 | pretend_missing: | ||
| 76 | diff --git a/receiver.c b/receiver.c | ||
| 77 | index 8031b8f4..edfbb210 100644 | ||
| 78 | --- a/receiver.c | ||
| 79 | +++ b/receiver.c | ||
| 80 | @@ -775,7 +775,7 @@ int recv_files(int f_in, int f_out, char *local_name) | ||
| 81 | if (fnamecmp != fname) { | ||
| 82 | fnamecmp = fname; | ||
| 83 | fnamecmp_type = FNAMECMP_FNAME; | ||
| 84 | - fd1 = do_open(fnamecmp, O_RDONLY, 0); | ||
| 85 | + fd1 = do_open_nofollow(fnamecmp, O_RDONLY); | ||
| 86 | } | ||
| 87 | |||
| 88 | if (fd1 == -1 && basis_dir[0]) { | ||
| 89 | diff --git a/sender.c b/sender.c | ||
| 90 | index 2bbff2fa..a4d46c39 100644 | ||
| 91 | --- a/sender.c | ||
| 92 | +++ b/sender.c | ||
| 93 | @@ -350,7 +350,7 @@ void send_files(int f_in, int f_out) | ||
| 94 | exit_cleanup(RERR_PROTOCOL); | ||
| 95 | } | ||
| 96 | |||
| 97 | - fd = do_open(fname, O_RDONLY, 0); | ||
| 98 | + fd = do_open_checklinks(fname); | ||
| 99 | if (fd == -1) { | ||
| 100 | if (errno == ENOENT) { | ||
| 101 | enum logcode c = am_daemon && protocol_version < 28 ? FERROR : FWARNING; | ||
| 102 | diff --git a/syscall.c b/syscall.c | ||
| 103 | index 081357bb..8cea2900 100644 | ||
| 104 | --- a/syscall.c | ||
| 105 | +++ b/syscall.c | ||
| 106 | @@ -45,6 +45,8 @@ extern int preallocate_files; | ||
| 107 | extern int preserve_perms; | ||
| 108 | extern int preserve_executability; | ||
| 109 | extern int open_noatime; | ||
| 110 | +extern int copy_links; | ||
| 111 | +extern int copy_unsafe_links; | ||
| 112 | |||
| 113 | #ifndef S_BLKSIZE | ||
| 114 | # if defined hpux || defined __hpux__ || defined __hpux | ||
| 115 | @@ -788,3 +790,21 @@ cleanup: | ||
| 116 | return retfd; | ||
| 117 | #endif // O_NOFOLLOW, O_DIRECTORY | ||
| 118 | } | ||
| 119 | + | ||
| 120 | +/* | ||
| 121 | + varient of do_open/do_open_nofollow which does do_open() if the | ||
| 122 | + copy_links or copy_unsafe_links options are set and does | ||
| 123 | + do_open_nofollow() otherwise | ||
| 124 | + | ||
| 125 | + This is used to prevent a race condition where an attacker could be | ||
| 126 | + switching a file between being a symlink and being a normal file | ||
| 127 | + | ||
| 128 | + The open is always done with O_RDONLY flags | ||
| 129 | + */ | ||
| 130 | +int do_open_checklinks(const char *pathname) | ||
| 131 | +{ | ||
| 132 | + if (copy_links || copy_unsafe_links) { | ||
| 133 | + return do_open(pathname, O_RDONLY, 0); | ||
| 134 | + } | ||
| 135 | + return do_open_nofollow(pathname, O_RDONLY); | ||
| 136 | +} | ||
| 137 | diff --git a/t_unsafe.c b/t_unsafe.c | ||
| 138 | index 010cac50..e10619a2 100644 | ||
| 139 | --- a/t_unsafe.c | ||
| 140 | +++ b/t_unsafe.c | ||
| 141 | @@ -28,6 +28,9 @@ int am_root = 0; | ||
| 142 | int am_sender = 1; | ||
| 143 | int read_only = 0; | ||
| 144 | int list_only = 0; | ||
| 145 | +int copy_links = 0; | ||
| 146 | +int copy_unsafe_links = 0; | ||
| 147 | + | ||
| 148 | short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG]; | ||
| 149 | |||
| 150 | int | ||
| 151 | diff --git a/tls.c b/tls.c | ||
| 152 | index e6b0708a..858f8f10 100644 | ||
| 153 | --- a/tls.c | ||
| 154 | +++ b/tls.c | ||
| 155 | @@ -49,6 +49,9 @@ int list_only = 0; | ||
| 156 | int link_times = 0; | ||
| 157 | int link_owner = 0; | ||
| 158 | int nsec_times = 0; | ||
| 159 | +int safe_symlinks = 0; | ||
| 160 | +int copy_links = 0; | ||
| 161 | +int copy_unsafe_links = 0; | ||
| 162 | |||
| 163 | #ifdef SUPPORT_XATTRS | ||
| 164 | |||
| 165 | diff --git a/trimslash.c b/trimslash.c | ||
| 166 | index 1ec928ca..f2774cd7 100644 | ||
| 167 | --- a/trimslash.c | ||
| 168 | +++ b/trimslash.c | ||
| 169 | @@ -26,6 +26,8 @@ int am_root = 0; | ||
| 170 | int am_sender = 1; | ||
| 171 | int read_only = 1; | ||
| 172 | int list_only = 0; | ||
| 173 | +int copy_links = 0; | ||
| 174 | +int copy_unsafe_links = 0; | ||
| 175 | |||
| 176 | int | ||
| 177 | main(int argc, char **argv) | ||
| 178 | diff --git a/util1.c b/util1.c | ||
| 179 | index f260d398..d84bc414 100644 | ||
| 180 | --- a/util1.c | ||
| 181 | +++ b/util1.c | ||
| 182 | @@ -365,7 +365,7 @@ int copy_file(const char *source, const char *dest, int tmpfilefd, mode_t mode) | ||
| 183 | int len; /* Number of bytes read into `buf'. */ | ||
| 184 | OFF_T prealloc_len = 0, offset = 0; | ||
| 185 | |||
| 186 | - if ((ifd = do_open(source, O_RDONLY, 0)) < 0) { | ||
| 187 | + if ((ifd = do_open_nofollow(source, O_RDONLY)) < 0) { | ||
| 188 | int save_errno = errno; | ||
| 189 | rsyserr(FERROR_XFER, errno, "open %s", full_fname(source)); | ||
| 190 | errno = save_errno; | ||
| 191 | -- | ||
| 192 | 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 169650fe91..d0796d3c12 100644 --- a/meta/recipes-devtools/rsync/rsync_3.2.7.bb +++ b/meta/recipes-devtools/rsync/rsync_3.2.7.bb | |||
| @@ -26,6 +26,7 @@ SRC_URI = "https://download.samba.org/pub/${BPN}/src/${BP}.tar.gz \ | |||
| 26 | file://CVE-2024-12087-0002.patch \ | 26 | file://CVE-2024-12087-0002.patch \ |
| 27 | file://CVE-2024-12087-0003.patch \ | 27 | file://CVE-2024-12087-0003.patch \ |
| 28 | file://CVE-2024-12088.patch \ | 28 | file://CVE-2024-12088.patch \ |
| 29 | file://CVE-2024-12747.patch \ | ||
| 29 | " | 30 | " |
| 30 | SRC_URI[sha256sum] = "4e7d9d3f6ed10878c58c5fb724a67dacf4b6aac7340b13e488fb2dc41346f2bb" | 31 | SRC_URI[sha256sum] = "4e7d9d3f6ed10878c58c5fb724a67dacf4b6aac7340b13e488fb2dc41346f2bb" |
| 31 | 32 | ||
