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 | |||