diff options
Diffstat (limited to 'meta/recipes-devtools/git/files/CVE-2022-41903-09.patch')
| -rw-r--r-- | meta/recipes-devtools/git/files/CVE-2022-41903-09.patch | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2022-41903-09.patch b/meta/recipes-devtools/git/files/CVE-2022-41903-09.patch new file mode 100644 index 0000000000..761d4c6a9f --- /dev/null +++ b/meta/recipes-devtools/git/files/CVE-2022-41903-09.patch | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | From 937b71cc8b5b998963a7f9a33312ba3549d55510 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Patrick Steinhardt <ps@pks.im> | ||
| 3 | Date: Thu, 1 Dec 2022 15:47:04 +0100 | ||
| 4 | Subject: [PATCH 09/12] utf8: fix overflow when returning string width | ||
| 5 | |||
| 6 | The return type of both `utf8_strwidth()` and `utf8_strnwidth()` is | ||
| 7 | `int`, but we operate on string lengths which are typically of type | ||
| 8 | `size_t`. This means that when the string is longer than `INT_MAX`, we | ||
| 9 | will overflow and thus return a negative result. | ||
| 10 | |||
| 11 | This can lead to an out-of-bounds write with `--pretty=format:%<1)%B` | ||
| 12 | and a commit message that is 2^31+1 bytes long: | ||
| 13 | |||
| 14 | ================================================================= | ||
| 15 | ==26009==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000001168 at pc 0x7f95c4e5f427 bp 0x7ffd8541c900 sp 0x7ffd8541c0a8 | ||
| 16 | WRITE of size 2147483649 at 0x603000001168 thread T0 | ||
| 17 | #0 0x7f95c4e5f426 in __interceptor_memcpy /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 | ||
| 18 | #1 0x5612bbb1068c in format_and_pad_commit pretty.c:1763 | ||
| 19 | #2 0x5612bbb1087a in format_commit_item pretty.c:1801 | ||
| 20 | #3 0x5612bbc33bab in strbuf_expand strbuf.c:429 | ||
| 21 | #4 0x5612bbb110e7 in repo_format_commit_message pretty.c:1869 | ||
| 22 | #5 0x5612bbb12d96 in pretty_print_commit pretty.c:2161 | ||
| 23 | #6 0x5612bba0a4d5 in show_log log-tree.c:781 | ||
| 24 | #7 0x5612bba0d6c7 in log_tree_commit log-tree.c:1117 | ||
| 25 | #8 0x5612bb691ed5 in cmd_log_walk_no_free builtin/log.c:508 | ||
| 26 | #9 0x5612bb69235b in cmd_log_walk builtin/log.c:549 | ||
| 27 | #10 0x5612bb6951a2 in cmd_log builtin/log.c:883 | ||
| 28 | #11 0x5612bb56c993 in run_builtin git.c:466 | ||
| 29 | #12 0x5612bb56d397 in handle_builtin git.c:721 | ||
| 30 | #13 0x5612bb56db07 in run_argv git.c:788 | ||
| 31 | #14 0x5612bb56e8a7 in cmd_main git.c:923 | ||
| 32 | #15 0x5612bb803682 in main common-main.c:57 | ||
| 33 | #16 0x7f95c4c3c28f (/usr/lib/libc.so.6+0x2328f) | ||
| 34 | #17 0x7f95c4c3c349 in __libc_start_main (/usr/lib/libc.so.6+0x23349) | ||
| 35 | #18 0x5612bb5680e4 in _start ../sysdeps/x86_64/start.S:115 | ||
| 36 | |||
| 37 | 0x603000001168 is located 0 bytes to the right of 24-byte region [0x603000001150,0x603000001168) | ||
| 38 | allocated by thread T0 here: | ||
| 39 | #0 0x7f95c4ebe7ea in __interceptor_realloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:85 | ||
| 40 | #1 0x5612bbcdd556 in xrealloc wrapper.c:136 | ||
| 41 | #2 0x5612bbc310a3 in strbuf_grow strbuf.c:99 | ||
| 42 | #3 0x5612bbc32acd in strbuf_add strbuf.c:298 | ||
| 43 | #4 0x5612bbc33aec in strbuf_expand strbuf.c:418 | ||
| 44 | #5 0x5612bbb110e7 in repo_format_commit_message pretty.c:1869 | ||
| 45 | #6 0x5612bbb12d96 in pretty_print_commit pretty.c:2161 | ||
| 46 | #7 0x5612bba0a4d5 in show_log log-tree.c:781 | ||
| 47 | #8 0x5612bba0d6c7 in log_tree_commit log-tree.c:1117 | ||
| 48 | #9 0x5612bb691ed5 in cmd_log_walk_no_free builtin/log.c:508 | ||
| 49 | #10 0x5612bb69235b in cmd_log_walk builtin/log.c:549 | ||
| 50 | #11 0x5612bb6951a2 in cmd_log builtin/log.c:883 | ||
| 51 | #12 0x5612bb56c993 in run_builtin git.c:466 | ||
| 52 | #13 0x5612bb56d397 in handle_builtin git.c:721 | ||
| 53 | #14 0x5612bb56db07 in run_argv git.c:788 | ||
| 54 | #15 0x5612bb56e8a7 in cmd_main git.c:923 | ||
| 55 | #16 0x5612bb803682 in main common-main.c:57 | ||
| 56 | #17 0x7f95c4c3c28f (/usr/lib/libc.so.6+0x2328f) | ||
| 57 | |||
| 58 | SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy | ||
| 59 | Shadow bytes around the buggy address: | ||
| 60 | 0x0c067fff81d0: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fa | ||
| 61 | 0x0c067fff81e0: fa fa fd fd fd fd fa fa fd fd fd fd fa fa fd fd | ||
| 62 | 0x0c067fff81f0: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa | ||
| 63 | 0x0c067fff8200: fd fd fd fa fa fa fd fd fd fd fa fa 00 00 00 fa | ||
| 64 | 0x0c067fff8210: fa fa fd fd fd fa fa fa fd fd fd fa fa fa fd fd | ||
| 65 | =>0x0c067fff8220: fd fa fa fa fd fd fd fa fa fa 00 00 00[fa]fa fa | ||
| 66 | 0x0c067fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | ||
| 67 | 0x0c067fff8240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | ||
| 68 | 0x0c067fff8250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | ||
| 69 | 0x0c067fff8260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | ||
| 70 | 0x0c067fff8270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa | ||
| 71 | Shadow byte legend (one shadow byte represents 8 application bytes): | ||
| 72 | Addressable: 00 | ||
| 73 | Partially addressable: 01 02 03 04 05 06 07 | ||
| 74 | Heap left redzone: fa | ||
| 75 | Freed heap region: fd | ||
| 76 | Stack left redzone: f1 | ||
| 77 | Stack mid redzone: f2 | ||
| 78 | Stack right redzone: f3 | ||
| 79 | Stack after return: f5 | ||
| 80 | Stack use after scope: f8 | ||
| 81 | Global redzone: f9 | ||
| 82 | Global init order: f6 | ||
| 83 | Poisoned by user: f7 | ||
| 84 | Container overflow: fc | ||
| 85 | Array cookie: ac | ||
| 86 | Intra object redzone: bb | ||
| 87 | ASan internal: fe | ||
| 88 | Left alloca redzone: ca | ||
| 89 | Right alloca redzone: cb | ||
| 90 | ==26009==ABORTING | ||
| 91 | |||
| 92 | Now the proper fix for this would be to convert both functions to return | ||
| 93 | an `size_t` instead of an `int`. But given that this commit may be part | ||
| 94 | of a security release, let's instead do the minimal viable fix and die | ||
| 95 | in case we see an overflow. | ||
| 96 | |||
| 97 | Add a test that would have previously caused us to crash. | ||
| 98 | |||
| 99 | Signed-off-by: Patrick Steinhardt <ps@pks.im> | ||
| 100 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | ||
| 101 | |||
| 102 | Upstream-Status: Backport [https://github.com/git/git/commit/937b71cc8b5b998963a7f9a33312ba3549d55510] | ||
| 103 | CVE: CVE-2022-41903 | ||
| 104 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
| 105 | --- | ||
| 106 | t/t4205-log-pretty-formats.sh | 8 ++++++++ | ||
| 107 | utf8.c | 12 +++++++++--- | ||
| 108 | 2 files changed, 17 insertions(+), 3 deletions(-) | ||
| 109 | |||
| 110 | diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh | ||
| 111 | index 261a6f0..de15007 100755 | ||
| 112 | --- a/t/t4205-log-pretty-formats.sh | ||
| 113 | +++ b/t/t4205-log-pretty-formats.sh | ||
| 114 | @@ -843,4 +843,12 @@ test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit mes | ||
| 115 | test_cmp expect actual | ||
| 116 | ' | ||
| 117 | |||
| 118 | +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message does not cause allocation failure' ' | ||
| 119 | + test_must_fail git log -1 --format="%<(1)%B" $huge_commit 2>error && | ||
| 120 | + cat >expect <<-EOF && | ||
| 121 | + fatal: number too large to represent as int on this platform: 2147483649 | ||
| 122 | + EOF | ||
| 123 | + test_cmp expect error | ||
| 124 | +' | ||
| 125 | + | ||
| 126 | test_done | ||
| 127 | diff --git a/utf8.c b/utf8.c | ||
| 128 | index 6632bd2..03be475 100644 | ||
| 129 | --- a/utf8.c | ||
| 130 | +++ b/utf8.c | ||
| 131 | @@ -208,11 +208,12 @@ int utf8_width(const char **start, size_t *remainder_p) | ||
| 132 | */ | ||
| 133 | int utf8_strnwidth(const char *string, size_t len, int skip_ansi) | ||
| 134 | { | ||
| 135 | - int width = 0; | ||
| 136 | const char *orig = string; | ||
| 137 | + size_t width = 0; | ||
| 138 | |||
| 139 | while (string && string < orig + len) { | ||
| 140 | - int glyph_width, skip; | ||
| 141 | + int glyph_width; | ||
| 142 | + size_t skip; | ||
| 143 | |||
| 144 | while (skip_ansi && | ||
| 145 | (skip = display_mode_esc_sequence_len(string)) != 0) | ||
| 146 | @@ -222,7 +223,12 @@ int utf8_strnwidth(const char *string, size_t len, int skip_ansi) | ||
| 147 | if (glyph_width > 0) | ||
| 148 | width += glyph_width; | ||
| 149 | } | ||
| 150 | - return string ? width : len; | ||
| 151 | + | ||
| 152 | + /* | ||
| 153 | + * TODO: fix the interface of this function and `utf8_strwidth()` to | ||
| 154 | + * return `size_t` instead of `int`. | ||
| 155 | + */ | ||
| 156 | + return cast_size_t_to_int(string ? width : len); | ||
| 157 | } | ||
| 158 | |||
| 159 | int utf8_strwidth(const char *string) | ||
| 160 | -- | ||
| 161 | 2.25.1 | ||
| 162 | |||
