diff options
Diffstat (limited to 'meta/recipes-devtools/git/files/CVE-2022-41903-10.patch')
-rw-r--r-- | meta/recipes-devtools/git/files/CVE-2022-41903-10.patch | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2022-41903-10.patch b/meta/recipes-devtools/git/files/CVE-2022-41903-10.patch new file mode 100644 index 0000000000..bbfc6e758f --- /dev/null +++ b/meta/recipes-devtools/git/files/CVE-2022-41903-10.patch | |||
@@ -0,0 +1,99 @@ | |||
1 | From 81c2d4c3a5ba0e6ab8c348708441fed170e63a82 Mon Sep 17 00:00:00 2001 | ||
2 | From: Patrick Steinhardt <ps@pks.im> | ||
3 | Date: Thu, 1 Dec 2022 15:47:10 +0100 | ||
4 | Subject: [PATCH 10/12] utf8: fix checking for glyph width in strbuf_utf8_replace() | ||
5 | |||
6 | In `strbuf_utf8_replace()`, we call `utf8_width()` to compute the width | ||
7 | of the current glyph. If the glyph is a control character though it can | ||
8 | be that `utf8_width()` returns `-1`, but because we assign this value to | ||
9 | a `size_t` the conversion will cause us to underflow. This bug can | ||
10 | easily be triggered with the following command: | ||
11 | |||
12 | $ git log --pretty='format:xxx%<|(1,trunc)%x10' | ||
13 | |||
14 | >From all I can see though this seems to be a benign underflow that has | ||
15 | no security-related consequences. | ||
16 | |||
17 | Fix the bug by using an `int` instead. When we see a control character, | ||
18 | we now copy it into the target buffer but don't advance the current | ||
19 | width of the string. | ||
20 | |||
21 | Signed-off-by: Patrick Steinhardt <ps@pks.im> | ||
22 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | ||
23 | |||
24 | Upstream-Status: Backport [https://github.com/git/git/commit/81c2d4c3a5ba0e6ab8c348708441fed170e63a82] | ||
25 | CVE: CVE-2022-41903 | ||
26 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
27 | --- | ||
28 | t/t4205-log-pretty-formats.sh | 7 +++++++ | ||
29 | utf8.c | 19 ++++++++++++++----- | ||
30 | 2 files changed, 21 insertions(+), 5 deletions(-) | ||
31 | |||
32 | diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh | ||
33 | index de15007..52c8bc8 100755 | ||
34 | --- a/t/t4205-log-pretty-formats.sh | ||
35 | +++ b/t/t4205-log-pretty-formats.sh | ||
36 | @@ -826,6 +826,13 @@ test_expect_success 'log --pretty with padding and preceding control chars' ' | ||
37 | test_cmp expect actual | ||
38 | ' | ||
39 | |||
40 | +test_expect_success 'log --pretty truncation with control chars' ' | ||
41 | + test_commit "$(printf "\20\20\20\20xxxx")" file contents commit-with-control-chars && | ||
42 | + printf "\20\20\20\20x.." >expect && | ||
43 | + git log -1 --pretty="format:%<(3,trunc)%s" commit-with-control-chars >actual && | ||
44 | + test_cmp expect actual | ||
45 | +' | ||
46 | + | ||
47 | test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' ' | ||
48 | # We only assert that this command does not crash. This needs to be | ||
49 | # executed with the address sanitizer to demonstrate failure. | ||
50 | diff --git a/utf8.c b/utf8.c | ||
51 | index 03be475..ec03e69 100644 | ||
52 | --- a/utf8.c | ||
53 | +++ b/utf8.c | ||
54 | @@ -377,6 +377,7 @@ void strbuf_utf8_replace(struct strbuf *sb_src, int pos, int width, | ||
55 | dst = sb_dst.buf; | ||
56 | |||
57 | while (src < end) { | ||
58 | + int glyph_width; | ||
59 | char *old; | ||
60 | size_t n; | ||
61 | |||
62 | @@ -390,21 +391,29 @@ void strbuf_utf8_replace(struct strbuf *sb_src, int pos, int width, | ||
63 | break; | ||
64 | |||
65 | old = src; | ||
66 | - n = utf8_width((const char**)&src, NULL); | ||
67 | - if (!src) /* broken utf-8, do nothing */ | ||
68 | + glyph_width = utf8_width((const char**)&src, NULL); | ||
69 | + if (!src) /* broken utf-8, do nothing */ | ||
70 | goto out; | ||
71 | - if (n && w >= pos && w < pos + width) { | ||
72 | + | ||
73 | + /* | ||
74 | + * In case we see a control character we copy it into the | ||
75 | + * buffer, but don't add it to the width. | ||
76 | + */ | ||
77 | + if (glyph_width < 0) | ||
78 | + glyph_width = 0; | ||
79 | + | ||
80 | + if (glyph_width && w >= pos && w < pos + width) { | ||
81 | if (subst) { | ||
82 | memcpy(dst, subst, subst_len); | ||
83 | dst += subst_len; | ||
84 | subst = NULL; | ||
85 | } | ||
86 | - w += n; | ||
87 | + w += glyph_width; | ||
88 | continue; | ||
89 | } | ||
90 | memcpy(dst, old, src - old); | ||
91 | dst += src - old; | ||
92 | - w += n; | ||
93 | + w += glyph_width; | ||
94 | } | ||
95 | strbuf_setlen(&sb_dst, dst - sb_dst.buf); | ||
96 | strbuf_swap(sb_src, &sb_dst); | ||
97 | -- | ||
98 | 2.25.1 | ||
99 | |||