diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-02-02 10:40:16 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-02-02 10:41:18 +0000 |
commit | 5ac69ea49d71a514ca0d499827d11c4b5bb05d93 (patch) | |
tree | 86dfcfb4c9b461ab234bfb8f08361dcccd507bad /main/patch | |
parent | 2abdc2eb07801022e8314da1b96378364a1d83f9 (diff) | |
download | aports-5ac69ea49d71a514ca0d499827d11c4b5bb05d93.tar.bz2 aports-5ac69ea49d71a514ca0d499827d11c4b5bb05d93.tar.xz |
main/patch: security fix for CVE-2015-119
ref #3854
Diffstat (limited to 'main/patch')
-rw-r--r-- | main/patch/APKBUILD | 20 | ||||
-rw-r--r-- | main/patch/CVE-2015-119.patch | 175 |
2 files changed, 192 insertions, 3 deletions
diff --git a/main/patch/APKBUILD b/main/patch/APKBUILD index fa8f5e0478..bf00399d50 100644 --- a/main/patch/APKBUILD +++ b/main/patch/APKBUILD @@ -1,17 +1,26 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=patch pkgver=2.7.1 -pkgrel=0 +pkgrel=1 pkgdesc="Utility to apply diffs to files" url="http://www.gnu.org/software/patch/patch.html" arch="all" license='GPL' depends= -source="ftp://ftp.gnu.org/gnu/patch/patch-$pkgver.tar.bz2" +source="ftp://ftp.gnu.org/gnu/patch/patch-$pkgver.tar.bz2 + CVE-2015-119.patch" subpackages="$pkgname-doc" install= _builddir="$srcdir"/$pkgname-$pkgver +prepare() { + cd "$_builddir" + for i in $source; do + case $i in + *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;; + esac + done +} build() { cd "$_builddir" @@ -32,4 +41,9 @@ package() { return 0 } -md5sums="0881a7c6477862fc395f373ada0ec6b6 patch-2.7.1.tar.bz2" +md5sums="0881a7c6477862fc395f373ada0ec6b6 patch-2.7.1.tar.bz2 +614f3d2d3e9db815f0292c774b4e09ee CVE-2015-119.patch" +sha256sums="aae676de9e95051f425af4507fcc9a019941a2a1f78405e7dbd40bccf786aa11 patch-2.7.1.tar.bz2 +894e3ef9f731384e26164222b340bc87ada0a61fd7ed8d5d2a63f548c8153fba CVE-2015-119.patch" +sha512sums="b9411f1d7bb55151e6fa3b44bbbb73e025be8e87fad73b0c39b27d9b6467c7633c17fe772f6727c2be8779706d612ddb29ba6f94ed7c3d43e8327372940a9d03 patch-2.7.1.tar.bz2 +3654605a9b52520ca3fa4ee22969a38e480937aa579c53974c50ed08877dde0d8c870e5d5765aaf430537b94c62a0304f4e9d4c78b82e87e6e09161d5411fd87 CVE-2015-119.patch" diff --git a/main/patch/CVE-2015-119.patch b/main/patch/CVE-2015-119.patch new file mode 100644 index 0000000000..814c14364f --- /dev/null +++ b/main/patch/CVE-2015-119.patch @@ -0,0 +1,175 @@ +From 4e9269a5fc1fe80a1095a92593dd85db871e1fd3 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher <andreas.gruenbacher@gmail.com> +Date: Mon, 19 Jan 2015 22:18:30 +0000 +Subject: Make sure symlinks don't point outside working directory (CVE-2015-119) + +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. +--- +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 +@@ -466,6 +466,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 <<EOF ++diff --git a/dir/foo b/dir/foo ++new file mode 120000 ++index 0000000..cad2309 ++--- /dev/null +++++ b/dir/foo ++@@ -0,0 +1 @@ +++../foo ++\ No newline at end of file ++EOF ++ ++check 'patch -p1 < symlink-target.diff || echo "Status: $?"' <<EOF ++patching symbolic link dir/foo ++EOF ++ ++cat > bad-symlink-target1.diff <<EOF ++diff --git a/bar b/bar ++new file mode 120000 ++index 0000000..cad2309 ++--- /dev/null +++++ b/bar ++@@ -0,0 +1 @@ +++/bar ++\ No newline at end of file ++EOF ++ ++check 'patch -p1 < bad-symlink-target1.diff || echo "Status: $?"' <<EOF ++patching symbolic link bar ++symbolic link target '/bar' is invalid ++Status: 2 ++EOF ++ ++cat > bad-symlink-target2.diff <<EOF ++diff --git a/baz b/baz ++new file mode 120000 ++index 0000000..cad2309 ++--- /dev/null +++++ b/baz ++@@ -0,0 +1 @@ +++../baz ++\ No newline at end of file ++EOF ++ ++check 'patch -p1 < bad-symlink-target2.diff || echo "Status: $?"' <<EOF ++patching symbolic link baz ++symbolic link target '../baz' is invalid ++Status: 2 ++EOF ++ ++# -------------------------------------------------------------- ++ + # The backup file of a new symlink is an empty regular file. + + check 'patch -p1 --backup < create-symlink.diff || echo "Status: $?"' <<EOF +-- +cgit v0.9.0.2 |