From 66db094272742977499fd51f48ccba95ab34287b Mon Sep 17 00:00:00 2001 From: Robert Yang Date: Wed, 25 Mar 2015 23:42:34 -0700 Subject: patch: fix CVE-2015-1196 A directory traversal flaw was reported in patch: References: http://www.openwall.com/lists/oss-security/2015/01/18/6 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=775227 https://bugzilla.redhat.com/show_bug.cgi?id=1182154 [YOCTO #7182] (From OE-Core rev: 4c389880dc9c6221344f7aed221fe8356e8c2056) (From OE-Core rev: e2032c5788f7a77aa0e4e8545b550551c23a25fb) Signed-off-by: Robert Yang Signed-off-by: Richard Purdie Signed-off-by: Armin Kuster Signed-off-by: Richard Purdie Signed-off-by: Sona Sarmadi --- .../patch/patch/patch-CVE-2015-1196.patch | 200 +++++++++++++++++++++ meta/recipes-devtools/patch/patch_2.7.1.bb | 1 + 2 files changed, 201 insertions(+) create mode 100644 meta/recipes-devtools/patch/patch/patch-CVE-2015-1196.patch 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 @@ +From 4e9269a5fc1fe80a1095a92593dd85db871e1fd3 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 19 Jan 2015 23:18:30 +0100 +Subject: [PATCH] Make sure symlinks don't point outside working directory + (CVE-2015-1196) + +When creating symlinks from git-style patches, make sure the symlinks don't +point above the current working directory. Otherwise, a subsequent patch could +use the symlink to write outside the working directory. + +* src/pch.c (symlink_target_is_valid): New function to check for valid symlink +targets. +* src/util.c (move_file): Use symlink_target_is_valid() here. +* tests/symlinks: Add valid and invalid symlink test cases. + +Signed-off-by: Robert Yang + +Upstream-Status: Backport + +--- + NEWS | 3 ++ + src/pch.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/pch.h | 1 + + src/util.c | 7 +++++++ + tests/symlinks | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 117 insertions(+) + +diff --git a/NEWS b/NEWS +index 42afed7..d3f1c2d 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,3 +1,6 @@ ++* With git-style patches, symlinks that point outside the working directory ++ will no longer be created. ++ + Changes in version 2.7.1: + + * Two critical bug fixes in the "diff --git" format support. +diff --git a/src/pch.c b/src/pch.c +index 55e1504..f05ef83 100644 +--- a/src/pch.c ++++ b/src/pch.c +@@ -454,6 +454,60 @@ name_is_valid (char const *name) + return is_valid; + } + ++bool ++symlink_target_is_valid (char const *target, char const *to) ++{ ++ bool is_valid; ++ ++ if (IS_ABSOLUTE_FILE_NAME (to)) ++ is_valid = true; ++ else if (IS_ABSOLUTE_FILE_NAME (target)) ++ is_valid = false; ++ else ++ { ++ unsigned int depth = 0; ++ char const *t; ++ ++ is_valid = true; ++ t = to; ++ while (*t) ++ { ++ while (*t && ! ISSLASH (*t)) ++ t++; ++ if (ISSLASH (*t)) ++ { ++ while (ISSLASH (*t)) ++ t++; ++ depth++; ++ } ++ } ++ ++ t = target; ++ while (*t) ++ { ++ if (*t == '.' && *++t == '.' && (! *++t || ISSLASH (*t))) ++ { ++ if (! depth--) ++ { ++ is_valid = false; ++ break; ++ } ++ } ++ else ++ { ++ while (*t && ! ISSLASH (*t)) ++ t++; ++ depth++; ++ } ++ while (ISSLASH (*t)) ++ t++; ++ } ++ } ++ ++ /* Allow any symlink target if we are in the filesystem root. */ ++ return is_valid || cwd_is_root (to); ++} ++ + /* Determine what kind of diff is in the remaining part of the patch file. */ + + static enum diff +diff --git a/src/pch.h b/src/pch.h +index 0c7ff62..58861b0 100644 +--- a/src/pch.h ++++ b/src/pch.h +@@ -37,6 +37,7 @@ bool pch_write_line (lin, FILE *); + bool there_is_another_patch (bool, mode_t *); + char *pfetch (lin) _GL_ATTRIBUTE_PURE; + char pch_char (lin) _GL_ATTRIBUTE_PURE; ++bool symlink_target_is_valid (char const *, char const *); + int another_hunk (enum diff, bool); + int pch_says_nonexistent (bool) _GL_ATTRIBUTE_PURE; + size_t pch_line_len (lin) _GL_ATTRIBUTE_PURE; +diff --git a/src/util.c b/src/util.c +index 66ae90f..636eded 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -470,6 +470,13 @@ move_file (char const *from, bool *from_needs_removal, + read_fatal (); + buffer[size] = 0; + ++ if (! symlink_target_is_valid (buffer, to)) ++ { ++ fprintf (stderr, "symbolic link target '%s' is invalid\n", ++ buffer); ++ fatal_exit (0); ++ } ++ + if (! backup) + { + if (unlink (to) == 0) +diff --git a/tests/symlinks b/tests/symlinks +index 96626b3..6211026 100644 +--- a/tests/symlinks ++++ b/tests/symlinks +@@ -146,6 +146,59 @@ ncheck 'test ! -L symlink' + + # -------------------------------------------------------------- + ++# Patch should not create symlinks which point outside the working directory. ++ ++cat > symlink-target.diff < bad-symlink-target1.diff < bad-symlink-target2.diff <