diff options
| -rw-r--r-- | meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch | 200 | ||||
| -rw-r--r-- | meta/recipes-devtools/patch/patch_2.7.1.bb | 1 |
2 files changed, 201 insertions, 0 deletions
diff --git a/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch b/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch new file mode 100644 index 0000000000..d408346ac2 --- /dev/null +++ b/meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | From 4e9269a5fc1fe80a1095a92593dd85db871e1fd3 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Andreas Gruenbacher <andreas.gruenbacher@gmail.com> | ||
| 3 | Date: Mon, 19 Jan 2015 23:18:30 +0100 | ||
| 4 | Subject: [PATCH] Make sure symlinks don't point outside working directory | ||
| 5 | (CVE-2015-1196) | ||
| 6 | |||
| 7 | When creating symlinks from git-style patches, make sure the symlinks don't | ||
| 8 | point above the current working directory. Otherwise, a subsequent patch could | ||
| 9 | use the symlink to write outside the working directory. | ||
| 10 | |||
| 11 | * src/pch.c (symlink_target_is_valid): New function to check for valid symlink | ||
| 12 | targets. | ||
| 13 | * src/util.c (move_file): Use symlink_target_is_valid() here. | ||
| 14 | * tests/symlinks: Add valid and invalid symlink test cases. | ||
| 15 | |||
| 16 | Signed-off-by: Robert Yang <liezhi.yang@windriver.com> | ||
| 17 | |||
| 18 | Upstream-Status: Backport | ||
| 19 | |||
| 20 | --- | ||
| 21 | NEWS | 3 ++ | ||
| 22 | src/pch.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 23 | src/pch.h | 1 + | ||
| 24 | src/util.c | 7 +++++++ | ||
| 25 | tests/symlinks | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 26 | 5 files changed, 117 insertions(+) | ||
| 27 | |||
| 28 | diff --git a/NEWS b/NEWS | ||
| 29 | index 42afed7..d3f1c2d 100644 | ||
| 30 | --- a/NEWS | ||
| 31 | +++ b/NEWS | ||
| 32 | @@ -1,3 +1,6 @@ | ||
| 33 | +* With git-style patches, symlinks that point outside the working directory | ||
| 34 | + will no longer be created. | ||
| 35 | + | ||
| 36 | Changes in version 2.7.1: | ||
| 37 | |||
| 38 | * Two critical bug fixes in the "diff --git" format support. | ||
| 39 | diff --git a/src/pch.c b/src/pch.c | ||
| 40 | index 55e1504..f05ef83 100644 | ||
| 41 | --- a/src/pch.c | ||
| 42 | +++ b/src/pch.c | ||
| 43 | @@ -454,6 +454,60 @@ name_is_valid (char const *name) | ||
| 44 | return is_valid; | ||
| 45 | } | ||
| 46 | |||
| 47 | +bool | ||
| 48 | +symlink_target_is_valid (char const *target, char const *to) | ||
| 49 | +{ | ||
| 50 | + bool is_valid; | ||
| 51 | + | ||
| 52 | + if (IS_ABSOLUTE_FILE_NAME (to)) | ||
| 53 | + is_valid = true; | ||
| 54 | + else if (IS_ABSOLUTE_FILE_NAME (target)) | ||
| 55 | + is_valid = false; | ||
| 56 | + else | ||
| 57 | + { | ||
| 58 | + unsigned int depth = 0; | ||
| 59 | + char const *t; | ||
| 60 | + | ||
| 61 | + is_valid = true; | ||
| 62 | + t = to; | ||
| 63 | + while (*t) | ||
| 64 | + { | ||
| 65 | + while (*t && ! ISSLASH (*t)) | ||
| 66 | + t++; | ||
| 67 | + if (ISSLASH (*t)) | ||
| 68 | + { | ||
| 69 | + while (ISSLASH (*t)) | ||
| 70 | + t++; | ||
| 71 | + depth++; | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + t = target; | ||
| 76 | + while (*t) | ||
| 77 | + { | ||
| 78 | + if (*t == '.' && *++t == '.' && (! *++t || ISSLASH (*t))) | ||
| 79 | + { | ||
| 80 | + if (! depth--) | ||
| 81 | + { | ||
| 82 | + is_valid = false; | ||
| 83 | + break; | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + else | ||
| 87 | + { | ||
| 88 | + while (*t && ! ISSLASH (*t)) | ||
| 89 | + t++; | ||
| 90 | + depth++; | ||
| 91 | + } | ||
| 92 | + while (ISSLASH (*t)) | ||
| 93 | + t++; | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + /* Allow any symlink target if we are in the filesystem root. */ | ||
| 98 | + return is_valid || cwd_is_root (to); | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | /* Determine what kind of diff is in the remaining part of the patch file. */ | ||
| 102 | |||
| 103 | static enum diff | ||
| 104 | diff --git a/src/pch.h b/src/pch.h | ||
| 105 | index 0c7ff62..58861b0 100644 | ||
| 106 | --- a/src/pch.h | ||
| 107 | +++ b/src/pch.h | ||
| 108 | @@ -37,6 +37,7 @@ bool pch_write_line (lin, FILE *); | ||
| 109 | bool there_is_another_patch (bool, mode_t *); | ||
| 110 | char *pfetch (lin) _GL_ATTRIBUTE_PURE; | ||
| 111 | char pch_char (lin) _GL_ATTRIBUTE_PURE; | ||
| 112 | +bool symlink_target_is_valid (char const *, char const *); | ||
| 113 | int another_hunk (enum diff, bool); | ||
| 114 | int pch_says_nonexistent (bool) _GL_ATTRIBUTE_PURE; | ||
| 115 | size_t pch_line_len (lin) _GL_ATTRIBUTE_PURE; | ||
| 116 | diff --git a/src/util.c b/src/util.c | ||
| 117 | index 66ae90f..636eded 100644 | ||
| 118 | --- a/src/util.c | ||
| 119 | +++ b/src/util.c | ||
| 120 | @@ -470,6 +470,13 @@ move_file (char const *from, bool *from_needs_removal, | ||
| 121 | read_fatal (); | ||
| 122 | buffer[size] = 0; | ||
| 123 | |||
| 124 | + if (! symlink_target_is_valid (buffer, to)) | ||
| 125 | + { | ||
| 126 | + fprintf (stderr, "symbolic link target '%s' is invalid\n", | ||
| 127 | + buffer); | ||
| 128 | + fatal_exit (0); | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | if (! backup) | ||
| 132 | { | ||
| 133 | if (unlink (to) == 0) | ||
| 134 | diff --git a/tests/symlinks b/tests/symlinks | ||
| 135 | index 96626b3..6211026 100644 | ||
| 136 | --- a/tests/symlinks | ||
| 137 | +++ b/tests/symlinks | ||
| 138 | @@ -146,6 +146,59 @@ ncheck 'test ! -L symlink' | ||
| 139 | |||
| 140 | # -------------------------------------------------------------- | ||
| 141 | |||
| 142 | +# Patch should not create symlinks which point outside the working directory. | ||
| 143 | + | ||
| 144 | +cat > symlink-target.diff <<EOF | ||
| 145 | +diff --git a/dir/foo b/dir/foo | ||
| 146 | +new file mode 120000 | ||
| 147 | +index 0000000..cad2309 | ||
| 148 | +--- /dev/null | ||
| 149 | ++++ b/dir/foo | ||
| 150 | +@@ -0,0 +1 @@ | ||
| 151 | ++../foo | ||
| 152 | +\ No newline at end of file | ||
| 153 | +EOF | ||
| 154 | + | ||
| 155 | +check 'patch -p1 < symlink-target.diff || echo "Status: $?"' <<EOF | ||
| 156 | +patching symbolic link dir/foo | ||
| 157 | +EOF | ||
| 158 | + | ||
| 159 | +cat > bad-symlink-target1.diff <<EOF | ||
| 160 | +diff --git a/bar b/bar | ||
| 161 | +new file mode 120000 | ||
| 162 | +index 0000000..cad2309 | ||
| 163 | +--- /dev/null | ||
| 164 | ++++ b/bar | ||
| 165 | +@@ -0,0 +1 @@ | ||
| 166 | ++/bar | ||
| 167 | +\ No newline at end of file | ||
| 168 | +EOF | ||
| 169 | + | ||
| 170 | +check 'patch -p1 < bad-symlink-target1.diff || echo "Status: $?"' <<EOF | ||
| 171 | +patching symbolic link bar | ||
| 172 | +symbolic link target '/bar' is invalid | ||
| 173 | +Status: 2 | ||
| 174 | +EOF | ||
| 175 | + | ||
| 176 | +cat > bad-symlink-target2.diff <<EOF | ||
| 177 | +diff --git a/baz b/baz | ||
| 178 | +new file mode 120000 | ||
| 179 | +index 0000000..cad2309 | ||
| 180 | +--- /dev/null | ||
| 181 | ++++ b/baz | ||
| 182 | +@@ -0,0 +1 @@ | ||
| 183 | ++../baz | ||
| 184 | +\ No newline at end of file | ||
| 185 | +EOF | ||
| 186 | + | ||
| 187 | +check 'patch -p1 < bad-symlink-target2.diff || echo "Status: $?"' <<EOF | ||
| 188 | +patching symbolic link baz | ||
| 189 | +symbolic link target '../baz' is invalid | ||
| 190 | +Status: 2 | ||
| 191 | +EOF | ||
| 192 | + | ||
| 193 | +# -------------------------------------------------------------- | ||
| 194 | + | ||
| 195 | # The backup file of a new symlink is an empty regular file. | ||
| 196 | |||
| 197 | check 'patch -p1 --backup < create-symlink.diff || echo "Status: $?"' <<EOF | ||
| 198 | -- | ||
| 199 | 2.1.4 | ||
| 200 | |||
diff --git a/meta/recipes-devtools/patch/patch_2.7.1.bb b/meta/recipes-devtools/patch/patch_2.7.1.bb index 3db318a7ec..1a3b9b1201 100644 --- a/meta/recipes-devtools/patch/patch_2.7.1.bb +++ b/meta/recipes-devtools/patch/patch_2.7.1.bb | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | require patch.inc | 1 | require patch.inc |
| 2 | LICENSE = "GPLv3" | 2 | LICENSE = "GPLv3" |
| 3 | 3 | ||
| 4 | SRC_URI += "file://patch-CVE-2015-1196.patch" | ||
| 4 | 5 | ||
| 5 | SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d" | 6 | SRC_URI[md5sum] = "95dd8d7e41dcbcecdd5cd88ef915378d" |
| 6 | SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5" | 7 | SRC_URI[sha256sum] = "c05f28668c3474bc63adcd48abae921d15e71c254fbebdbaeda40456d64039d5" |
