diff options
| author | Chen Qi <Qi.Chen@windriver.com> | 2025-05-07 22:49:19 -0700 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2025-05-12 22:01:55 +0100 |
| commit | a48e6883611c07d5ab5e69517c9d562902c57888 (patch) | |
| tree | 8cdc23a1bf8711ecc089ceda78a52f1b7062988a /meta | |
| parent | 6c8bf0fcf25e4873ef9e8be6d1c6396cb283dbd9 (diff) | |
| download | poky-a48e6883611c07d5ab5e69517c9d562902c57888.tar.gz | |
busybox: fix CVE-2023-39810
Backport patch to fix CVE-2023-39810.
Note that the patch adds a config option which is disabled by
default. So users wanting this feature needs to enable that option.
(From OE-Core rev: b16c9a295d5d2c5d2100bce11fffeae6beb766c5)
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
| -rw-r--r-- | meta/recipes-core/busybox/busybox/0001-archival-disallow-path-traversals-CVE-2023-39810.patch | 141 | ||||
| -rw-r--r-- | meta/recipes-core/busybox/busybox_1.37.0.bb | 1 |
2 files changed, 142 insertions, 0 deletions
diff --git a/meta/recipes-core/busybox/busybox/0001-archival-disallow-path-traversals-CVE-2023-39810.patch b/meta/recipes-core/busybox/busybox/0001-archival-disallow-path-traversals-CVE-2023-39810.patch new file mode 100644 index 0000000000..e76a4b128e --- /dev/null +++ b/meta/recipes-core/busybox/busybox/0001-archival-disallow-path-traversals-CVE-2023-39810.patch | |||
| @@ -0,0 +1,141 @@ | |||
| 1 | From 42ce7953f48e5542297ff4381086b45ae28a02cf Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Denys Vlasenko <vda.linux@googlemail.com> | ||
| 3 | Date: Wed, 2 Oct 2024 10:12:05 +0200 | ||
| 4 | Subject: [PATCH] archival: disallow path traversals (CVE-2023-39810) | ||
| 5 | |||
| 6 | Create new configure option for archival/libarchive based extractions to | ||
| 7 | disallow path traversals. | ||
| 8 | As this is a paranoid option and might introduce backward | ||
| 9 | incompatibility, default it to no. | ||
| 10 | |||
| 11 | Fixes: CVE-2023-39810 | ||
| 12 | |||
| 13 | Based on the patch by Peter Kaestle <peter.kaestle@nokia.com> | ||
| 14 | |||
| 15 | function old new delta | ||
| 16 | data_extract_all 921 945 +24 | ||
| 17 | strip_unsafe_prefix 101 102 +1 | ||
| 18 | ------------------------------------------------------------------------------ | ||
| 19 | (add/remove: 0/0 grow/shrink: 2/0 up/down: 25/0) Total: 25 bytes | ||
| 20 | |||
| 21 | Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> | ||
| 22 | |||
| 23 | CVE: CVE-2023-39810 | ||
| 24 | |||
| 25 | Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?id=9a8796436b9b0641e13480811902ea2ac57881d3] | ||
| 26 | |||
| 27 | Signed-off-by: Chen Qi <Qi.Chen@windriver.com> | ||
| 28 | --- | ||
| 29 | archival/Config.src | 11 +++++++++++ | ||
| 30 | archival/libarchive/data_extract_all.c | 8 ++++++++ | ||
| 31 | archival/libarchive/unsafe_prefix.c | 6 +++++- | ||
| 32 | scripts/kconfig/lxdialog/check-lxdialog.sh | 2 +- | ||
| 33 | testsuite/cpio.tests | 23 ++++++++++++++++++++++ | ||
| 34 | 5 files changed, 48 insertions(+), 2 deletions(-) | ||
| 35 | |||
| 36 | diff --git a/archival/Config.src b/archival/Config.src | ||
| 37 | index 6f4f30c43..cbcd7217c 100644 | ||
| 38 | --- a/archival/Config.src | ||
| 39 | +++ b/archival/Config.src | ||
| 40 | @@ -35,4 +35,15 @@ config FEATURE_LZMA_FAST | ||
| 41 | This option reduces decompression time by about 25% at the cost of | ||
| 42 | a 1K bigger binary. | ||
| 43 | |||
| 44 | +config FEATURE_PATH_TRAVERSAL_PROTECTION | ||
| 45 | + bool "Prevent extraction of filenames with /../ path component" | ||
| 46 | + default n | ||
| 47 | + help | ||
| 48 | + busybox tar and unzip remove "PREFIX/../" (if it exists) | ||
| 49 | + from extracted names. | ||
| 50 | + This option enables this behavior for all other unpacking applets, | ||
| 51 | + such as cpio, ar, rpm. | ||
| 52 | + GNU cpio 2.15 has NO such sanity check. | ||
| 53 | +# try other archivers and document their behavior? | ||
| 54 | + | ||
| 55 | endmenu | ||
| 56 | diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c | ||
| 57 | index 049c2c156..8a69711c1 100644 | ||
| 58 | --- a/archival/libarchive/data_extract_all.c | ||
| 59 | +++ b/archival/libarchive/data_extract_all.c | ||
| 60 | @@ -65,6 +65,14 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | ||
| 61 | } while (--n != 0); | ||
| 62 | } | ||
| 63 | #endif | ||
| 64 | +#if ENABLE_FEATURE_PATH_TRAVERSAL_PROTECTION | ||
| 65 | + /* Strip leading "/" and up to last "/../" path component */ | ||
| 66 | + dst_name = (char *)strip_unsafe_prefix(dst_name); | ||
| 67 | +#endif | ||
| 68 | +// ^^^ This may be a problem if some applets do need to extract absolute names. | ||
| 69 | +// (Probably will need to invent ARCHIVE_ALLOW_UNSAFE_NAME flag). | ||
| 70 | +// You might think that rpm needs it, but in my tests rpm's internal cpio | ||
| 71 | +// archive has names like "./usr/bin/FOO", not "/usr/bin/FOO". | ||
| 72 | |||
| 73 | if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { | ||
| 74 | char *slash = strrchr(dst_name, '/'); | ||
| 75 | diff --git a/archival/libarchive/unsafe_prefix.c b/archival/libarchive/unsafe_prefix.c | ||
| 76 | index 33e487bf9..667081195 100644 | ||
| 77 | --- a/archival/libarchive/unsafe_prefix.c | ||
| 78 | +++ b/archival/libarchive/unsafe_prefix.c | ||
| 79 | @@ -14,7 +14,11 @@ const char* FAST_FUNC strip_unsafe_prefix(const char *str) | ||
| 80 | cp++; | ||
| 81 | continue; | ||
| 82 | } | ||
| 83 | - if (is_prefixed_with(cp, "/../"+1)) { | ||
| 84 | + /* We are called lots of times. | ||
| 85 | + * is_prefixed_with(cp, "../") is slower than open-coding it, | ||
| 86 | + * with minimal code growth (~few bytes). | ||
| 87 | + */ | ||
| 88 | + if (cp[0] == '.' && cp[1] == '.' && cp[2] == '/') { | ||
| 89 | cp += 3; | ||
| 90 | continue; | ||
| 91 | } | ||
| 92 | diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh | ||
| 93 | index 7003e026a..b91a54be6 100755 | ||
| 94 | --- a/scripts/kconfig/lxdialog/check-lxdialog.sh | ||
| 95 | +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh | ||
| 96 | @@ -55,7 +55,7 @@ trap "rm -f $tmp" 0 1 2 3 15 | ||
| 97 | check() { | ||
| 98 | $cc -x c - -o $tmp 2>/dev/null <<'EOF' | ||
| 99 | #include CURSES_LOC | ||
| 100 | -main() {} | ||
| 101 | +int main() { return 0; } | ||
| 102 | EOF | ||
| 103 | if [ $? != 0 ]; then | ||
| 104 | echo " *** Unable to find the ncurses libraries or the" 1>&2 | ||
| 105 | diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests | ||
| 106 | index 85e746589..a4462c53e 100755 | ||
| 107 | --- a/testsuite/cpio.tests | ||
| 108 | +++ b/testsuite/cpio.tests | ||
| 109 | @@ -154,6 +154,29 @@ testing "cpio -R with extract" \ | ||
| 110 | " "" "" | ||
| 111 | SKIP= | ||
| 112 | |||
| 113 | +# Create an archive containing a file with "../dont_write" filename. | ||
| 114 | +# See that it will not be allowed to unpack. | ||
| 115 | +# NB: GNU cpio 2.15 DOES NOT do such checks. | ||
| 116 | +optional FEATURE_PATH_TRAVERSAL_PROTECTION | ||
| 117 | +rm -rf cpio.testdir | ||
| 118 | +mkdir -p cpio.testdir/prepare/inner | ||
| 119 | +echo "file outside of destination was written" > cpio.testdir/prepare/dont_write | ||
| 120 | +echo "data" > cpio.testdir/prepare/inner/to_extract | ||
| 121 | +mkdir -p cpio.testdir/extract | ||
| 122 | +testing "cpio extract file outside of destination" "\ | ||
| 123 | +(cd cpio.testdir/prepare/inner && echo -e '../dont_write\nto_extract' | cpio -o -H newc) | (cd cpio.testdir/extract && cpio -vi 2>&1) | ||
| 124 | +echo \$? | ||
| 125 | +ls cpio.testdir/dont_write 2>&1" \ | ||
| 126 | +"\ | ||
| 127 | +cpio: removing leading '../' from member names | ||
| 128 | +../dont_write | ||
| 129 | +to_extract | ||
| 130 | +1 blocks | ||
| 131 | +0 | ||
| 132 | +ls: cpio.testdir/dont_write: No such file or directory | ||
| 133 | +" "" "" | ||
| 134 | +SKIP= | ||
| 135 | + | ||
| 136 | # Clean up | ||
| 137 | rm -rf cpio.testdir cpio.testdir2 2>/dev/null | ||
| 138 | |||
| 139 | -- | ||
| 140 | 2.48.1 | ||
| 141 | |||
diff --git a/meta/recipes-core/busybox/busybox_1.37.0.bb b/meta/recipes-core/busybox/busybox_1.37.0.bb index c3131eb453..85f22ada53 100644 --- a/meta/recipes-core/busybox/busybox_1.37.0.bb +++ b/meta/recipes-core/busybox/busybox_1.37.0.bb | |||
| @@ -53,6 +53,7 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \ | |||
| 53 | file://0001-syslogd-fix-wrong-OPT_locallog-flag-detection.patch \ | 53 | file://0001-syslogd-fix-wrong-OPT_locallog-flag-detection.patch \ |
| 54 | file://0002-start-stop-daemon-fix-tests.patch \ | 54 | file://0002-start-stop-daemon-fix-tests.patch \ |
| 55 | file://0003-start-stop-false.patch \ | 55 | file://0003-start-stop-false.patch \ |
| 56 | file://0001-archival-disallow-path-traversals-CVE-2023-39810.patch \ | ||
| 56 | " | 57 | " |
| 57 | SRC_URI:append:libc-musl = " file://musl.cfg" | 58 | SRC_URI:append:libc-musl = " file://musl.cfg" |
| 58 | SRC_URI:append:x86-64 = " file://sha_accel.cfg" | 59 | SRC_URI:append:x86-64 = " file://sha_accel.cfg" |
