diff options
Diffstat (limited to 'meta/recipes-devtools/git/files/CVE-2023-23946.patch')
| -rw-r--r-- | meta/recipes-devtools/git/files/CVE-2023-23946.patch | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2023-23946.patch b/meta/recipes-devtools/git/files/CVE-2023-23946.patch new file mode 100644 index 0000000000..3629ff57b2 --- /dev/null +++ b/meta/recipes-devtools/git/files/CVE-2023-23946.patch | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | From fade728df1221598f42d391cf377e9e84a32053f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Patrick Steinhardt <ps@pks.im> | ||
| 3 | Date: Thu, 2 Feb 2023 11:54:34 +0100 | ||
| 4 | Subject: [PATCH] apply: fix writing behind newly created symbolic links | ||
| 5 | |||
| 6 | When writing files git-apply(1) initially makes sure that none of the | ||
| 7 | files it is about to create are behind a symlink: | ||
| 8 | |||
| 9 | ``` | ||
| 10 | $ git init repo | ||
| 11 | Initialized empty Git repository in /tmp/repo/.git/ | ||
| 12 | $ cd repo/ | ||
| 13 | $ ln -s dir symlink | ||
| 14 | $ git apply - <<EOF | ||
| 15 | diff --git a/symlink/file b/symlink/file | ||
| 16 | new file mode 100644 | ||
| 17 | index 0000000..e69de29 | ||
| 18 | EOF | ||
| 19 | error: affected file 'symlink/file' is beyond a symbolic link | ||
| 20 | ``` | ||
| 21 | |||
| 22 | This safety mechanism is crucial to ensure that we don't write outside | ||
| 23 | of the repository's working directory. It can be fooled though when the | ||
| 24 | patch that is being applied creates the symbolic link in the first | ||
| 25 | place, which can lead to writing files in arbitrary locations. | ||
| 26 | |||
| 27 | Fix this by checking whether the path we're about to create is | ||
| 28 | beyond a symlink or not. Tightening these checks like this should be | ||
| 29 | fine as we already have these precautions in Git as explained | ||
| 30 | above. Ideally, we should update the check we do up-front before | ||
| 31 | starting to reflect the computed changes to the working tree so that | ||
| 32 | we catch this case as well, but as part of embargoed security work, | ||
| 33 | adding an equivalent check just before we try to write out a file | ||
| 34 | should serve us well as a reasonable first step. | ||
| 35 | |||
| 36 | Digging back into history shows that this vulnerability has existed | ||
| 37 | since at least Git v2.9.0. As Git v2.8.0 and older don't build on my | ||
| 38 | system anymore I cannot tell whether older versions are affected, as | ||
| 39 | well. | ||
| 40 | |||
| 41 | Reported-by: Joern Schneeweisz <jschneeweisz@gitlab.com> | ||
| 42 | Signed-off-by: Patrick Steinhardt <ps@pks.im> | ||
| 43 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | ||
| 44 | |||
| 45 | Upstream-Status: Backport | ||
| 46 | [https://github.com/git/git/commit/fade728df1221598f42d391cf377e9e84a32053f] | ||
| 47 | CVE: CVE-2023-23946 | ||
| 48 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
| 49 | --- | ||
| 50 | apply.c | 27 ++++++++++++++ | ||
| 51 | t/t4115-apply-symlink.sh | 81 ++++++++++++++++++++++++++++++++++++++++ | ||
| 52 | 2 files changed, 108 insertions(+) | ||
| 53 | |||
| 54 | diff --git a/apply.c b/apply.c | ||
| 55 | index f8a046a..4f303bf 100644 | ||
| 56 | --- a/apply.c | ||
| 57 | +++ b/apply.c | ||
| 58 | @@ -4373,6 +4373,33 @@ static int create_one_file(struct apply_state *state, | ||
| 59 | if (state->cached) | ||
| 60 | return 0; | ||
| 61 | |||
| 62 | + /* | ||
| 63 | + * We already try to detect whether files are beyond a symlink in our | ||
| 64 | + * up-front checks. But in the case where symlinks are created by any | ||
| 65 | + * of the intermediate hunks it can happen that our up-front checks | ||
| 66 | + * didn't yet see the symlink, but at the point of arriving here there | ||
| 67 | + * in fact is one. We thus repeat the check for symlinks here. | ||
| 68 | + * | ||
| 69 | + * Note that this does not make the up-front check obsolete as the | ||
| 70 | + * failure mode is different: | ||
| 71 | + * | ||
| 72 | + * - The up-front checks cause us to abort before we have written | ||
| 73 | + * anything into the working directory. So when we exit this way the | ||
| 74 | + * working directory remains clean. | ||
| 75 | + * | ||
| 76 | + * - The checks here happen in the middle of the action where we have | ||
| 77 | + * already started to apply the patch. The end result will be a dirty | ||
| 78 | + * working directory. | ||
| 79 | + * | ||
| 80 | + * Ideally, we should update the up-front checks to catch what would | ||
| 81 | + * happen when we apply the patch before we damage the working tree. | ||
| 82 | + * We have all the information necessary to do so. But for now, as a | ||
| 83 | + * part of embargoed security work, having this check would serve as a | ||
| 84 | + * reasonable first step. | ||
| 85 | + */ | ||
| 86 | + if (path_is_beyond_symlink(state, path)) | ||
| 87 | + return error(_("affected file '%s' is beyond a symbolic link"), path); | ||
| 88 | + | ||
| 89 | res = try_create_file(state, path, mode, buf, size); | ||
| 90 | if (res < 0) | ||
| 91 | return -1; | ||
| 92 | diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh | ||
| 93 | index 872fcda..1acb7b2 100755 | ||
| 94 | --- a/t/t4115-apply-symlink.sh | ||
| 95 | +++ b/t/t4115-apply-symlink.sh | ||
| 96 | @@ -44,4 +44,85 @@ test_expect_success 'apply --index symlink patch' ' | ||
| 97 | |||
| 98 | ' | ||
| 99 | |||
| 100 | +test_expect_success 'symlink setup' ' | ||
| 101 | + ln -s .git symlink && | ||
| 102 | + git add symlink && | ||
| 103 | + git commit -m "add symlink" | ||
| 104 | +' | ||
| 105 | + | ||
| 106 | +test_expect_success SYMLINKS 'symlink escape when creating new files' ' | ||
| 107 | + test_when_finished "git reset --hard && git clean -dfx" && | ||
| 108 | + | ||
| 109 | + cat >patch <<-EOF && | ||
| 110 | + diff --git a/symlink b/renamed-symlink | ||
| 111 | + similarity index 100% | ||
| 112 | + rename from symlink | ||
| 113 | + rename to renamed-symlink | ||
| 114 | + -- | ||
| 115 | + diff --git /dev/null b/renamed-symlink/create-me | ||
| 116 | + new file mode 100644 | ||
| 117 | + index 0000000..039727e | ||
| 118 | + --- /dev/null | ||
| 119 | + +++ b/renamed-symlink/create-me | ||
| 120 | + @@ -0,0 +1,1 @@ | ||
| 121 | + +busted | ||
| 122 | + EOF | ||
| 123 | + | ||
| 124 | + test_must_fail git apply patch 2>stderr && | ||
| 125 | + cat >expected_stderr <<-EOF && | ||
| 126 | + error: affected file ${SQ}renamed-symlink/create-me${SQ} is beyond a symbolic link | ||
| 127 | + EOF | ||
| 128 | + test_cmp expected_stderr stderr && | ||
| 129 | + ! test_path_exists .git/create-me | ||
| 130 | +' | ||
| 131 | + | ||
| 132 | +test_expect_success SYMLINKS 'symlink escape when modifying file' ' | ||
| 133 | + test_when_finished "git reset --hard && git clean -dfx" && | ||
| 134 | + touch .git/modify-me && | ||
| 135 | + | ||
| 136 | + cat >patch <<-EOF && | ||
| 137 | + diff --git a/symlink b/renamed-symlink | ||
| 138 | + similarity index 100% | ||
| 139 | + rename from symlink | ||
| 140 | + rename to renamed-symlink | ||
| 141 | + -- | ||
| 142 | + diff --git a/renamed-symlink/modify-me b/renamed-symlink/modify-me | ||
| 143 | + index 1111111..2222222 100644 | ||
| 144 | + --- a/renamed-symlink/modify-me | ||
| 145 | + +++ b/renamed-symlink/modify-me | ||
| 146 | + @@ -0,0 +1,1 @@ | ||
| 147 | + +busted | ||
| 148 | + EOF | ||
| 149 | + | ||
| 150 | + test_must_fail git apply patch 2>stderr && | ||
| 151 | + cat >expected_stderr <<-EOF && | ||
| 152 | + error: renamed-symlink/modify-me: No such file or directory | ||
| 153 | + EOF | ||
| 154 | + test_cmp expected_stderr stderr && | ||
| 155 | + test_must_be_empty .git/modify-me | ||
| 156 | +' | ||
| 157 | + | ||
| 158 | +test_expect_success SYMLINKS 'symlink escape when deleting file' ' | ||
| 159 | + test_when_finished "git reset --hard && git clean -dfx && rm .git/delete-me" && | ||
| 160 | + touch .git/delete-me && | ||
| 161 | + | ||
| 162 | + cat >patch <<-EOF && | ||
| 163 | + diff --git a/symlink b/renamed-symlink | ||
| 164 | + similarity index 100% | ||
| 165 | + rename from symlink | ||
| 166 | + rename to renamed-symlink | ||
| 167 | + -- | ||
| 168 | + diff --git a/renamed-symlink/delete-me b/renamed-symlink/delete-me | ||
| 169 | + deleted file mode 100644 | ||
| 170 | + index 1111111..0000000 100644 | ||
| 171 | + EOF | ||
| 172 | + | ||
| 173 | + test_must_fail git apply patch 2>stderr && | ||
| 174 | + cat >expected_stderr <<-EOF && | ||
| 175 | + error: renamed-symlink/delete-me: No such file or directory | ||
| 176 | + EOF | ||
| 177 | + test_cmp expected_stderr stderr && | ||
| 178 | + test_path_is_file .git/delete-me | ||
| 179 | +' | ||
| 180 | + | ||
| 181 | test_done | ||
| 182 | -- | ||
| 183 | 2.25.1 | ||
| 184 | |||
