Update buidlroot to version 2016.08.1
This commit is contained in:
@@ -1,174 +0,0 @@
|
||||
From https://bugzilla.redhat.com/show_bug.cgi?id=1157689
|
||||
Modified for eglibc.
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
|
||||
EMBARGOED !!! EMBARGOED !!! EMARGOED !!! EMBARGOED !!! EMBARGOED !!!
|
||||
SECURITY !!! SECURITY !!! SECURITY !!! SECURITY !!! SECURITY !!!
|
||||
|
||||
CVE-2014-7817:
|
||||
|
||||
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 parse_arith(). The patch also hardens parse_backticks() and
|
||||
parse_comm() to check for WRDE_NOCMD flag and return an error instead
|
||||
of ever running a shell.
|
||||
|
||||
We expand the testsuite and add 3 new regression tests of roughtly
|
||||
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, 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.
|
||||
|
||||
2014-10-27 Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
* wordexp-test.c (__dso_handle): Add prototype.
|
||||
(__register_atfork): Likewise.
|
||||
(__app_register_atfork): New function.
|
||||
(registered_forks): New global.
|
||||
(register_fork): New function.
|
||||
(test_case): Add 3 new tests for WRDE_CMDSUB.
|
||||
(main): Call __app_register_atfork.
|
||||
(testit): If WRDE_NOCMD set registered_forks to zero, run test, and
|
||||
if fork count is non-zero fail the test.
|
||||
* posix/wordexp.c (parse_arith): Return WRDE_NOCMD if WRDE_NOCMD flag
|
||||
is set and parsing '`'.
|
||||
(parse_comm): Return WRDE_NOCMD if WRDE_NOCMD flag is set.
|
||||
(parse_backtick): Return WRDE_NOCMD if WRDE_NOCMD flag is set and
|
||||
parsing '`'.
|
||||
|
||||
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
|
||||
index 4957006..5ce2a1b 100644
|
||||
--- a/libc/posix/wordexp-test.c
|
||||
+++ b/libc/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..d6a158f 100644
|
||||
--- a/libc/posix/wordexp.c
|
||||
+++ b/libc/posix/wordexp.c
|
||||
@@ -693,6 +693,12 @@ parse_arith (char **word, size_t *word_length, size_t *max_length,
|
||||
break;
|
||||
|
||||
case '`':
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ {
|
||||
+ free (expr);
|
||||
+ return WRDE_NOCMD;
|
||||
+ }
|
||||
+
|
||||
(*offset)++;
|
||||
error = parse_backtick (&expr, &expr_length, &expr_maxlen,
|
||||
words, offset, flags, NULL, NULL, NULL);
|
||||
@@ -1144,6 +1150,10 @@ parse_comm (char **word, size_t *word_length, size_t *max_length,
|
||||
size_t comm_maxlen;
|
||||
char *comm = w_newword (&comm_length, &comm_maxlen);
|
||||
|
||||
+ /* Do nothing if command substitution should not succeed. */
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ return WRDE_CMDSUB;
|
||||
+
|
||||
for (; words[*offset]; ++(*offset))
|
||||
{
|
||||
switch (words[*offset])
|
||||
@@ -2121,6 +2131,9 @@ parse_backtick (char **word, size_t *word_length, size_t *max_length,
|
||||
switch (words[*offset])
|
||||
{
|
||||
case '`':
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ return WRDE_NOCMD;
|
||||
+
|
||||
/* Go -- give the script to the shell */
|
||||
error = exec_comm (comm, word, word_length, max_length, flags,
|
||||
pwordexp, ifs, ifs_white);
|
||||
@@ -1,33 +0,0 @@
|
||||
Backport upstream patch (28d708c44bc47b56f6551ff285f78edcf61c208a) to accept
|
||||
make-4.0 or newer.
|
||||
We patch both configure and configure.in files so if we ever have to run
|
||||
autoreconf in the glibc source, then the fix will be propagated properly.
|
||||
|
||||
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
|
||||
|
||||
Index: glibc-2.18-svnr23787/libc/configure
|
||||
===================================================================
|
||||
--- glibc-2.18-svnr23787.orig/libc/configure
|
||||
+++ glibc-2.18-svnr23787/libc/configure
|
||||
@@ -4772,7 +4772,7 @@ $as_echo_n "checking version of $MAKE...
|
||||
ac_prog_version=`$MAKE --version 2>&1 | sed -n 's/^.*GNU Make[^0-9]*\([0-9][0-9.]*\).*$/\1/p'`
|
||||
case $ac_prog_version in
|
||||
'') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
|
||||
- 3.79* | 3.[89]*)
|
||||
+ 3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*)
|
||||
ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
|
||||
*) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
|
||||
|
||||
Index: glibc-2.18-svnr23787/libc/configure.in
|
||||
===================================================================
|
||||
--- glibc-2.18-svnr23787.orig/libc/configure.in
|
||||
+++ glibc-2.18-svnr23787/libc/configure.in
|
||||
@@ -989,7 +989,7 @@ AC_CHECK_PROG_VER(CC, ${ac_tool_prefix}g
|
||||
critic_missing="$critic_missing gcc")
|
||||
AC_CHECK_PROG_VER(MAKE, gnumake gmake make, --version,
|
||||
[GNU Make[^0-9]*\([0-9][0-9.]*\)],
|
||||
- [3.79* | 3.[89]*], critic_missing="$critic_missing make")
|
||||
+ [3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make")
|
||||
|
||||
AC_CHECK_PROG_VER(MSGFMT, gnumsgfmt gmsgfmt msgfmt, --version,
|
||||
[GNU gettext.* \([0-9]*\.[0-9.]*\)],
|
||||
@@ -1,141 +0,0 @@
|
||||
Backport from https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=41488498b6
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=1135841
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm1364.c eglibc-2.19/libc/iconvdata/ibm1364.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm1364.c 2015-01-08 16:05:53.918823240 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm1364.c 2015-01-08 16:06:02.781555143 -0300
|
||||
@@ -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')) \
|
||||
{ \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm932.c eglibc-2.19/libc/iconvdata/ibm932.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm932.c 2015-01-08 16:05:53.910818967 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm932.c 2015-01-08 16:06:02.781555143 -0300
|
||||
@@ -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)) \
|
||||
{ \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm933.c eglibc-2.19/libc/iconvdata/ibm933.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm933.c 2015-01-08 16:05:53.917822706 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm933.c 2015-01-08 16:06:02.781555143 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm935.c eglibc-2.19/libc/iconvdata/ibm935.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm935.c 2015-01-08 16:05:53.921824843 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm935.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm937.c eglibc-2.19/libc/iconvdata/ibm937.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm937.c 2015-01-08 16:05:53.915821638 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm937.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm939.c eglibc-2.19/libc/iconvdata/ibm939.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm939.c 2015-01-08 16:05:53.917822706 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm939.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm943.c eglibc-2.19/libc/iconvdata/ibm943.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm943.c 2015-01-08 16:05:53.918823240 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm943.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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 -Nura eglibc-2.19.orig/libc/iconvdata/Makefile eglibc-2.19/libc/iconvdata/Makefile
|
||||
--- eglibc-2.19.orig/libc/iconvdata/Makefile 2015-01-08 16:05:53.903815227 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/Makefile 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -303,6 +303,7 @@
|
||||
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
|
||||
$(addprefix $(objpfx),$(modules.so)) \
|
||||
$(common-objdir)/iconv/iconv_prog TESTS
|
||||
+ iconv_modules="$(modules)" \
|
||||
$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
|
||||
|
||||
$(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/run-iconv-test.sh eglibc-2.19/libc/iconvdata/run-iconv-test.sh
|
||||
--- eglibc-2.19.orig/libc/iconvdata/run-iconv-test.sh 2015-01-08 16:05:53.894810420 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/run-iconv-test.sh 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -188,6 +188,24 @@
|
||||
|
||||
done < TESTS2
|
||||
|
||||
+# Check for crashes in decoders.
|
||||
+printf '\016\377\377\377\377\377\377\377' > $temp1
|
||||
+for from in $iconv_modules ; do
|
||||
+ echo $ac_n "test decoder $from $ac_c"
|
||||
+ PROG=`eval echo $ICONV`
|
||||
+ if $PROG < $temp1 >/dev/null 2>&1 ; then
|
||||
+ : # fall through
|
||||
+ else
|
||||
+ status=$?
|
||||
+ if test $status -gt 1 ; then
|
||||
+ echo "/FAILED"
|
||||
+ failed=1
|
||||
+ continue
|
||||
+ fi
|
||||
+ fi
|
||||
+ echo "OK"
|
||||
+done
|
||||
+
|
||||
exit $failed
|
||||
# Local Variables:
|
||||
# mode:shell-script
|
||||
@@ -1,20 +0,0 @@
|
||||
Fix CVE-2014-9402 - denial of service in getnetbyname function.
|
||||
Backport from https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=11e3417af6e354f1942c68a271ae51e892b2814d
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=1175369
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
diff -Nura eglibc-2.19.orig/libc/resolv/nss_dns/dns-network.c eglibc-2.19/libc/resolv/nss_dns/dns-network.c
|
||||
--- eglibc-2.19.orig/libc/resolv/nss_dns/dns-network.c 2015-01-08 16:12:35.024977879 -0300
|
||||
+++ eglibc-2.19/libc/resolv/nss_dns/dns-network.c 2015-01-08 16:12:42.543992357 -0300
|
||||
@@ -398,8 +398,8 @@
|
||||
|
||||
case BYNAME:
|
||||
{
|
||||
- char **ap = result->n_aliases++;
|
||||
- while (*ap != NULL)
|
||||
+ char **ap;
|
||||
+ for (ap = result->n_aliases; *ap != NULL; ++ap)
|
||||
{
|
||||
/* Check each alias name for being of the forms:
|
||||
4.3.2.1.in-addr.arpa = net 1.2.3.4
|
||||
@@ -1,88 +0,0 @@
|
||||
Fix CVE-2015-1472 - heap buffer overflow in wscanf
|
||||
Backport from upstream:
|
||||
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=5bd80bfe9ca0d955bfbbc002781bc7b01b6bcb06
|
||||
See: https://bugzilla.redhat.com/show_bug.cgi?id=1188235
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
diff --git a/stdio-common/tst-sscanf.c b/stdio-common/tst-sscanf.c
|
||||
index aece3f2..8a2eb9e 100644
|
||||
--- a/libc/stdio-common/tst-sscanf.c
|
||||
+++ b/libc/stdio-common/tst-sscanf.c
|
||||
@@ -233,5 +233,38 @@ main (void)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* BZ #16618
|
||||
+ The test will segfault during SSCANF if the buffer overflow
|
||||
+ is not fixed. The size of `s` is such that it forces the use
|
||||
+ of malloc internally and this triggers the incorrect computation.
|
||||
+ Thus the value for SIZE is arbitrariy high enough that malloc
|
||||
+ is used. */
|
||||
+ {
|
||||
+#define SIZE 131072
|
||||
+ CHAR *s = malloc ((SIZE + 1) * sizeof (*s));
|
||||
+ if (s == NULL)
|
||||
+ abort ();
|
||||
+ for (size_t i = 0; i < SIZE; i++)
|
||||
+ s[i] = L('0');
|
||||
+ s[SIZE] = L('\0');
|
||||
+ int i = 42;
|
||||
+ /* Scan multi-digit zero into `i`. */
|
||||
+ if (SSCANF (s, L("%d"), &i) != 1)
|
||||
+ {
|
||||
+ printf ("FAIL: bug16618: SSCANF did not read one input item.\n");
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ if (i != 0)
|
||||
+ {
|
||||
+ printf ("FAIL: bug16618: Value of `i` was not zero as expected.\n");
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ free (s);
|
||||
+ if (result != 1)
|
||||
+ printf ("PASS: bug16618: Did not crash.\n");
|
||||
+#undef SIZE
|
||||
+ }
|
||||
+
|
||||
+
|
||||
return result;
|
||||
}
|
||||
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
|
||||
index cd129a8..0e204e7 100644
|
||||
--- a/libc/stdio-common/vfscanf.c
|
||||
+++ b/libc/stdio-common/vfscanf.c
|
||||
@@ -272,9 +272,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (__glibc_unlikely (wpsize == wpmax)) \
|
||||
{ \
|
||||
CHAR_T *old = wp; \
|
||||
- size_t newsize = (UCHAR_MAX + 1 > 2 * wpmax \
|
||||
- ? UCHAR_MAX + 1 : 2 * wpmax); \
|
||||
- if (use_malloc || !__libc_use_alloca (newsize)) \
|
||||
+ bool fits = __glibc_likely (wpmax <= SIZE_MAX / sizeof (CHAR_T) / 2); \
|
||||
+ size_t wpneed = MAX (UCHAR_MAX + 1, 2 * wpmax); \
|
||||
+ size_t newsize = fits ? wpneed * sizeof (CHAR_T) : SIZE_MAX; \
|
||||
+ if (!__libc_use_alloca (newsize)) \
|
||||
{ \
|
||||
wp = realloc (use_malloc ? wp : NULL, newsize); \
|
||||
if (wp == NULL) \
|
||||
@@ -286,14 +287,13 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
} \
|
||||
if (! use_malloc) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
- wpmax = newsize; \
|
||||
+ wpmax = wpneed; \
|
||||
use_malloc = true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
size_t s = wpmax * sizeof (CHAR_T); \
|
||||
- wp = (CHAR_T *) extend_alloca (wp, s, \
|
||||
- newsize * sizeof (CHAR_T)); \
|
||||
+ wp = (CHAR_T *) extend_alloca (wp, s, newsize); \
|
||||
wpmax = s / sizeof (CHAR_T); \
|
||||
if (old != NULL) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
--
|
||||
1.9.4
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
From https://bugzilla.redhat.com/show_bug.cgi?id=1157689
|
||||
Modified for eglibc.
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!
|
||||
EMBARGOED !!! EMBARGOED !!! EMARGOED !!! EMBARGOED !!! EMBARGOED !!!
|
||||
SECURITY !!! SECURITY !!! SECURITY !!! SECURITY !!! SECURITY !!!
|
||||
|
||||
CVE-2014-7817:
|
||||
|
||||
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 parse_arith(). The patch also hardens parse_backticks() and
|
||||
parse_comm() to check for WRDE_NOCMD flag and return an error instead
|
||||
of ever running a shell.
|
||||
|
||||
We expand the testsuite and add 3 new regression tests of roughtly
|
||||
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, 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.
|
||||
|
||||
2014-10-27 Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
* wordexp-test.c (__dso_handle): Add prototype.
|
||||
(__register_atfork): Likewise.
|
||||
(__app_register_atfork): New function.
|
||||
(registered_forks): New global.
|
||||
(register_fork): New function.
|
||||
(test_case): Add 3 new tests for WRDE_CMDSUB.
|
||||
(main): Call __app_register_atfork.
|
||||
(testit): If WRDE_NOCMD set registered_forks to zero, run test, and
|
||||
if fork count is non-zero fail the test.
|
||||
* posix/wordexp.c (parse_arith): Return WRDE_NOCMD if WRDE_NOCMD flag
|
||||
is set and parsing '`'.
|
||||
(parse_comm): Return WRDE_NOCMD if WRDE_NOCMD flag is set.
|
||||
(parse_backtick): Return WRDE_NOCMD if WRDE_NOCMD flag is set and
|
||||
parsing '`'.
|
||||
|
||||
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
|
||||
index 4957006..5ce2a1b 100644
|
||||
--- a/libc/posix/wordexp-test.c
|
||||
+++ b/libc/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..d6a158f 100644
|
||||
--- a/libc/posix/wordexp.c
|
||||
+++ b/libc/posix/wordexp.c
|
||||
@@ -693,6 +693,12 @@ parse_arith (char **word, size_t *word_length, size_t *max_length,
|
||||
break;
|
||||
|
||||
case '`':
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ {
|
||||
+ free (expr);
|
||||
+ return WRDE_NOCMD;
|
||||
+ }
|
||||
+
|
||||
(*offset)++;
|
||||
error = parse_backtick (&expr, &expr_length, &expr_maxlen,
|
||||
words, offset, flags, NULL, NULL, NULL);
|
||||
@@ -1144,6 +1150,10 @@ parse_comm (char **word, size_t *word_length, size_t *max_length,
|
||||
size_t comm_maxlen;
|
||||
char *comm = w_newword (&comm_length, &comm_maxlen);
|
||||
|
||||
+ /* Do nothing if command substitution should not succeed. */
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ return WRDE_CMDSUB;
|
||||
+
|
||||
for (; words[*offset]; ++(*offset))
|
||||
{
|
||||
switch (words[*offset])
|
||||
@@ -2121,6 +2131,9 @@ parse_backtick (char **word, size_t *word_length, size_t *max_length,
|
||||
switch (words[*offset])
|
||||
{
|
||||
case '`':
|
||||
+ if (flags & WRDE_NOCMD)
|
||||
+ return WRDE_NOCMD;
|
||||
+
|
||||
/* Go -- give the script to the shell */
|
||||
error = exec_comm (comm, word, word_length, max_length, flags,
|
||||
pwordexp, ifs, ifs_white);
|
||||
@@ -1,141 +0,0 @@
|
||||
Backport from https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commit;h=41488498b6
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=1135841
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm1364.c eglibc-2.19/libc/iconvdata/ibm1364.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm1364.c 2015-01-08 16:05:53.918823240 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm1364.c 2015-01-08 16:06:02.781555143 -0300
|
||||
@@ -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')) \
|
||||
{ \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm932.c eglibc-2.19/libc/iconvdata/ibm932.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm932.c 2015-01-08 16:05:53.910818967 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm932.c 2015-01-08 16:06:02.781555143 -0300
|
||||
@@ -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)) \
|
||||
{ \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm933.c eglibc-2.19/libc/iconvdata/ibm933.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm933.c 2015-01-08 16:05:53.917822706 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm933.c 2015-01-08 16:06:02.781555143 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm935.c eglibc-2.19/libc/iconvdata/ibm935.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm935.c 2015-01-08 16:05:53.921824843 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm935.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm937.c eglibc-2.19/libc/iconvdata/ibm937.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm937.c 2015-01-08 16:05:53.915821638 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm937.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm939.c eglibc-2.19/libc/iconvdata/ibm939.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm939.c 2015-01-08 16:05:53.917822706 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm939.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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')) \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/ibm943.c eglibc-2.19/libc/iconvdata/ibm943.c
|
||||
--- eglibc-2.19.orig/libc/iconvdata/ibm943.c 2015-01-08 16:05:53.918823240 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/ibm943.c 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -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 -Nura eglibc-2.19.orig/libc/iconvdata/Makefile eglibc-2.19/libc/iconvdata/Makefile
|
||||
--- eglibc-2.19.orig/libc/iconvdata/Makefile 2015-01-08 16:05:53.903815227 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/Makefile 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -303,6 +303,7 @@
|
||||
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
|
||||
$(addprefix $(objpfx),$(modules.so)) \
|
||||
$(common-objdir)/iconv/iconv_prog TESTS
|
||||
+ iconv_modules="$(modules)" \
|
||||
$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
|
||||
|
||||
$(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
|
||||
diff -Nura eglibc-2.19.orig/libc/iconvdata/run-iconv-test.sh eglibc-2.19/libc/iconvdata/run-iconv-test.sh
|
||||
--- eglibc-2.19.orig/libc/iconvdata/run-iconv-test.sh 2015-01-08 16:05:53.894810420 -0300
|
||||
+++ eglibc-2.19/libc/iconvdata/run-iconv-test.sh 2015-01-08 16:06:02.782555677 -0300
|
||||
@@ -188,6 +188,24 @@
|
||||
|
||||
done < TESTS2
|
||||
|
||||
+# Check for crashes in decoders.
|
||||
+printf '\016\377\377\377\377\377\377\377' > $temp1
|
||||
+for from in $iconv_modules ; do
|
||||
+ echo $ac_n "test decoder $from $ac_c"
|
||||
+ PROG=`eval echo $ICONV`
|
||||
+ if $PROG < $temp1 >/dev/null 2>&1 ; then
|
||||
+ : # fall through
|
||||
+ else
|
||||
+ status=$?
|
||||
+ if test $status -gt 1 ; then
|
||||
+ echo "/FAILED"
|
||||
+ failed=1
|
||||
+ continue
|
||||
+ fi
|
||||
+ fi
|
||||
+ echo "OK"
|
||||
+done
|
||||
+
|
||||
exit $failed
|
||||
# Local Variables:
|
||||
# mode:shell-script
|
||||
@@ -1,20 +0,0 @@
|
||||
Fix CVE-2014-9402 - denial of service in getnetbyname function.
|
||||
Backport from https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=11e3417af6e354f1942c68a271ae51e892b2814d
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=1175369
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
diff -Nura eglibc-2.19.orig/libc/resolv/nss_dns/dns-network.c eglibc-2.19/libc/resolv/nss_dns/dns-network.c
|
||||
--- eglibc-2.19.orig/libc/resolv/nss_dns/dns-network.c 2015-01-08 16:12:35.024977879 -0300
|
||||
+++ eglibc-2.19/libc/resolv/nss_dns/dns-network.c 2015-01-08 16:12:42.543992357 -0300
|
||||
@@ -398,8 +398,8 @@
|
||||
|
||||
case BYNAME:
|
||||
{
|
||||
- char **ap = result->n_aliases++;
|
||||
- while (*ap != NULL)
|
||||
+ char **ap;
|
||||
+ for (ap = result->n_aliases; *ap != NULL; ++ap)
|
||||
{
|
||||
/* Check each alias name for being of the forms:
|
||||
4.3.2.1.in-addr.arpa = net 1.2.3.4
|
||||
@@ -1,88 +0,0 @@
|
||||
Fix CVE-2015-1472 - heap buffer overflow in wscanf
|
||||
Backport from upstream:
|
||||
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=5bd80bfe9ca0d955bfbbc002781bc7b01b6bcb06
|
||||
See: https://bugzilla.redhat.com/show_bug.cgi?id=1188235
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
diff --git a/stdio-common/tst-sscanf.c b/stdio-common/tst-sscanf.c
|
||||
index aece3f2..8a2eb9e 100644
|
||||
--- a/libc/stdio-common/tst-sscanf.c
|
||||
+++ b/libc/stdio-common/tst-sscanf.c
|
||||
@@ -233,5 +233,38 @@ main (void)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* BZ #16618
|
||||
+ The test will segfault during SSCANF if the buffer overflow
|
||||
+ is not fixed. The size of `s` is such that it forces the use
|
||||
+ of malloc internally and this triggers the incorrect computation.
|
||||
+ Thus the value for SIZE is arbitrariy high enough that malloc
|
||||
+ is used. */
|
||||
+ {
|
||||
+#define SIZE 131072
|
||||
+ CHAR *s = malloc ((SIZE + 1) * sizeof (*s));
|
||||
+ if (s == NULL)
|
||||
+ abort ();
|
||||
+ for (size_t i = 0; i < SIZE; i++)
|
||||
+ s[i] = L('0');
|
||||
+ s[SIZE] = L('\0');
|
||||
+ int i = 42;
|
||||
+ /* Scan multi-digit zero into `i`. */
|
||||
+ if (SSCANF (s, L("%d"), &i) != 1)
|
||||
+ {
|
||||
+ printf ("FAIL: bug16618: SSCANF did not read one input item.\n");
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ if (i != 0)
|
||||
+ {
|
||||
+ printf ("FAIL: bug16618: Value of `i` was not zero as expected.\n");
|
||||
+ result = 1;
|
||||
+ }
|
||||
+ free (s);
|
||||
+ if (result != 1)
|
||||
+ printf ("PASS: bug16618: Did not crash.\n");
|
||||
+#undef SIZE
|
||||
+ }
|
||||
+
|
||||
+
|
||||
return result;
|
||||
}
|
||||
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
|
||||
index cd129a8..0e204e7 100644
|
||||
--- a/libc/stdio-common/vfscanf.c
|
||||
+++ b/libc/stdio-common/vfscanf.c
|
||||
@@ -272,9 +272,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
if (__glibc_unlikely (wpsize == wpmax)) \
|
||||
{ \
|
||||
CHAR_T *old = wp; \
|
||||
- size_t newsize = (UCHAR_MAX + 1 > 2 * wpmax \
|
||||
- ? UCHAR_MAX + 1 : 2 * wpmax); \
|
||||
- if (use_malloc || !__libc_use_alloca (newsize)) \
|
||||
+ bool fits = __glibc_likely (wpmax <= SIZE_MAX / sizeof (CHAR_T) / 2); \
|
||||
+ size_t wpneed = MAX (UCHAR_MAX + 1, 2 * wpmax); \
|
||||
+ size_t newsize = fits ? wpneed * sizeof (CHAR_T) : SIZE_MAX; \
|
||||
+ if (!__libc_use_alloca (newsize)) \
|
||||
{ \
|
||||
wp = realloc (use_malloc ? wp : NULL, newsize); \
|
||||
if (wp == NULL) \
|
||||
@@ -286,14 +287,13 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
|
||||
} \
|
||||
if (! use_malloc) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
- wpmax = newsize; \
|
||||
+ wpmax = wpneed; \
|
||||
use_malloc = true; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
size_t s = wpmax * sizeof (CHAR_T); \
|
||||
- wp = (CHAR_T *) extend_alloca (wp, s, \
|
||||
- newsize * sizeof (CHAR_T)); \
|
||||
+ wp = (CHAR_T *) extend_alloca (wp, s, newsize); \
|
||||
wpmax = s / sizeof (CHAR_T); \
|
||||
if (old != NULL) \
|
||||
MEMCPY (wp, old, wpsize); \
|
||||
--
|
||||
1.9.4
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
Fetched from gentoo glibc patchball
|
||||
Original patch filename: 10_all_glibc-CVE-2015-7547.patch
|
||||
Based on: https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html
|
||||
|
||||
Fixes:
|
||||
CVE-2015-7547 - glibc getaddrinfo stack-based buffer overflow.
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
|
||||
int h_namelen = 0;
|
||||
|
||||
if (ancount == 0)
|
||||
- return NSS_STATUS_NOTFOUND;
|
||||
+ {
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ }
|
||||
|
||||
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
||||
{
|
||||
@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
|
||||
/* Special case here: if the resolver sent a result but it only
|
||||
contains a CNAME while we are looking for a T_A or T_AAAA record,
|
||||
we fail with NOTFOUND instead of TRYAGAIN. */
|
||||
- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
|
||||
+ if (canon != NULL)
|
||||
+ {
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ }
|
||||
+
|
||||
+ *h_errnop = NETDB_INTERNAL;
|
||||
+ return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
|
||||
@@ -1242,8 +1252,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
|
||||
&pat, &buffer, &buflen,
|
||||
errnop, h_errnop, ttlp,
|
||||
&first);
|
||||
+ /* Use the second response status in some cases. */
|
||||
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
|
||||
status = status2;
|
||||
+ /* Do not return a truncated second response (unless it was
|
||||
+ unavoidable e.g. unrecoverable TRYAGAIN). */
|
||||
+ if (status == NSS_STATUS_SUCCESS
|
||||
+ && (status2 == NSS_STATUS_TRYAGAIN
|
||||
+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
|
||||
+ status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
return status;
|
||||
--- a/resolv/res_query.c
|
||||
+++ b/resolv/res_query.c
|
||||
@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
}
|
||||
@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp,
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
|
||||
@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp,
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
if (saved_herrno != -1)
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -639,11 +639,7 @@ send_vc(res_state statp,
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
- u_char *ans = *ansp;
|
||||
- int orig_anssizp = *anssizp;
|
||||
- // XXX REMOVE
|
||||
- // int anssiz = *anssizp;
|
||||
- HEADER *anhp = (HEADER *) ans;
|
||||
+ HEADER *anhp = (HEADER *) *ansp;
|
||||
struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
|
||||
int truncating, connreset, n;
|
||||
/* On some architectures compiler might emit a warning indicating
|
||||
@@ -767,35 +763,6 @@ send_vc(res_state statp,
|
||||
assert (anscp != NULL || ansp2 == NULL);
|
||||
thisresplenp = &resplen;
|
||||
} else {
|
||||
- if (*anssizp != MAXPACKET) {
|
||||
- /* No buffer allocated for the first
|
||||
- reply. We can try to use the rest
|
||||
- of the user-provided buffer. */
|
||||
-#if __GNUC_PREREQ (4, 7)
|
||||
- DIAG_PUSH_NEEDS_COMMENT;
|
||||
- DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
|
||||
-#endif
|
||||
-#if _STRING_ARCH_unaligned
|
||||
- *anssizp2 = orig_anssizp - resplen;
|
||||
- *ansp2 = *ansp + resplen;
|
||||
-#else
|
||||
- int aligned_resplen
|
||||
- = ((resplen + __alignof__ (HEADER) - 1)
|
||||
- & ~(__alignof__ (HEADER) - 1));
|
||||
- *anssizp2 = orig_anssizp - aligned_resplen;
|
||||
- *ansp2 = *ansp + aligned_resplen;
|
||||
-#endif
|
||||
-#if __GNUC_PREREQ (4, 7)
|
||||
- DIAG_POP_NEEDS_COMMENT;
|
||||
-#endif
|
||||
- } else {
|
||||
- /* The first reply did not fit into the
|
||||
- user-provided buffer. Maybe the second
|
||||
- answer will. */
|
||||
- *anssizp2 = orig_anssizp;
|
||||
- *ansp2 = *ansp;
|
||||
- }
|
||||
-
|
||||
thisanssizp = anssizp2;
|
||||
thisansp = ansp2;
|
||||
thisresplenp = resplen2;
|
||||
@@ -804,10 +771,14 @@ send_vc(res_state statp,
|
||||
anhp = (HEADER *) *thisansp;
|
||||
|
||||
*thisresplenp = rlen;
|
||||
- if (rlen > *thisanssizp) {
|
||||
- /* Yes, we test ANSCP here. If we have two buffers
|
||||
- both will be allocatable. */
|
||||
- if (__glibc_likely (anscp != NULL)) {
|
||||
+ /* Is the answer buffer too small? */
|
||||
+ if (*thisanssizp < rlen) {
|
||||
+ /* If the current buffer is not the the static
|
||||
+ user-supplied buffer then we can reallocate
|
||||
+ it. */
|
||||
+ if (thisansp != NULL && thisansp != ansp) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *newp = malloc (MAXPACKET);
|
||||
if (newp == NULL) {
|
||||
*terrno = ENOMEM;
|
||||
@@ -957,8 +928,6 @@ send_dg(res_state statp,
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
- u_char *ans = *ansp;
|
||||
- int orig_anssizp = *anssizp;
|
||||
struct timespec now, timeout, finish;
|
||||
struct pollfd pfd[1];
|
||||
int ptimeout;
|
||||
@@ -1154,50 +1123,48 @@ send_dg(res_state statp,
|
||||
assert (anscp != NULL || ansp2 == NULL);
|
||||
thisresplenp = &resplen;
|
||||
} else {
|
||||
- if (*anssizp != MAXPACKET) {
|
||||
- /* No buffer allocated for the first
|
||||
- reply. We can try to use the rest
|
||||
- of the user-provided buffer. */
|
||||
-#if _STRING_ARCH_unaligned
|
||||
- *anssizp2 = orig_anssizp - resplen;
|
||||
- *ansp2 = *ansp + resplen;
|
||||
-#else
|
||||
- int aligned_resplen
|
||||
- = ((resplen + __alignof__ (HEADER) - 1)
|
||||
- & ~(__alignof__ (HEADER) - 1));
|
||||
- *anssizp2 = orig_anssizp - aligned_resplen;
|
||||
- *ansp2 = *ansp + aligned_resplen;
|
||||
-#endif
|
||||
- } else {
|
||||
- /* The first reply did not fit into the
|
||||
- user-provided buffer. Maybe the second
|
||||
- answer will. */
|
||||
- *anssizp2 = orig_anssizp;
|
||||
- *ansp2 = *ansp;
|
||||
- }
|
||||
-
|
||||
thisanssizp = anssizp2;
|
||||
thisansp = ansp2;
|
||||
thisresplenp = resplen2;
|
||||
}
|
||||
|
||||
if (*thisanssizp < MAXPACKET
|
||||
- /* Yes, we test ANSCP here. If we have two buffers
|
||||
- both will be allocatable. */
|
||||
- && anscp
|
||||
+ /* If the current buffer is not the the static
|
||||
+ user-supplied buffer then we can reallocate
|
||||
+ it. */
|
||||
+ && (thisansp != NULL && thisansp != ansp)
|
||||
#ifdef FIONREAD
|
||||
+ /* Is the size too small? */
|
||||
&& (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
|
||||
|| *thisanssizp < *thisresplenp)
|
||||
#endif
|
||||
) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *newp = malloc (MAXPACKET);
|
||||
if (newp != NULL) {
|
||||
- *anssizp = MAXPACKET;
|
||||
- *thisansp = ans = newp;
|
||||
+ *thisanssizp = MAXPACKET;
|
||||
+ *thisansp = newp;
|
||||
if (thisansp == ansp2)
|
||||
*ansp2_malloced = 1;
|
||||
}
|
||||
}
|
||||
+ /* We could end up with truncation if anscp was NULL
|
||||
+ (not allowed to change caller's buffer) and the
|
||||
+ response buffer size is too small. This isn't a
|
||||
+ reliable way to detect truncation because the ioctl
|
||||
+ may be an inaccurate report of the UDP message size.
|
||||
+ Therefore we use this only to issue debug output.
|
||||
+ To do truncation accurately with UDP we need
|
||||
+ MSG_TRUNC which is only available on Linux. We
|
||||
+ can abstract out the Linux-specific feature in the
|
||||
+ future to detect truncation. */
|
||||
+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
|
||||
+ Dprint(statp->options & RES_DEBUG,
|
||||
+ (stdout, ";; response may be truncated (UDP)\n")
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
HEADER *anhp = (HEADER *) *thisansp;
|
||||
socklen_t fromlen = sizeof(struct sockaddr_in6);
|
||||
assert (sizeof(from) <= fromlen);
|
||||
@@ -1,32 +0,0 @@
|
||||
From 10c6d2e3243cefdd22933d3706f53d9f913c6cab Mon Sep 17 00:00:00 2001
|
||||
From: Arjun Shankar <arjun.is@lostca.se>
|
||||
Date: Tue, 21 Apr 2015 14:06:31 +0200
|
||||
Subject: [PATCH] CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow
|
||||
[BZ#18287]
|
||||
|
||||
Fixes:
|
||||
CVE-2015-1781 - buffer overflow in gethostbyname_r() and related
|
||||
functions with misaligned buffer.
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
---
|
||||
resolv/nss_dns/dns-host.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
|
||||
index f715ab0..40069a7 100644
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -615,7 +615,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
int have_to_map = 0;
|
||||
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
|
||||
buffer += pad;
|
||||
- if (__glibc_unlikely (buflen < sizeof (struct host_data) + pad))
|
||||
+ buflen = buflen > pad ? buflen - pad : 0;
|
||||
+ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
|
||||
{
|
||||
/* The buffer is too small. */
|
||||
too_small:
|
||||
--
|
||||
2.4.4
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
From 6d0b7b443c9735672bb76d003c3f7263c5292d7d Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed, 29 Apr 2015 14:41:25 +0200
|
||||
Subject: [PATCH 23/27] CVE-2014-8121: Do not close NSS files database during
|
||||
iteration [BZ #18007]
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
(cherry picked from commit e871e19b5f19d2e6595e911b0a5b1c19cda20cc7)
|
||||
|
||||
Fixes:
|
||||
CVE-2014-8121 - Unexpected closing of nss_files databases after lookups
|
||||
causes denial of service.
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
---
|
||||
nss/Makefile | 2 +-
|
||||
nss/nss_files/files-XXX.c | 2 +-
|
||||
nss/tst-nss-getpwent.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 120 insertions(+), 2 deletions(-)
|
||||
create mode 100644 nss/tst-nss-getpwent.c
|
||||
|
||||
diff --git a/nss/Makefile b/nss/Makefile
|
||||
index d419baf..dc351dd 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -39,7 +39,7 @@ install-bin := getent makedb
|
||||
makedb-modules = xmalloc hash-string
|
||||
extra-objs += $(makedb-modules:=.o)
|
||||
|
||||
-tests = test-netdb tst-nss-test1 test-digits-dots
|
||||
+tests = test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
|
||||
xtests = bug-erange
|
||||
|
||||
# Specify rules for the nss_* modules. We have some services.
|
||||
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
|
||||
index a7a45e5..a7ce5ea 100644
|
||||
--- a/nss/nss_files/files-XXX.c
|
||||
+++ b/nss/nss_files/files-XXX.c
|
||||
@@ -134,7 +134,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
- status = internal_setent (stayopen);
|
||||
+ status = internal_setent (1);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
|
||||
{
|
||||
diff --git a/nss/tst-nss-getpwent.c b/nss/tst-nss-getpwent.c
|
||||
new file mode 100644
|
||||
index 0000000..f2e8abc
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-getpwent.c
|
||||
@@ -0,0 +1,118 @@
|
||||
+/* Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <pwd.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* Count the number of entries in the password database, and fetch
|
||||
+ data from the first and last entries. */
|
||||
+ size_t count = 0;
|
||||
+ struct passwd * pw;
|
||||
+ char *first_name = NULL;
|
||||
+ uid_t first_uid = 0;
|
||||
+ char *last_name = NULL;
|
||||
+ uid_t last_uid = 0;
|
||||
+ setpwent ();
|
||||
+ while ((pw = getpwent ()) != NULL)
|
||||
+ {
|
||||
+ if (first_name == NULL)
|
||||
+ {
|
||||
+ first_name = strdup (pw->pw_name);
|
||||
+ if (first_name == NULL)
|
||||
+ {
|
||||
+ printf ("strdup: %m\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ first_uid = pw->pw_uid;
|
||||
+ }
|
||||
+
|
||||
+ free (last_name);
|
||||
+ last_name = strdup (pw->pw_name);
|
||||
+ if (last_name == NULL)
|
||||
+ {
|
||||
+ printf ("strdup: %m\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ last_uid = pw->pw_uid;
|
||||
+ ++count;
|
||||
+ }
|
||||
+ endpwent ();
|
||||
+
|
||||
+ if (count == 0)
|
||||
+ {
|
||||
+ printf ("No entries in the password database.\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Try again, this time interleaving with name-based and UID-based
|
||||
+ lookup operations. The counts do not match if the interleaved
|
||||
+ lookups affected the enumeration. */
|
||||
+ size_t new_count = 0;
|
||||
+ setpwent ();
|
||||
+ while ((pw = getpwent ()) != NULL)
|
||||
+ {
|
||||
+ if (new_count == count)
|
||||
+ {
|
||||
+ printf ("Additional entry in the password database.\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ ++new_count;
|
||||
+ struct passwd *pw2 = getpwnam (first_name);
|
||||
+ if (pw2 == NULL)
|
||||
+ {
|
||||
+ printf ("getpwnam (%s) failed: %m\n", first_name);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ pw2 = getpwnam (last_name);
|
||||
+ if (pw2 == NULL)
|
||||
+ {
|
||||
+ printf ("getpwnam (%s) failed: %m\n", last_name);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ pw2 = getpwuid (first_uid);
|
||||
+ if (pw2 == NULL)
|
||||
+ {
|
||||
+ printf ("getpwuid (%llu) failed: %m\n",
|
||||
+ (unsigned long long) first_uid);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ pw2 = getpwuid (last_uid);
|
||||
+ if (pw2 == NULL)
|
||||
+ {
|
||||
+ printf ("getpwuid (%llu) failed: %m\n",
|
||||
+ (unsigned long long) last_uid);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ endpwent ();
|
||||
+ if (new_count < count)
|
||||
+ {
|
||||
+ printf ("Missing entry in the password database.\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
||||
--
|
||||
2.6.2
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From 8415fb8d4f05c023b9d79e44dff197cc285fd1e5 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Frysinger <vapier@gentoo.org>
|
||||
Date: Thu, 6 Aug 2015 02:10:46 -0400
|
||||
Subject: [PATCH] microblaze: include unix/sysdep.h
|
||||
|
||||
The semi-recent SYSCALL_CANCEL inclusion broke microblaze due to the
|
||||
sysdep.h header not including the unix/sysdep.h header. Include it
|
||||
here like all other ports.
|
||||
|
||||
(cherry picked from commit 5d5de49c3ccd69f65b801f1ca490a0112d1cbd7d)
|
||||
|
||||
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
[edited to remove ChangeLog modifications, which cause conflicts.]
|
||||
---
|
||||
sysdeps/unix/sysv/linux/microblaze/sysdep.h | 7 ++++++-
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/microblaze/sysdep.h b/sysdeps/unix/sysv/linux/microblaze/sysdep.h
|
||||
index 83c0340..9d5c542 100644
|
||||
--- a/sysdeps/unix/sysv/linux/microblaze/sysdep.h
|
||||
+++ b/sysdeps/unix/sysv/linux/microblaze/sysdep.h
|
||||
@@ -16,8 +16,11 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
+#ifndef _LINUX_MICROBLAZE_SYSDEP_H
|
||||
+#define _LINUX_MICROBLAZE_SYSDEP_H 1
|
||||
+
|
||||
+#include <sysdeps/unix/sysdep.h>
|
||||
#include <sysdeps/microblaze/sysdep.h>
|
||||
-#include <sys/syscall.h>
|
||||
|
||||
/* Defines RTLD_PRIVATE_ERRNO. */
|
||||
#include <dl-sysdep.h>
|
||||
@@ -305,3 +308,5 @@ SYSCALL_ERROR_LABEL_DCL: \
|
||||
# define PTR_DEMANGLE(var) (void) (var)
|
||||
|
||||
#endif /* not __ASSEMBLER__ */
|
||||
+
|
||||
+#endif /* _LINUX_MICROBLAZE_SYSDEP_H */
|
||||
--
|
||||
2.6.4
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From 883dceebc8f11921a9890211a4e202e5be17562f Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 29 Mar 2016 12:57:56 +0200
|
||||
Subject: [PATCH 1/1] CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879]
|
||||
|
||||
The defensive copy is not needed because the name may not alias the
|
||||
output buffer.
|
||||
|
||||
(cherry picked from commit 317b199b4aff8cfa27f2302ab404d2bb5032b9a4)
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
||||
(downloaded from upstream git repo and removed changes to Changelog:
|
||||
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=883dceebc8f11921a9890211a4e202e5be17562f;hp=5a1a5f0dd2744044801c91bf2588444c29cda533)
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
resolv/nss_dns/dns-network.c | 5 +----
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
|
||||
index 00f4490..89f8783 100644
|
||||
--- a/resolv/nss_dns/dns-network.c
|
||||
+++ b/resolv/nss_dns/dns-network.c
|
||||
@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
int anslen;
|
||||
- char *qbuf;
|
||||
enum nss_status status;
|
||||
|
||||
if (__res_maybe_init (&_res, 0) == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
- qbuf = strdupa (name);
|
||||
-
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
+ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (anslen < 0)
|
||||
{
|
||||
--
|
||||
1.7.1
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 146b58d11fddbef15b888906e3be4f33900c416f Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 29 Mar 2016 12:57:56 +0200
|
||||
Subject: [PATCH 1/1] CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879]
|
||||
|
||||
The defensive copy is not needed because the name may not alias the
|
||||
output buffer.
|
||||
|
||||
(cherry picked from commit 317b199b4aff8cfa27f2302ab404d2bb5032b9a4)
|
||||
(cherry picked from commit 883dceebc8f11921a9890211a4e202e5be17562f)
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
||||
(downloaded from upstream git repo and removed changes to files
|
||||
Changelog and NEWS:
|
||||
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=146b58d11fddbef15b888906e3be4f33900c416f;hp=0eb234232eaf925fe4dca3bd60a3e1b4a7ab2882)
|
||||
---
|
||||
ChangeLog | 7 +++++++
|
||||
NEWS | 10 ++++++++--
|
||||
resolv/nss_dns/dns-network.c | 5 +----
|
||||
3 files changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
|
||||
index 2eb2f67..8f301a7 100644
|
||||
--- a/resolv/nss_dns/dns-network.c
|
||||
+++ b/resolv/nss_dns/dns-network.c
|
||||
@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
int anslen;
|
||||
- char *qbuf;
|
||||
enum nss_status status;
|
||||
|
||||
if (__res_maybe_init (&_res, 0) == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
- qbuf = strdupa (name);
|
||||
-
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
+ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
|
||||
if (anslen < 0)
|
||||
{
|
||||
--
|
||||
1.7.1
|
||||
|
||||
88
bsp/buildroot/package/glibc/2.23/0002-gcc6.patch
Normal file
88
bsp/buildroot/package/glibc/2.23/0002-gcc6.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 5769d5d17cdb4770f1e08167b76c1684ad4e1f73 Mon Sep 17 00:00:00 2001
|
||||
From: Yvan Roux <yvan.roux@linaro.org>
|
||||
Date: Fri, 15 Apr 2016 13:29:26 +0200
|
||||
Subject: [PATCH 1/1] Suppress GCC 6 warning about ambiguous 'else' with -Wparentheses
|
||||
|
||||
(cherry picked from commit df1cf48777fe4cd81ad7fb09ecbe5b31432b7c1c)
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
||||
(downloaded from upstream git repo and removed changes to Changelog:
|
||||
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5769d5d17cdb4770f1e08167b76c1684ad4e1f73;hp=f1e182acaaa84e844eb96462a92ba532e1c1fff4)
|
||||
---
|
||||
ChangeLog | 5 +++++
|
||||
nis/nis_call.c | 20 +++++++++++---------
|
||||
stdlib/setenv.c | 26 ++++++++++++++------------
|
||||
3 files changed, 30 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/nis/nis_call.c b/nis/nis_call.c
|
||||
index 3fa37e4..cb7839a 100644
|
||||
--- a/nis/nis_call.c
|
||||
+++ b/nis/nis_call.c
|
||||
@@ -680,16 +680,18 @@ nis_server_cache_add (const_nis_name name, int search_parent,
|
||||
/* Choose which entry should be evicted from the cache. */
|
||||
loc = &nis_server_cache[0];
|
||||
if (*loc != NULL)
|
||||
- for (i = 1; i < 16; ++i)
|
||||
- if (nis_server_cache[i] == NULL)
|
||||
- {
|
||||
+ {
|
||||
+ for (i = 1; i < 16; ++i)
|
||||
+ if (nis_server_cache[i] == NULL)
|
||||
+ {
|
||||
+ loc = &nis_server_cache[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ else if ((*loc)->uses > nis_server_cache[i]->uses
|
||||
+ || ((*loc)->uses == nis_server_cache[i]->uses
|
||||
+ && (*loc)->expires > nis_server_cache[i]->expires))
|
||||
loc = &nis_server_cache[i];
|
||||
- break;
|
||||
- }
|
||||
- else if ((*loc)->uses > nis_server_cache[i]->uses
|
||||
- || ((*loc)->uses == nis_server_cache[i]->uses
|
||||
- && (*loc)->expires > nis_server_cache[i]->expires))
|
||||
- loc = &nis_server_cache[i];
|
||||
+ }
|
||||
old = *loc;
|
||||
*loc = new;
|
||||
|
||||
diff --git a/stdlib/setenv.c b/stdlib/setenv.c
|
||||
index da61ee0..e66045f 100644
|
||||
--- a/stdlib/setenv.c
|
||||
+++ b/stdlib/setenv.c
|
||||
@@ -278,18 +278,20 @@ unsetenv (const char *name)
|
||||
ep = __environ;
|
||||
if (ep != NULL)
|
||||
while (*ep != NULL)
|
||||
- if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
- {
|
||||
- /* Found it. Remove this pointer by moving later ones back. */
|
||||
- char **dp = ep;
|
||||
-
|
||||
- do
|
||||
- dp[0] = dp[1];
|
||||
- while (*dp++);
|
||||
- /* Continue the loop in case NAME appears again. */
|
||||
- }
|
||||
- else
|
||||
- ++ep;
|
||||
+ {
|
||||
+ if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
+ {
|
||||
+ /* Found it. Remove this pointer by moving later ones back. */
|
||||
+ char **dp = ep;
|
||||
+
|
||||
+ do
|
||||
+ dp[0] = dp[1];
|
||||
+ while (*dp++);
|
||||
+ /* Continue the loop in case NAME appears again. */
|
||||
+ }
|
||||
+ else
|
||||
+ ++ep;
|
||||
+ }
|
||||
|
||||
UNLOCK;
|
||||
|
||||
--
|
||||
1.7.1
|
||||
|
||||
@@ -1,45 +1,26 @@
|
||||
if BR2_TOOLCHAIN_BUILDROOT_EGLIBC
|
||||
|
||||
config BR2_PACKAGE_EGLIBC
|
||||
bool
|
||||
default y
|
||||
select BR2_PACKAGE_LINUX_HEADERS
|
||||
|
||||
choice
|
||||
prompt "eglibc version"
|
||||
default BR2_EGLIBC_VERSION_2_18
|
||||
|
||||
config BR2_EGLIBC_VERSION_2_18
|
||||
bool "2.18-svnr23787"
|
||||
# Build breakage
|
||||
depends on !BR2_sparc
|
||||
|
||||
config BR2_EGLIBC_VERSION_2_19
|
||||
bool "2.19-svnr25243"
|
||||
# Build breakage
|
||||
depends on !BR2_powerpc_SPE
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
if BR2_TOOLCHAIN_BUILDROOT_GLIBC
|
||||
|
||||
config BR2_PACKAGE_GLIBC
|
||||
bool
|
||||
default y
|
||||
select BR2_PACKAGE_LINUX_HEADERS
|
||||
select BR2_TOOLCHAIN_HAS_SSP
|
||||
|
||||
choice
|
||||
prompt "glibc version"
|
||||
default BR2_GLIBC_VERSION_2_21
|
||||
|
||||
config BR2_GLIBC_VERSION_2_21
|
||||
bool "2.21"
|
||||
default BR2_GLIBC_VERSION_2_23
|
||||
|
||||
config BR2_GLIBC_VERSION_2_22
|
||||
bool "2.22"
|
||||
depends on !BR2_sparc # broken
|
||||
# No support for pthread barriers on < v9 ISA
|
||||
depends on !BR2_sparc
|
||||
# Too old to build with gcc >= 6.x
|
||||
depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_6
|
||||
|
||||
config BR2_GLIBC_VERSION_2_23
|
||||
bool "2.23"
|
||||
# No support for pthread barriers on < v9 ISA
|
||||
depends on !BR2_sparc
|
||||
|
||||
endchoice
|
||||
|
||||
@@ -47,7 +28,5 @@ endif
|
||||
|
||||
config BR2_GLIBC_VERSION_STRING
|
||||
string
|
||||
default "2.18-svnr23787" if BR2_EGLIBC_VERSION_2_18
|
||||
default "2.19-svnr25243" if BR2_EGLIBC_VERSION_2_19
|
||||
default "2.21" if BR2_GLIBC_VERSION_2_21
|
||||
default "2.22" if BR2_GLIBC_VERSION_2_22
|
||||
default "2.23" if BR2_GLIBC_VERSION_2_23
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# Locally calculated after checking pgp signature (glibc)
|
||||
# http://downloads.yoctoproject.org/releases/eglibc/*.{md5,sha1} (eglibc)
|
||||
md5 b395b021422a027d89884992e91734fc eglibc-2.18-svnr23787.tar.bz2
|
||||
sha1 224d9e655e8f0ad04ffde47b97a11c64e2255b56 eglibc-2.18-svnr23787.tar.bz2
|
||||
md5 197836c2ba42fb146e971222647198dd eglibc-2.19-svnr25243.tar.bz2
|
||||
sha1 8013c1935b46fd50d2d1fbfad3b0af362b75fb28 eglibc-2.19-svnr25243.tar.bz2
|
||||
sha256 aeeb362437965a5d3f40b151094ca79def04a115bd363fdd4a9a0c69482923b8 glibc-2.21.tar.xz
|
||||
sha256 eb731406903befef1d8f878a46be75ef862b9056ab0cde1626d08a7a05328948 glibc-2.22.tar.xz
|
||||
sha256 94efeb00e4603c8546209cefb3e1a50a5315c86fa9b078b6fad758e187ce13e9 glibc-2.23.tar.xz
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
################################################################################
|
||||
#
|
||||
# glibc/eglibc
|
||||
# glibc
|
||||
#
|
||||
################################################################################
|
||||
|
||||
GLIBC_VERSION = $(call qstrip,$(BR2_GLIBC_VERSION_STRING))
|
||||
|
||||
ifeq ($(BR2_TOOLCHAIN_BUILDROOT_EGLIBC),y)
|
||||
GLIBC_SITE = http://downloads.yoctoproject.org/releases/eglibc
|
||||
GLIBC_SOURCE = eglibc-$(GLIBC_VERSION).tar.bz2
|
||||
GLIBC_SRC_SUBDIR = libc
|
||||
else
|
||||
GLIBC_SITE = $(BR2_GNU_MIRROR)/libc
|
||||
GLIBC_SOURCE = glibc-$(GLIBC_VERSION).tar.xz
|
||||
GLIBC_SRC_SUBDIR = .
|
||||
endif
|
||||
|
||||
GLIBC_LICENSE = GPLv2+ (programs), LGPLv2.1+, BSD-3c, MIT (library)
|
||||
GLIBC_LICENSE_FILES = $(addprefix $(GLIBC_SRC_SUBDIR)/,COPYING COPYING.LIB LICENSES)
|
||||
@@ -22,7 +15,7 @@ GLIBC_LICENSE_FILES = $(addprefix $(GLIBC_SRC_SUBDIR)/,COPYING COPYING.LIB LICEN
|
||||
# glibc is part of the toolchain so disable the toolchain dependency
|
||||
GLIBC_ADD_TOOLCHAIN_DEPENDENCY = NO
|
||||
|
||||
# Before (e)glibc is configured, we must have the first stage
|
||||
# Before glibc is configured, we must have the first stage
|
||||
# cross-compiler and the kernel headers
|
||||
GLIBC_DEPENDENCIES = host-gcc-initial linux-headers host-gawk
|
||||
|
||||
@@ -71,7 +64,7 @@ endif
|
||||
# 2. We have to execute the configure script with bash and not sh.
|
||||
#
|
||||
# Note that as mentionned in
|
||||
# http://patches.openembedded.org/patch/38849/, eglibc/glibc must be
|
||||
# http://patches.openembedded.org/patch/38849/, glibc must be
|
||||
# built with -O2, so we pass our own CFLAGS and CXXFLAGS below.
|
||||
define GLIBC_CONFIGURE_CMDS
|
||||
mkdir -p $(@D)/build
|
||||
@@ -96,6 +89,7 @@ define GLIBC_CONFIGURE_CMDS
|
||||
--disable-profile \
|
||||
--without-gd \
|
||||
--enable-obsolete-rpc \
|
||||
--enable-kernel=$(call qstrip,$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)) \
|
||||
--with-headers=$(STAGING_DIR)/usr/include)
|
||||
$(GLIBC_ADD_MISSING_STUB_H)
|
||||
endef
|
||||
@@ -117,7 +111,7 @@ endif
|
||||
|
||||
define GLIBC_INSTALL_TARGET_CMDS
|
||||
for libs in $(GLIBC_LIBS_LIB); do \
|
||||
$(call copy_toolchain_lib_root,$(STAGING_DIR)/,,lib,$$libs,/lib) ; \
|
||||
$(call copy_toolchain_lib_root,$$libs) ; \
|
||||
done
|
||||
endef
|
||||
|
||||
|
||||
Reference in New Issue
Block a user