Move all to deprecated folder.

This commit is contained in:
2016-11-16 21:57:57 +01:00
parent 01738a7684
commit 05de7d6c04
9777 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
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);

View File

@@ -0,0 +1,33 @@
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.]*\)],

View File

@@ -0,0 +1,141 @@
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

View File

@@ -0,0 +1,20 @@
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

View File

@@ -0,0 +1,88 @@
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

View File

@@ -0,0 +1,174 @@
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);

View File

@@ -0,0 +1,141 @@
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

View File

@@ -0,0 +1,20 @@
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

View File

@@ -0,0 +1,88 @@
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

View File

@@ -0,0 +1,236 @@
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);

View File

@@ -0,0 +1,32 @@
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

View File

@@ -0,0 +1,176 @@
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

View File

@@ -0,0 +1,236 @@
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 *nsap = get_nsaddr (statp, 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);

View File

@@ -0,0 +1,53 @@
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
choice
prompt "glibc version"
default BR2_GLIBC_VERSION_2_21
config BR2_GLIBC_VERSION_2_21
bool "2.21"
config BR2_GLIBC_VERSION_2_22
bool "2.22"
depends on !BR2_sparc # broken
endchoice
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

View File

@@ -0,0 +1,8 @@
# 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

View File

@@ -0,0 +1,154 @@
################################################################################
#
# glibc/eglibc
#
################################################################################
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)
# 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
# cross-compiler and the kernel headers
GLIBC_DEPENDENCIES = host-gcc-initial linux-headers host-gawk
GLIBC_SUBDIR = build
GLIBC_INSTALL_STAGING = YES
GLIBC_INSTALL_STAGING_OPTS = install_root=$(STAGING_DIR) install
# Thumb build is broken, build in ARM mode
ifeq ($(BR2_ARM_INSTRUCTIONS_THUMB),y)
GLIBC_EXTRA_CFLAGS += -marm
endif
# MIPS64 defaults to n32 so pass the correct -mabi if
# we are using a different ABI. OABI32 is also used
# in MIPS so we pass -mabi=32 in this case as well
# even though it's not strictly necessary.
ifeq ($(BR2_MIPS_NABI64),y)
GLIBC_EXTRA_CFLAGS += -mabi=64
else ifeq ($(BR2_MIPS_OABI32),y)
GLIBC_EXTRA_CFLAGS += -mabi=32
endif
ifeq ($(BR2_ENABLE_DEBUG),y)
GLIBC_EXTRA_CFLAGS += -g
endif
# The stubs.h header is not installed by install-headers, but is
# needed for the gcc build. An empty stubs.h will work, as explained
# in http://gcc.gnu.org/ml/gcc/2002-01/msg00900.html. The same trick
# is used by Crosstool-NG.
ifeq ($(BR2_TOOLCHAIN_BUILDROOT_GLIBC),y)
define GLIBC_ADD_MISSING_STUB_H
mkdir -p $(STAGING_DIR)/usr/include/gnu
touch $(STAGING_DIR)/usr/include/gnu/stubs.h
endef
endif
# Even though we use the autotools-package infrastructure, we have to
# override the default configure commands for several reasons:
#
# 1. We have to build out-of-tree, but we can't use the same
# 'symbolic link to configure' used with the gcc packages.
#
# 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
# built with -O2, so we pass our own CFLAGS and CXXFLAGS below.
define GLIBC_CONFIGURE_CMDS
mkdir -p $(@D)/build
# Do the configuration
(cd $(@D)/build; \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="-O2 $(GLIBC_EXTRA_CFLAGS)" CPPFLAGS="" \
CXXFLAGS="-O2 $(GLIBC_EXTRA_CFLAGS)" \
$(SHELL) $(@D)/$(GLIBC_SRC_SUBDIR)/configure \
ac_cv_path_BASH_SHELL=/bin/bash \
libc_cv_forced_unwind=yes \
libc_cv_ssp=no \
--target=$(GNU_TARGET_NAME) \
--host=$(GNU_TARGET_NAME) \
--build=$(GNU_HOST_NAME) \
--prefix=/usr \
--enable-shared \
$(if $(BR2_SOFT_FLOAT),--without-fp,--with-fp) \
$(if $(BR2_x86_64),--enable-lock-elision) \
--with-pkgversion="Buildroot" \
--without-cvs \
--disable-profile \
--without-gd \
--enable-obsolete-rpc \
--with-headers=$(STAGING_DIR)/usr/include)
$(GLIBC_ADD_MISSING_STUB_H)
endef
#
# We also override the install to target commands since we only want
# to install the libraries, and nothing more.
#
GLIBC_LIBS_LIB = \
ld*.so.* libc.so.* libcrypt.so.* libdl.so.* libgcc_s.so.* libm.so.* \
libnsl.so.* libpthread.so.* libresolv.so.* librt.so.* libutil.so.* \
libnss_files.so.* libnss_dns.so.*
ifeq ($(BR2_PACKAGE_GDB),y)
GLIBC_LIBS_LIB += libthread_db.so.*
endif
define GLIBC_INSTALL_TARGET_CMDS
for libs in $(GLIBC_LIBS_LIB); do \
$(call copy_toolchain_lib_root,$(STAGING_DIR)/,,lib,$$libs,/lib) ; \
done
endef
# MIPS R6 requires to have NaN2008 support which is currently not
# supported by the Linux kernel. In order to prevent building the
# glibc against kernels not having NaN2008 support on platforms that
# requires it, glibc currently checks for an (inexisting) 10.0.0
# kernel headers version.
#
# Since in practice the kernel support for NaN2008 is not really
# required for things to work properly, we adjust the glibc check to
# make it believe that NaN2008 support was added in the kernel
# starting from version 4.0.0.
#
# In general the compatibility issues introduced by mis-matched NaN
# encodings will not cause a problem as signalling NaNs are rarely used
# in average code. For MIPS R6 there isn't actually any compatibility
# issue as the hardware is always NaN2008 and software is always
# NaN2008. The problem only comes from when older MIPS code is linked in
# via a DSO and multiple NaN encodings are introduced. Since Buildroot
# is intended to have all code built from source then this scenario is
# highly unlikely. The failure mode, if it ever occurs, would be either
# that a signalling NaN fails to raise an invalid operation exception or
# (more likely) an ordinary NaN raises an invalid operation exception.
ifeq ($(BR2_mips_32r6)$(BR2_mips_64r6),y)
define GLIBC_FIX_MIPS_R6
$(SED) 's#10.0.0#4.0.0#' \
$(@D)/sysdeps/unix/sysv/linux/mips/configure \
$(@D)/sysdeps/unix/sysv/linux/mips/configure.ac
endef
GLIBC_POST_EXTRACT_HOOKS += GLIBC_FIX_MIPS_R6
endif
$(eval $(autotools-package))

View File

@@ -0,0 +1,13 @@
# /etc/nsswitch.conf
passwd: files
group: files
shadow: files
hosts: files dns
networks: files dns
protocols: files
services: files
ethers: files
rpc: files