Florian Weimer [Thu, 15 Oct 2015 07:23:07 +0000 (09:23 +0200)]
Always enable pointer guard [BZ #18928]
Honoring the LD_POINTER_GUARD environment variable in AT_SECURE mode
has security implications. This commit enables pointer guard
unconditionally, and the environment variable is now ignored.
[BZ #18928]
* sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove
_dl_pointer_guard member.
* elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard
initializer.
(security_init): Always set up pointer guard.
(process_envvars): Do not process LD_POINTER_GUARD.
Leonhard Holz [Tue, 13 Jan 2015 06:03:56 +0000 (11:33 +0530)]
Fix memory handling in strxfrm_l [BZ #16009]
[Modified from the original email by Siddhesh Poyarekar]
This patch solves bug #16009 by implementing an additional path in
strxfrm that does not depend on caching the weight and rule indices.
In detail the following changed:
* The old main loop was factored out of strxfrm_l into the function
do_xfrm_cached to be able to alternativly use the non-caching version
do_xfrm.
* strxfrm_l allocates a a fixed size array on the stack. If this is not
sufficiant to store the weight and rule indices, the non-caching path is
taken. As the cache size is not dependent on the input there can be no
problems with integer overflows or stack allocations greater than
__MAX_ALLOCA_CUTOFF. Note that malloc-ing is not possible because the
definition of strxfrm does not allow an oom errorhandling.
* The uncached path determines the weight and rule index for every char
and for every pass again.
* Passing all the locale data array by array resulted in very long
parameter lists, so I introduced a structure that holds them.
* Checking for zero src string has been moved a bit upwards, it is
before the locale data initialization now.
* To verify that the non-caching path works correct I added a test run
to localedata/sort-test.sh & localedata/xfrm-test.c where all strings
are patched up with spaces so that they are too large for the caching path.
Florian Weimer [Mon, 23 May 2016 18:18:34 +0000 (20:18 +0200)]
CVE-2016-4429: sunrpc: Do not use alloca in clntudp_call [BZ #20112]
The call is technically in a loop, and under certain circumstances
(which are quite difficult to reproduce in a test case), alloca
can be invoked repeatedly during a single call to clntudp_call.
As a result, the available stack space can be exhausted (even
though individual alloca sizes are bounded implicitly by what
can fit into a UDP packet, as a side effect of the earlier
successful send operation).
Florian Weimer [Fri, 25 Mar 2016 10:49:51 +0000 (11:49 +0100)]
resolv: Always set *resplen2 out parameter in send_dg [BZ #19791]
Since commit 44d20bca52ace85850012b0ead37b360e3ecd96e (Implement
second fallback mode for DNS requests), there is a code path which
returns early, before *resplen2 is initialized. This happens if the
name server address is immediately recognized as invalid (because of
lack of protocol support, or if it is a broadcast address such
255.255.255.255, or another invalid address).
If this happens and *resplen2 was non-zero (which is the case if a
previous query resulted in a failure), __libc_res_nquery would reuse
an existing second answer buffer. This answer has been previously
identified as unusable (for example, it could be an NXDOMAIN
response). Due to the presence of a second answer, no name server
switching will occur. The result is a name resolution failure,
although a successful resolution would have been possible if name
servers have been switched and queries had proceeded along the search
path.
The above paragraph still simplifies the situation. Before glibc
2.23, if the second answer needed malloc, the stub resolver would
still attempt to reuse the second answer, but this is not possible
because __libc_res_nsearch has freed it, after the unsuccessful call
to __libc_res_nquerydomain, and set the buffer pointer to NULL. This
eventually leads to an assertion failure in __libc_res_nquery:
/* Make sure both hp and hp2 are defined */
assert((hp != NULL) && (hp2 != NULL));
If assertions are disabled, the consequence is a NULL pointer
dereference on the next line.
Starting with glibc 2.23, as a result of commit e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca (CVE-2015-7547: getaddrinfo()
stack-based buffer overflow (Bug 18665)), the second answer is always
allocated with malloc. This means that the assertion failure happens
with small responses as well because there is no buffer to reuse, as
soon as there is a name resolution failure which triggers a search for
an answer along the search path.
This commit addresses the issue by ensuring that *resplen2 is
initialized before the send_dg function returns.
This commit also addresses a bug where an invalid second reply is
incorrectly returned as a valid to the caller.
* A stack-based buffer overflow was found in libresolv when invoked from
libnss_dns, allowing specially crafted DNS responses to seize control
of execution flow in the DNS client. The buffer overflow occurs in
the functions send_dg (send datagram) and send_vc (send TCP) for the
NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
family. The use of AF_UNSPEC triggers the low-level resolver code to
send out two parallel queries for A and AAAA. A mismanagement of the
buffers used for those queries could result in the response of a query
writing beyond the alloca allocated buffer created by
_nss_dns_gethostbyname4_r. Buffer management is simplified to remove
the overflow. Thanks to the Google Security Team and Red Hat for
reporting the security impact of this issue, and Robert Holiday of
Ciena for reporting the related bug 18665. (CVE-2015-7547)
See also:
https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html
https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html
CVE-2016-3706: getaddrinfo: stack overflow in hostent conversion [BZ #20010]
When converting a struct hostent response to struct gaih_addrtuple, the
gethosts macro (which is called from gaih_inet) used alloca, without
malloc fallback for large responses. This commit changes this code to
use calloc unconditionally.
This commit also consolidated a second hostent-to-gaih_addrtuple
conversion loop (in gaih_inet) to use the new conversion function.
Florian Weimer [Wed, 4 May 2016 10:09:35 +0000 (12:09 +0200)]
CVE-2016-1234: glob: Do not copy d_name field of struct dirent [BZ #19779]
Instead, we store the data we need from the return value of
readdir in an object of the new type struct readdir_result.
This type is independent of the layout of struct dirent.
glob: Simplify the interface for the GLOB_ALTDIRFUNC callback gl_readdir
Previously, application code had to set up the d_namlen member if
the target supported it, involving conditional compilation. After
this change, glob will use the length of the string in d_name instead
of d_namlen to determine the file name length. All glibc targets
provide the d_type and d_ino members, and setting them as needed for
gl_readdir is straightforward.
Changing the behavior with regards to d_ino is left to a future
cleanup.
Stefan Liebler [Thu, 28 Apr 2016 08:21:58 +0000 (10:21 +0200)]
S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()" [BZ #18508].
On s390/s390x backtrace(buffer, size) returns the series of called functions until
"makecontext_ret" and additional entries (up to "size") with "makecontext_ret".
GDB-backtrace is also warning:
"Backtrace stopped: previous frame identical to this frame (corrupt stack?)"
To reproduce this scenario you have to setup a new context with makecontext()
and activate it with setcontext(). See e.g. cf() function in testcase stdlib/tst-makecontext.c.
Or see bug in libgo "Bug 66303 - runtime.Caller() returns infinitely deep stack frames
on s390x " (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66303).
This patch omits the cfi_startproc/cfi_endproc directives in ENTRY/END macro of
__makecontext_ret. Thus no frame information is generated in .eh_frame and backtrace
stops after __makecontext_ret. There is also no .eh_frame info for _start or
thread_start functions.
ChangeLog:
[BZ #18508]
* stdlib/Makefile ($(objpfx)tst-makecontext3):
Depend on $(libdl).
* stdlib/tst-makecontext.c (cf): Test if _Unwind_Backtrace
is not called infinitely times.
(backtrace_helper): New function.
(trace_arg): New struct.
(st1): Enlarge stack size.
* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S:
(__makecontext_ret): Omit cfi_startproc and cfi_endproc.
* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S:
Likewise.
As in bugzilla entry there is overflow in hsearch when looking for prime
number as SIZE_MAX - 1 is divisible by 5. We fix that by rejecting large
inputs before looking for prime.
Avoid overlapping addresses to stpcpy calls in nscd (BZ #16760)
Calls to stpcpy from nscd netgroups code will have overlapping source
and destination when all three values in the returned triplet are
non-NULL and in the expected (host,user,domain) order. This is seen
in valgrind as:
==3181== Source and destination overlap in stpcpy(0x19973b48, 0x19973b48)
==3181== at 0x4C2F30A: stpcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==3181== by 0x12567A: addgetnetgrentX (string3.h:111)
==3181== by 0x12722D: addgetnetgrent (netgroupcache.c:665)
==3181== by 0x11114C: nscd_run_worker (connections.c:1338)
==3181== by 0x4E3C102: start_thread (pthread_create.c:309)
==3181== by 0x59B81AC: clone (clone.S:111)
==3181==
Return NULL for wildcard values in getnetgrent from nscd (BZ #16759)
getnetgrent is supposed to return NULL for values that are wildcards
in the (host, user, domain) triplet. This works correctly with nscd
disabled, but with it enabled, it returns a blank ("") instead of a
NULL. This is easily seen with the output of `getent netgroup foonet`
for a netgroup foonet defined as follows in /etc/netgroup:
foonet (,foo,)
The output with nscd disabled is:
foonet ( ,foo,)
while with nscd enabled, it is:
foonet (,foo,)
The extra space with nscd disabled is due to the fact that `getent
netgroup` adds it if the return value from getnetgrent is NULL for
either host or user.
Fix nscd lookup for innetgr when netgroup has wildcards (BZ #16758)
nscd works correctly when the request in innetgr is a wildcard,
i.e. when one or more of host, user or domain parameters is NULL.
However, it does not work when the the triplet in the netgroup
definition has a wildcard. This is easy to reproduce for a triplet
defined as follows:
foonet (,foo,)
Here, an innetgr call that looks like this:
innetgr ("foonet", "foohost", "foo", NULL);
should succeed and so should:
innetgr ("foonet", NULL, "foo", "foodomain");
It does succeed with nscd disabled, but not with nscd enabled. This
fix adds this additional check for all three parts of the triplet so
that it gives the correct result.
[BZ #16758]
* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
blank values.
The lookup function implementation in
nss/nss_files/files-XXX.c:DB_LOOKUP has code to prevent that. It is
supposed skip closing the input file if it was already open.
/* Reset file pointer to beginning or open file. */ \
status = internal_setent (keep_stream); \
\
if (status == NSS_STATUS_SUCCESS) \
{ \
/* Tell getent function that we have repositioned the file pointer. */ \
last_use = getby; \
\
while ((status = internal_getent (result, buffer, buflen, errnop \
H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
== NSS_STATUS_SUCCESS) \
{ break_if_match } \
\
if (! keep_stream) \
internal_endent (); \
} \
keep_stream is initialized from the stayopen flag in internal_setent.
internal_setent is called from the set*ent implementation as:
status = internal_setent (stayopen);
However, for non-host database, this flag is always 0, per the
STAYOPEN magic in nss/getXXent_r.c.
Thus, the fix is this:
- status = internal_setent (stayopen);
+ status = internal_setent (1);
This is not a behavioral change even for the hosts database (where the
application can specify the stayopen flag) because with a call to
sethostent(0), the file handle is still not closed in the
implementation of gethostent.
Andreas Schwab [Thu, 20 Mar 2014 14:05:25 +0000 (15:05 +0100)]
Fix use of half-initialized result in getaddrinfo when using nscd (bug 16743)
This fixes a bug in the way the results from __nscd_getai are collected:
for every returned result a new entry is first added to the
gaih_addrtuple list, but if that result doesn't match the request this
entry remains uninitialized. So for this non-matching result an extra
result with uninitialized content is returned.
To reproduce (with nscd running):
$ getent ahostsv4 localhost
127.0.0.1 STREAM localhost
127.0.0.1 DGRAM
127.0.0.1 RAW
(null) STREAM
(null) DGRAM
(null) RAW
The lookup function implementation in
nss/nss_files/files-XXX.c:DB_LOOKUP has code to prevent that. It is
supposed skip closing the input file if it was already open.
/* Reset file pointer to beginning or open file. */ \
status = internal_setent (keep_stream); \
\
if (status == NSS_STATUS_SUCCESS) \
{ \
/* Tell getent function that we have repositioned the file pointer. */ \
last_use = getby; \
\
while ((status = internal_getent (result, buffer, buflen, errnop \
H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
== NSS_STATUS_SUCCESS) \
{ break_if_match } \
\
if (! keep_stream) \
internal_endent (); \
} \
keep_stream is initialized from the stayopen flag in internal_setent.
internal_setent is called from the set*ent implementation as:
status = internal_setent (stayopen);
However, for non-host database, this flag is always 0, per the
STAYOPEN magic in nss/getXXent_r.c.
Thus, the fix is this:
- status = internal_setent (stayopen);
+ status = internal_setent (1);
This is not a behavioral change even for the hosts database (where the
application can specify the stayopen flag) because with a call to
sethostent(0), the file handle is still not closed in the
implementation of gethostent.
Paul Pluzhnikov [Fri, 6 Feb 2015 05:30:42 +0000 (00:30 -0500)]
CVE-2015-1472: wscanf allocates too little memory
BZ #16618
Under certain conditions wscanf can allocate too little memory for the
to-be-scanned arguments and overflow the allocated buffer. The
implementation now correctly computes the required buffer size when
using malloc.
Carlos O'Donell [Wed, 19 Nov 2014 16:44:12 +0000 (11:44 -0500)]
CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
The function wordexp() fails to properly handle the WRDE_NOCMD
flag when processing arithmetic inputs in the form of "$((... ``))"
where "..." can be anything valid. The backticks in the arithmetic
epxression are evaluated by in a shell even if WRDE_NOCMD forbade
command substitution. This allows an attacker to attempt to pass
dangerous commands via constructs of the above form, and bypass
the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
in exec_comm(), the only place that can execute a shell. All other
checks for WRDE_NOCMD are superfluous and removed.
We expand the testsuite and add 3 new regression tests of roughly
the same form but with a couple of nested levels.
On top of the 3 new tests we add fork validation to the WRDE_NOCMD
testing. If any forks are detected during the execution of a wordexp()
call with WRDE_NOCMD, the test is marked as failed. This is slightly
heuristic since vfork might be used in the future, but it provides a
higher level of assurance that no shells were executed as part of
command substitution with WRDE_NOCMD in effect. In addition it doesn't
require libpthread or libdl, instead we use the public implementation
namespace function __register_atfork (already part of the public ABI
for libpthread).
Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer (BZ #16878)
The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL
(with errno as ERANGE) when the supplied buffer does not have
sufficient space for the result. This is wrong, because the canonical
way to indicate insufficient buffer is to set the errno to ERANGE and
the status to NSS_STATUS_TRYAGAIN, as is used by all other modules.
This fixes nscd behaviour when the nss_ldap module returns
NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to
fit into the supplied buffer.
Provide correct buffer length to netgroup queries in nscd (BZ #16695)
The buffer to query netgroup entries is allocated sufficient space for
the netgroup entries and the key to be appended at the end, but it
sends in an incorrect available length to the NSS netgroup query
functions, resulting in overflow of the buffer in some special cases.
The fix here is to factor in the key length when sending the available
buffer and buffer length to the query functions.
Now that MEMCPY_OK_FOR_FWD_MEMMOVE should be define on memcopy.h there
is no need to specialized powerpc memmove implementation. This patch
moves the define set to powerpc memcopy and cleanup its definition on
powerpc code.
PowerPC: Align power7 memcpy using VSX to quadword
This patch changes power7 memcpy to use VSX instructions only when
memory is aligned to quardword. It is to avoid unaligned kernel traps
on non-cacheable memory (for instance, memory-mapped I/O).
This patch adds an optimized memmove optimization for POWER7/powerpc64.
Basically the idea is to use the memcpy for POWER7 on non-overlapped
memory regions and a optimized backward memcpy for memory regions
that overlap (similar to the idea of string/memmove.c).
The backward memcpy algorithm used is similar the one use for memcpy for
POWER7, with adjustments done for alignment. The difference is memory
is always aligned to 16 bytes before using VSX/altivec instructions.
This patch removes the powerpc specific logic in memmove and instead
include default implementation with MEMCPY_OK_FOR_FWD_MEMMOVE defined.
This lead in a increase performance, since the constraints to use
memcpy in powerpc code are too restrictive and memcpy can be used for
any forward memmove.
This patch adds an ifunc power7 strcat symbol that uses the logic on
sysdeps/powerpc/strcat.c but call power7 strlen/strcpy symbols instead
of default ones.
Linux commit dd58a092c4202f2bd490adab7285b3ff77f8e467 added the
PPC_FEATURE2_VEC_CRYPTO auvx capability to indicate whether to
hardware supports vector crypto hardware instructions. This patch
adds its definition to powerpc hwcap bits.
This patch fixes few failures in nearbyintl() where the fraction part is
close to 0.5.i The new tests added report few extra failures in
nearbyint_downward and nearbyint_towardzero which is a known issue.
Optimization is achieved on 8 byte aligned strings with double word
comparison using cmpb instruction. On unaligned strings loop unrolling
is applied for Power7 gain.
This patch fixes the optimized ppc64/power7 strncat strlen call for
static build without ifunc enabled. The strlen symbol to call in such
situation is just strlen, instead of __GI_strlen (since the __GI_
alias is just created for shared objects).
This patch fixes some powerpc32 and powerpc64 builds with
--disable-multi-arch option along with different --with-cpu=powerN.
It cleanups the Implies directories by removing the multiarch
folder for non multiarch config and also fixing two assembly
implementations: powerpc64/power7/strncat.S that is calling the
wrong strlen; and power8/fpu/s_isnan.S that misses the hidden_def and
weak_alias directives.
This patch fixes a similar issue to 736c304a1ab4cee36a2f3343f1698bc0abae4608, where for PPC32 if the symbol
is defined as hidden (memchr) then compiler will create a local branc
(symbol@local) and the linker will not create a required PLT call to
make the ifunc work. It changes the default hidden symbol (__GI_memchr)
to default memchr symbol for powerpc32 (__memchr_ppc32).
aarch64: Merge __local_multiple_threads offset with memory reference
This also highlights that we'd been loading 64-bits instead of
the proper 32-bits. Caught by the linker as a relocation error,
since the variable happened to be unaligned for 64-bits.
PowerPC: strncpy/stpncpy optimization for PPC64/POWER7
The optimization is achieved by following techniques:
> data alignment [gain from aligned memory access on read/write]
> POWER7 gains performance with loop unrolling/unwinding
[gain by reduction of branch penalty].
> zero padding done by calling optimized memset
This patch changes de default symbol redirection for internal call of
memcpy, memset, memchr, and strlen to the IFUNC resolved ones. The
performance improvement is noticeable in algorithms that uses these
symbols extensible, like the regex functions.
Serge Hallyn [Tue, 11 Mar 2014 04:17:07 +0000 (23:17 -0500)]
misc/sys/xattr.h: guard against linux uapi header inclusion
If the glibc xattr.h header is included after the uapi header,
compilation fails due to an enum re-using a #define from the
uapi header. Protect against this by guarding the define and
enum inclusions against each other.
(A corresponding kernel patch has been sent here:
http://lkml.org/lkml/2014/3/7/331 )
(See https://lists.debian.org/debian-glibc/2014/03/msg00029.html
and https://sourceware.org/glibc/wiki/Synchronizing_Headers
for more information.)