Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=frugalware-current.git;a=commitdiff;h=3feeacad0816963b05dbbfae96ffea876e98cc35
commit 3feeacad0816963b05dbbfae96ffea876e98cc35 Author: kikadf <[email protected]> Date: Wed Dec 10 09:58:52 2014 +0100 glibc-2.19-4-x86_64 * Fix CVE-2014-4043, CVE-2014-6040, CVE-2014-7817 diff --git a/source/base/glibc/CVE-2014-4043.patch b/source/base/glibc/CVE-2014-4043.patch new file mode 100644 index 0000000..dbbd433 --- /dev/null +++ b/source/base/glibc/CVE-2014-4043.patch @@ -0,0 +1,133 @@ +Description: fix use-after-free via posix_spawn_file_actions_addopen + failing to copy the path argument +Origin: backport, https://sourceware.org/git/?p=glibc.git;h=89e435f3559c53084498e9baad22172b64429362 +Origin: backport, https://sourceware.org/git/?p=glibc.git;h=35a5e3e338ae17f3d42c60a708763c5d498fb840 +Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17048 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=751774 + +Index: eglibc-2.19/posix/spawn_faction_addopen.c +=================================================================== +--- eglibc-2.19.orig/posix/spawn_faction_addopen.c 2014-01-03 12:51:28.000000000 -0500 ++++ eglibc-2.19/posix/spawn_faction_addopen.c 2014-07-25 08:52:06.166911382 -0400 +@@ -18,6 +18,7 @@ + #include <errno.h> + #include <spawn.h> + #include <unistd.h> ++#include <string.h> + + #include "spawn_int.h" + +@@ -35,17 +36,24 @@ + if (fd < 0 || fd >= maxfd) + return EBADF; + ++ char *path_copy = strdup (path); ++ if (path_copy == NULL) ++ return ENOMEM; ++ + /* Allocate more memory if needed. */ + if (file_actions->__used == file_actions->__allocated + && __posix_spawn_file_actions_realloc (file_actions) != 0) +- /* This can only mean we ran out of memory. */ +- return ENOMEM; ++ { ++ /* This can only mean we ran out of memory. */ ++ free (path_copy); ++ return ENOMEM; ++ } + + /* Add the new value. */ + rec = &file_actions->__actions[file_actions->__used]; + rec->tag = spawn_do_open; + rec->action.open_action.fd = fd; +- rec->action.open_action.path = path; ++ rec->action.open_action.path = path_copy; + rec->action.open_action.oflag = oflag; + rec->action.open_action.mode = mode; + +Index: eglibc-2.19/posix/spawn_faction_destroy.c +=================================================================== +--- eglibc-2.19.orig/posix/spawn_faction_destroy.c 2014-01-03 12:51:28.000000000 -0500 ++++ eglibc-2.19/posix/spawn_faction_destroy.c 2014-07-25 08:52:01.954911403 -0400 +@@ -18,11 +18,29 @@ + #include <spawn.h> + #include <stdlib.h> + +-/* Initialize data structure for file attribute for `spawn' call. */ ++#include "spawn_int.h" ++ ++/* Deallocate the file actions. */ + int + posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions) + { +- /* Free the memory allocated. */ ++ /* Free the paths in the open actions. */ ++ for (int i = 0; i < file_actions->__used; ++i) ++ { ++ struct __spawn_action *sa = &file_actions->__actions[i]; ++ switch (sa->tag) ++ { ++ case spawn_do_open: ++ free (sa->action.open_action.path); ++ break; ++ case spawn_do_close: ++ case spawn_do_dup2: ++ /* No cleanup required. */ ++ break; ++ } ++ } ++ ++ /* Free the array of actions. */ + free (file_actions->__actions); + return 0; + } +Index: eglibc-2.19/posix/spawn_int.h +=================================================================== +--- eglibc-2.19.orig/posix/spawn_int.h 2011-09-06 11:08:18.000000000 -0400 ++++ eglibc-2.19/posix/spawn_int.h 2014-07-25 08:52:01.954911403 -0400 +@@ -22,7 +22,7 @@ + struct + { + int fd; +- const char *path; ++ char *path; + int oflag; + mode_t mode; + } open_action; +Index: eglibc-2.19/posix/tst-spawn.c +=================================================================== +--- eglibc-2.19.orig/posix/tst-spawn.c 2014-01-03 12:51:28.000000000 -0500 ++++ eglibc-2.19/posix/tst-spawn.c 2014-07-25 08:52:01.954911403 -0400 +@@ -168,6 +168,7 @@ + char fd2name[18]; + char fd3name[18]; + char fd4name[18]; ++ char *name3_copy; + char *spargv[12]; + int i; + +@@ -222,9 +223,15 @@ + if (posix_spawn_file_actions_addclose (&actions, fd1) != 0) + error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose"); + /* We want to open the third file. */ +- if (posix_spawn_file_actions_addopen (&actions, fd3, name3, ++ name3_copy = strdup (name3); ++ if (name3_copy == NULL) ++ error (EXIT_FAILURE, errno, "strdup"); ++ if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy, + O_RDONLY, 0666) != 0) + error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen"); ++ /* Overwrite the name to check that a copy has been made. */ ++ memset (name3_copy, 'X', strlen (name3_copy)); ++ + /* We dup the second descriptor. */ + fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1; + if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0) +@@ -253,6 +260,7 @@ + /* Cleanup. */ + if (posix_spawn_file_actions_destroy (&actions) != 0) + error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy"); ++ free (name3_copy); + + /* Wait for the child. */ + if (waitpid (pid, &status, 0) != pid) diff --git a/source/base/glibc/CVE-2014-6040.patch b/source/base/glibc/CVE-2014-6040.patch new file mode 100644 index 0000000..79cfd64 --- /dev/null +++ b/source/base/glibc/CVE-2014-6040.patch @@ -0,0 +1,117 @@ +2014-09-03 Florian Weimer <[email protected]> + + [BZ #17325] + * iconvdata/ibm1364.c (BODY): Fix check for sentinel. + * iconvdata/ibm932.c (BODY): Replace invalid sentinel check with + assert. + * iconvdata/ibm933.c (BODY): Fix check for sentinel. + * iconvdata/ibm935.c (BODY): Likewise. + * iconvdata/ibm937.c (BODY): Likewise. + * iconvdata/ibm939.c (BODY): Likewise. + * iconvdata/ibm943.c (BODY): Replace invalid sentinel check with + assert. + +Index: glibc-2.19/iconvdata/ibm1364.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm1364.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm1364.c 2014-11-28 10:46:39.041255818 -0500 +@@ -220,7 +220,8 @@ + ++rp2; \ + \ + uint32_t res; \ +- if (__builtin_expect (ch < rp2->start, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ ++ || __builtin_expect (ch < rp2->start, 0) \ + || (res = DB_TO_UCS4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ + { \ +Index: glibc-2.19/iconvdata/ibm932.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm932.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm932.c 2014-11-28 10:46:39.041255818 -0500 +@@ -73,11 +73,12 @@ + } \ + \ + ch = (ch * 0x100) + inptr[1]; \ ++ /* ch was less than 0xfd. */ \ ++ assert (ch < 0xfd00); \ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ +- || __builtin_expect (ch < rp2->start, 0) \ ++ if (__builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm932db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, '\1') == 0 && ch !=0)) \ + { \ +Index: glibc-2.19/iconvdata/ibm933.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm933.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm933.c 2014-11-28 10:46:39.041255818 -0500 +@@ -161,7 +161,7 @@ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm933db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +Index: glibc-2.19/iconvdata/ibm935.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm935.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm935.c 2014-11-28 10:46:39.041255818 -0500 +@@ -161,7 +161,7 @@ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm935db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +Index: glibc-2.19/iconvdata/ibm937.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm937.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm937.c 2014-11-28 10:46:39.041255818 -0500 +@@ -161,7 +161,7 @@ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm937db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +Index: glibc-2.19/iconvdata/ibm939.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm939.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm939.c 2014-11-28 10:46:39.041255818 -0500 +@@ -161,7 +161,7 @@ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm939db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +Index: glibc-2.19/iconvdata/ibm943.c +=================================================================== +--- glibc-2.19.orig/iconvdata/ibm943.c 2014-11-28 10:46:39.045255850 -0500 ++++ glibc-2.19/iconvdata/ibm943.c 2014-11-28 10:46:39.041255818 -0500 +@@ -74,11 +74,12 @@ + } \ + \ + ch = (ch * 0x100) + inptr[1]; \ ++ /* ch was less than 0xfd. */ \ ++ assert (ch < 0xfd00); \ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ +- || __builtin_expect (ch < rp2->start, 0) \ ++ if (__builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm943db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, '\1') == 0 && ch !=0)) \ + { \ diff --git a/source/base/glibc/CVE-2014-7817.patch b/source/base/glibc/CVE-2014-7817.patch new file mode 100644 index 0000000..cfa9911 --- /dev/null +++ b/source/base/glibc/CVE-2014-7817.patch @@ -0,0 +1,172 @@ +From 33ceaf6187b31ea15284ac65131749e1cb68d2ae Mon Sep 17 00:00:00 2001 +From: Carlos O'Donell <[email protected]> +Date: Wed, 19 Nov 2014 11:44:12 -0500 +Subject: [PATCH] CVE-2014-7817: wordexp fails to honour WRDE_NOCMD. + +The function wordexp() fails to properly handle the WRDE_NOCMD +flag when processing arithmetic inputs in the form of "$((... ``))" +where "..." can be anything valid. The backticks in the arithmetic +epxression are evaluated by in a shell even if WRDE_NOCMD forbade +command substitution. This allows an attacker to attempt to pass +dangerous commands via constructs of the above form, and bypass +the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD +in exec_comm(), the only place that can execute a shell. All other +checks for WRDE_NOCMD are superfluous and removed. + +We expand the testsuite and add 3 new regression tests of roughly +the same form but with a couple of nested levels. + +On top of the 3 new tests we add fork validation to the WRDE_NOCMD +testing. If any forks are detected during the execution of a wordexp() +call with WRDE_NOCMD, the test is marked as failed. This is slightly +heuristic since vfork might be used in the future, but it provides a +higher level of assurance that no shells were executed as part of +command substitution with WRDE_NOCMD in effect. In addition it doesn't +require libpthread or libdl, instead we use the public implementation +namespace function __register_atfork (already part of the public ABI +for libpthread). + +Tested on x86_64 with no regressions. + +(cherry picked from commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c) +--- + ChangeLog | 22 ++++++++++++++++++++++ + NEWS | 9 ++++++++- + posix/wordexp-test.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + posix/wordexp.c | 16 ++++------------ + 4 files changed, 78 insertions(+), 13 deletions(-) + +diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c +index 4957006..bdd65e4 100644 +--- a/posix/wordexp-test.c ++++ b/posix/wordexp-test.c +@@ -27,6 +27,25 @@ + + #define IFS " \n\t" + ++extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden"))); ++extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *); ++ ++static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void)) ++{ ++ return __register_atfork (prepare, parent, child, ++ &__dso_handle == NULL ? NULL : __dso_handle); ++} ++ ++/* Number of forks seen. */ ++static int registered_forks; ++ ++/* For each fork increment the fork count. */ ++static void ++register_fork (void) ++{ ++ registered_forks++; ++} ++ + struct test_case_struct + { + int retval; +@@ -206,6 +225,12 @@ struct test_case_struct + { WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS }, + { WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS }, + { WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS }, ++ /* Test for CVE-2014-7817. We test 3 combinations of command ++ substitution inside an arithmetic expression to make sure that ++ no commands are executed and error is returned. */ ++ { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS }, ++ { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS }, ++ { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS }, + + { -1, NULL, NULL, 0, 0, { NULL, }, IFS }, + }; +@@ -258,6 +283,15 @@ main (int argc, char *argv[]) + return -1; + } + ++ /* If we are not allowed to do command substitution, we install ++ fork handlers to verify that no forks happened. No forks should ++ happen at all if command substitution is disabled. */ ++ if (__app_register_atfork (register_fork, NULL, NULL) != 0) ++ { ++ printf ("Failed to register fork handler.\n"); ++ return -1; ++ } ++ + for (test = 0; test_case[test].retval != -1; test++) + if (testit (&test_case[test])) + ++fail; +@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc) + + printf ("Test %d (%s): ", ++tests, tc->words); + ++ if (tc->flags & WRDE_NOCMD) ++ registered_forks = 0; ++ + if (tc->flags & WRDE_APPEND) + { + /* initial wordexp() call, to be appended to */ +@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc) + } + retval = wordexp (tc->words, &we, tc->flags); + ++ if ((tc->flags & WRDE_NOCMD) ++ && (registered_forks > 0)) ++ { ++ printf ("FAILED fork called for WRDE_NOCMD\n"); ++ return 1; ++ } ++ + if (tc->flags & WRDE_DOOFFS) + start_offs = sav_we.we_offs; + +diff --git a/posix/wordexp.c b/posix/wordexp.c +index b6b65dd..26f3a26 100644 +--- a/posix/wordexp.c ++++ b/posix/wordexp.c +@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length, + pid_t pid; + int noexec = 0; + ++ /* Do nothing if command substitution should not succeed. */ ++ if (flags & WRDE_NOCMD) ++ return WRDE_CMDSUB; ++ + /* Don't fork() unless necessary */ + if (!comm || !*comm) + return 0; +@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length, + } + } + +- if (flags & WRDE_NOCMD) +- return WRDE_CMDSUB; +- + (*offset) += 2; + return parse_comm (word, word_length, max_length, words, offset, flags, + quoted? NULL : pwordexp, ifs, ifs_white); +@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length, + break; + + case '`': +- if (flags & WRDE_NOCMD) +- return WRDE_CMDSUB; +- + ++(*offset); + error = parse_backtick (word, word_length, max_length, words, + offset, flags, NULL, NULL, NULL); +@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags) + break; + + case '`': +- if (flags & WRDE_NOCMD) +- { +- error = WRDE_CMDSUB; +- goto do_error; +- } +- + ++words_offset; + error = parse_backtick (&word, &word_length, &max_length, words, + &words_offset, flags, pwordexp, ifs, +-- +1.7.1 + diff --git a/source/base/glibc/FrugalBuild b/source/base/glibc/FrugalBuild index 978a40e..a324040 100644 --- a/source/base/glibc/FrugalBuild +++ b/source/base/glibc/FrugalBuild @@ -4,7 +4,7 @@ pkgname=glibc pkgver=2.19 -pkgrel=3 +pkgrel=4 pkgdesc="GNU C Library" url="http://www.gnu.org/software/libc/libc.html" depends=() @@ -20,8 +20,9 @@ source=($_dlurl/glibc-$pkgver.tar.xz) signatures=($_dlurl/glibc-$pkgver.tar.xz.sig) # FSA fix *** -source=(${source[@]} CVE-2014-0475.patch CVE-2014-5119.patch) -signatures=(${signatures[@]} '' '') +source=(${source[@]} CVE-2014-0475.patch CVE-2014-5119.patch CVE-2014-4043.patch + CVE-2014-6040.patch CVE-2014-7817.patch) +signatures=(${signatures[@]} '' '' '' '' '') # *********** _______________________________________________ Frugalware-git mailing list [email protected] http://frugalware.org/mailman/listinfo/frugalware-git
