diff options
Diffstat (limited to 'meta/recipes-devtools/git/files/CVE-2022-41903-05.patch')
-rw-r--r-- | meta/recipes-devtools/git/files/CVE-2022-41903-05.patch | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2022-41903-05.patch b/meta/recipes-devtools/git/files/CVE-2022-41903-05.patch new file mode 100644 index 0000000000..994f7a55b1 --- /dev/null +++ b/meta/recipes-devtools/git/files/CVE-2022-41903-05.patch | |||
@@ -0,0 +1,98 @@ | |||
1 | From 1de69c0cdd388b0a5b7bdde0bfa0bda514a354b0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Patrick Steinhardt <ps@pks.im> | ||
3 | Date: Thu, 1 Dec 2022 15:46:39 +0100 | ||
4 | Subject: [PATCH 05/12] pretty: fix adding linefeed when placeholder is not expanded | ||
5 | |||
6 | When a formatting directive has a `+` or ` ` after the `%`, then we add | ||
7 | either a line feed or space if the placeholder expands to a non-empty | ||
8 | string. In specific cases though this logic doesn't work as expected, | ||
9 | and we try to add the character even in the case where the formatting | ||
10 | directive is empty. | ||
11 | |||
12 | One such pattern is `%w(1)%+d%+w(2)`. `%+d` expands to reference names | ||
13 | pointing to a certain commit, like in `git log --decorate`. For a tagged | ||
14 | commit this would for example expand to `\n (tag: v1.0.0)`, which has a | ||
15 | leading newline due to the `+` modifier and a space added by `%d`. Now | ||
16 | the second wrapping directive will cause us to rewrap the text to | ||
17 | `\n(tag:\nv1.0.0)`, which is one byte shorter due to the missing leading | ||
18 | space. The code that handles the `+` magic now notices that the length | ||
19 | has changed and will thus try to insert a leading line feed at the | ||
20 | original posititon. But as the string was shortened, the original | ||
21 | position is past the buffer's boundary and thus we die with an error. | ||
22 | |||
23 | Now there are two issues here: | ||
24 | |||
25 | 1. We check whether the buffer length has changed, not whether it | ||
26 | has been extended. This causes us to try and add the character | ||
27 | past the string boundary. | ||
28 | |||
29 | 2. The current logic does not make any sense whatsoever. When the | ||
30 | string got expanded due to the rewrap, putting the separator into | ||
31 | the original position is likely to put it somewhere into the | ||
32 | middle of the rewrapped contents. | ||
33 | |||
34 | It is debatable whether `%+w()` makes any sense in the first place. | ||
35 | Strictly speaking, the placeholder never expands to a non-empty string, | ||
36 | and consequentially we shouldn't ever accept this combination. We thus | ||
37 | fix the bug by simply refusing `%+w()`. | ||
38 | |||
39 | Signed-off-by: Patrick Steinhardt <ps@pks.im> | ||
40 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | ||
41 | |||
42 | Upstream-Status: Backport [https://github.com/git/git/commit/1de69c0cdd388b0a5b7bdde0bfa0bda514a354b0] | ||
43 | CVE: CVE-2022-41903 | ||
44 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
45 | --- | ||
46 | pretty.c | 14 +++++++++++++- | ||
47 | t/t4205-log-pretty-formats.sh | 8 ++++++++ | ||
48 | 2 files changed, 21 insertions(+), 1 deletion(-) | ||
49 | |||
50 | diff --git a/pretty.c b/pretty.c | ||
51 | index c49e818..195d005 100644 | ||
52 | --- a/pretty.c | ||
53 | +++ b/pretty.c | ||
54 | @@ -1551,9 +1551,21 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ | ||
55 | default: | ||
56 | break; | ||
57 | } | ||
58 | - if (magic != NO_MAGIC) | ||
59 | + if (magic != NO_MAGIC) { | ||
60 | placeholder++; | ||
61 | |||
62 | + switch (placeholder[0]) { | ||
63 | + case 'w': | ||
64 | + /* | ||
65 | + * `%+w()` cannot ever expand to a non-empty string, | ||
66 | + * and it potentially changes the layout of preceding | ||
67 | + * contents. We're thus not able to handle the magic in | ||
68 | + * this combination and refuse the pattern. | ||
69 | + */ | ||
70 | + return 0; | ||
71 | + }; | ||
72 | + } | ||
73 | + | ||
74 | orig_len = sb->len; | ||
75 | if (((struct format_commit_context *)context)->flush_type != no_flush) | ||
76 | consumed = format_and_pad_commit(sb, placeholder, context); | ||
77 | diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh | ||
78 | index 8a349df..fa1bc2b 100755 | ||
79 | --- a/t/t4205-log-pretty-formats.sh | ||
80 | +++ b/t/t4205-log-pretty-formats.sh | ||
81 | @@ -800,6 +800,14 @@ test_expect_success 'log --pretty with invalid padding format' ' | ||
82 | test_cmp expect actual | ||
83 | ' | ||
84 | |||
85 | +test_expect_success 'log --pretty with magical wrapping directives' ' | ||
86 | + commit_id=$(git commit-tree HEAD^{tree} -m "describe me") && | ||
87 | + git tag describe-me $commit_id && | ||
88 | + printf "\n(tag:\ndescribe-me)%%+w(2)" >expect && | ||
89 | + git log -1 --pretty="format:%w(1)%+d%+w(2)" $commit_id >actual && | ||
90 | + test_cmp expect actual | ||
91 | +' | ||
92 | + | ||
93 | test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' ' | ||
94 | # We only assert that this command does not crash. This needs to be | ||
95 | # executed with the address sanitizer to demonstrate failure. | ||
96 | -- | ||
97 | 2.25.1 | ||
98 | |||