Hello community,
here is the log from the commit of package glibc.5640 for openSUSE:13.2:Update checked in at 2016-10-04 13:04:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:13.2:Update/glibc.5640 (Old)
and /work/SRC/openSUSE:13.2:Update/.glibc.5640.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "glibc.5640"
Changes:
--------
New Changes file:
--- /dev/null 2016-09-15 12:42:18.240042505 +0200
+++ /work/SRC/openSUSE:13.2:Update/.glibc.5640.new/glibc-testsuite.changes 2016-10-04 13:04:43.000000000 +0200
@@ -0,0 +1,7260 @@
+-------------------------------------------------------------------
+Mon Sep 19 10:57:01 UTC 2016 - schwab@suse.de
+
+- aarch64-local-multiple-threads.patch: aarch64: Merge
+ __local_multiple_threads offset with memory reference
+- regcomp-memory-leak.patch: Fix memory leak in regexp compiler (BZ
+ #17069)
+- nscd-netgroup-query-buffer-len.patch: Provide correct buffer length to
+ netgroup queries in nscd (BZ #16695)
+- nscd-netgroup-tryagain.patch: Use NSS_STATUS_TRYAGAIN to indicate
+ insufficient buffer (BZ #16878)
+- aarch64-initial-frame.patch: aarch64: End frame record chain correctly
+ (BZ #17555)
+- io-wstr-overflow-integer-overflow.patch: _IO_wstr_overflow integer
+ overflow (BZ #17269)
+- nscd-netgroup-wildcards.patch: Fix nscd lookup when netgroup has
+ wildcards (BZ #16758, BZ #16759)
+- nscd-netgroup-overlap.patch: Avoid overlapping addresses to stpcpy calls
+ in nscd (BZ #16760)
+- resolv-assertion-failure.patch: resolv: Always set *resplen2 out
+ parameter in send_dg (bsc#994576, BZ #19791)
+- strxfrm-l-memory-handling.patch: Fix memory handling in strxfrm_l (BZ
+ #16009)
+- tls-dtor-list-pointer-mangling.patch: Harden tls_dtor_list with pointer
+ mangling (BZ #19018)
+- open-o-tmpfile-mode.patch: open and openat ignore 'mode' with O_TMPFILE
+ in flags (BZ #17523)
+- arm-startcontext.patch: arm: mark __startcontext as .cantunwind
+ (CVE-2016-6323, bsc#994359, BZ #20435)
+
+-------------------------------------------------------------------
+Tue May 24 14:26:03 UTC 2016 - schwab@suse.de
+
+- glob-altdirfunc.patch: Do not copy d_name field of struct dirent
+ (CVE-2016-1234, bsc#969727, BZ #19779)
+- nss-dns-memleak-2.patch: fix memory leak in _nss_dns_gethostbyname4_r
+ (bsc#973010)
+- nss-dns-getnetbyname.patch: fix stack overflow in
+ _nss_dns_getnetbyname_r (CVE-2016-3075, bsc#973164, BZ #19879)
+- getaddrinfo-hostent-conv-stack-overflow.patch: getaddrinfo stack
+ overflow in hostent conversion (CVE-2016-3706, bsc#980483, BZ #20010)
+- clntudp-call-alloca.patch: do not use alloca in clntudp_call
+ (CVE-2016-4429, bsc#980854, BZ #20112)
+
+-------------------------------------------------------------------
+Tue Feb 16 21:28:29 UTC 2016 - astieger@suse.com
+
+- errorcheck-mutex-no-elision.patch: Don't do lock elision on an error
+ checking mutex (bsc#956716, BZ #17514)
+- reinitialize-dl_load_write_lock.patch: Reinitialize dl_load_write_lock
+ on fork (bsc#958315, BZ #19282)
+- send-dg-buffer-overflow.patch: Fix getaddrinfo stack-based buffer
+ overflow (CVE-2015-7547, bsc#961721, BZ #18665)
+- strftime-range-check.patch: Add range check on time fields
+ (CVE-2015-8776, bsc#962736, BZ #18985)
+- hcreate-overflow-check.patch: Handle overflow in hcreate (CVE-2015-8778,
+ bsc#962737, BZ #18240)
+- refactor-nan-parsing.patch: Refactor strtod parsing of NaN payloads
+ (CVE-2014-9761, bsc#962738, BZ #16962)
+- catopen-unbound-alloca.patch: Fix unbound alloca in catopen
+ (CVE-2015-8779, bsc#962739, BZ #17905)
+
+-------------------------------------------------------------------
+Thu Dec 10 13:54:40 UTC 2015 - schwab@suse.de
+
+- resolv-mem-leak.patch: Fix resource leak in resolver (bsc#955647, BZ
+ #19257)
+- ld-pointer-guard.patch: Always enable pointer guard (bsc#950944, BZ
+ #18928)
+- define-clock-tai.patch: Define CLOCK_TAI on Linux (bsc#936251, BZ
+ #17608)
+
+-------------------------------------------------------------------
+Mon May 11 14:25:52 UTC 2015 - schwab@suse.de
+
+- resolv-nameserver-handling.patch: Simplify handling of nameserver
+ configuration in resolver (bsc#917539)
+- nss-separate-state-getXXent.patch: Separate internal state between
+ getXXent and getXXbyYY NSS calls (CVE-2014-8121, bsc#918187, BZ #18007)
+- fnmatch-read-eos.patch: Fix read past end of pattern in fnmatch
+ (bsc#920338, BZ #17062, BZ #18032, BZ #18036)
+- nss-dns-buffer-overflow.patch: Fix buffer overflow in nss_dns
+ (CVE-2015-1781, bsc#927080, BZ #18287)
+
+-------------------------------------------------------------------
+Mon Feb 9 16:38:08 UTC 2015 - schwab@suse.de
+
+- nss-dns-infinite-loop.patch: Avoid infinite loop in nss_dns getnetbyname
+ (CVE-2014-9402, bsc#910599, BZ #17630)
+- wordexp-wrde-nocmd.patch: wordexp fails to honour WRDE_NOCMD
+ (CVE-2014-7817, bsc#906371, BZ #17625)
+- res-send-fd-reuse.patch: Fix invalid file descriptor reuse while sending
+ DNS query (CVE-2013-7423, bsc#915526, BZ #15946)
+- wscanf-buffer-overflow.patch: Fix buffer overflow in wscanf
+ (CVE-2015-1472, bsc#916222, BZ #16618)
+
+-------------------------------------------------------------------
+Tue Sep 2 07:52:36 UTC 2014 - schwab@suse.de
+
+- iconv-ibm-sentinel-check.patch: Fix crashes on invalid input in IBM
+ gconv modules (CVE-2014-6040, bnc#894553, BZ #17325)
+
+-------------------------------------------------------------------
+Tue Aug 26 10:47:31 UTC 2014 - schwab@suse.de
+
+- disable-gconv-translit-modules.patch: Disable gconv transliteration
+ module loading (CVE-2014-5119, bnc#892073, BZ #17187)
+
+-------------------------------------------------------------------
+Mon Aug 11 10:01:54 UTC 2014 - schwab@suse.de
+
+- pthread-mutexattr-gettype-kind.patch: Filter out
+ PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype
+ (bnc#888131, BZ #15790)
+
+-------------------------------------------------------------------
+Thu Jul 31 08:06:50 UTC 2014 - schwab@suse.de
+
+- ppc64le-profiling.patch: fix profiling for ppc64le (bnc#889601, BZ
+ #17213)
+- s390-revert-abi-change.patch: replace with upstream patch, switches
+ default symbol version back to old version (bnc#887228)
+
+-------------------------------------------------------------------
+Mon Jul 28 10:18:46 UTC 2014 - schwab@suse.de
+
+- ibm93x-redundant-shift-si.patch: Avoid redundant shift character in
+ iconv output at block boundary (bnc#886416, BZ #17197)
+
+-------------------------------------------------------------------
+Thu Jul 24 15:35:50 UTC 2014 - schwab@suse.de
+
+- s390-revert-abi-change.patch: revert back to pre-2.19 layout of jmp_buf
+ and ucontext_t on s390 (bnc#887228)
+
+-------------------------------------------------------------------
+Tue Jul 22 08:37:38 UTC 2014 - schwab@suse.de
+
+- dt-ppc64-num.patch: Correct DT_PPC64_NUM (bnc#887169, BZ #17153)
+
+-------------------------------------------------------------------
+Mon Jul 14 08:33:08 UTC 2014 - schwab@suse.de
+
+- setlocale-directory-traversal.patch: Directory traversal in locale
+ environment handling (CVE-2014-0475, bnc#887022, BZ #17137)
+- Remove the ppc64le check-abi workaround, no longer needed
+
+-------------------------------------------------------------------
+Mon Jun 23 10:33:40 UTC 2014 - schwab@suse.de
+
+- nss-files-long-lines.patch: Don't ignore too long lines in nss_files
+ (bnc#883217, BZ #17079)
+- Remove locale.1, localedef.1 and iconvconfig.8 manpages, now included in
+ the man-pages package (bnc#880703)
+- manpages.patch: update
+
+-------------------------------------------------------------------
+Mon Jun 16 08:27:38 UTC 2014 - schwab@suse.de
+
+- psfaa.patch: copy filename argument in posix_spawn_file_actions_addopen
+ (CVE-2014-4043, bnc#882600, BZ #17048)
+
+-------------------------------------------------------------------
+Wed May 28 15:11:45 UTC 2014 - matz@suse.de
+
+- glibc-memset-nontemporal.diff: Speedup memset on x86_64
+ (bnc#868622, BZ #16830)
+
+-------------------------------------------------------------------
+Thu May 15 15:45:03 UTC 2014 - schwab@suse.de
+
+- add non-elision-enabled libpthread
+
+-------------------------------------------------------------------
+Mon May 12 13:22:40 UTC 2014 - schwab@suse.de
+
+- nss-nis-stack-use.patch: fix unbound stack use in NIS NSS module (BZ
+ #16932)
+
+-------------------------------------------------------------------
+Wed May 7 10:13:24 UTC 2014 - schwab@suse.de
+
+- getaddrinfo-uninit-result.patch: fix parsing of getai result for
+ IPv6-only request (bnc#876521)
+
+-------------------------------------------------------------------
+Thu Apr 17 09:13:32 UTC 2014 - schwab@suse.de
+
+- ibm-long-double-frexpl.patch: Correct IBM long double frexpl
+ (bnc#872573, BZ #16740, BZ #16619)
+
+-------------------------------------------------------------------
+Tue Apr 15 14:23:54 UTC 2014 - schwab@suse.de
+
+- ibm-long-double-math.patch: Remove faulty assembler implementations of
+ ceil, nearbyintl, roundl for IBM long double (bnc#873457, BZ #16701, BZ
+ #16706, BZ #16707)
++++ 7063 more lines (skipped)
++++ between /dev/null
++++ and /work/SRC/openSUSE:13.2:Update/.glibc.5640.new/glibc-testsuite.changes
New Changes file:
glibc-utils.changes: same change
New Changes file:
glibc.changes: same change
New:
----
_constraints
aarch64-initial-frame.patch
aarch64-local-multiple-threads.patch
aarch64-setcontext.patch
abort-no-flush.patch
arm-startcontext.patch
baselibs.conf
bindresvport.blacklist
catopen-unbound-alloca.patch
check-build.sh
check-pf-alloca.patch
clntudp-call-alloca.patch
crypt_blowfish-1.2-hack_around_arm.diff
crypt_blowfish-1.2-sha.diff
crypt_blowfish-1.2.tar.gz
crypt_blowfish-1.2.tar.gz.sign
crypt_blowfish-const.patch
crypt_blowfish-gensalt.patch
define-clock-tai.patch
disable-gconv-translit-modules.patch
dt-ppc64-num.patch
errorcheck-mutex-no-elision.patch
fix-locking-in-_IO_cleanup.patch
fnmatch-read-eos.patch
getaddrinfo-hostent-conv-stack-overflow.patch
getaddrinfo-ipv6-sanity.diff
getaddrinfo-uninit-result.patch
glibc-2.14-crypt.diff
glibc-2.19.tar.xz
glibc-2.2-sunrpc.diff
glibc-2.3.2.no_archive.diff
glibc-2.3.3-nscd-db-path.diff
glibc-2.3.90-langpackdir.diff
glibc-2.3.90-noversion.diff
glibc-2.3.locales.diff.bz2
glibc-2.4-china.diff
glibc-2.4.90-no_NO.diff
glibc-bindresvport-blacklist.diff
glibc-cpusetsize.diff
glibc-fix-double-loopback.diff
glibc-memset-nontemporal.diff
glibc-nodate.patch
glibc-nscd.conf.patch
glibc-resolv-mdnshint.diff
glibc-resolv-reload.diff
glibc-testsuite.changes
glibc-testsuite.patch
glibc-testsuite.spec
glibc-utils.changes
glibc-utils.spec
glibc-version.diff
glibc.changes
glibc.rpmlintrc
glibc.spec
glibc_post_upgrade.c
glob-altdirfunc.patch
hcreate-overflow-check.patch
ibm-long-double-frexpl.patch
ibm-long-double-math.patch
ibm93x-redundant-shift-si.patch
iconv-ibm-sentinel-check.patch
io-wstr-overflow-integer-overflow.patch
ld-pointer-guard.patch
ldd-system-interp.patch
manpages.patch
manpages.tar.bz2
nextafterl-ibm-ldouble.patch
noversion.tar.bz2
nscd-netgroup-overlap.patch
nscd-netgroup-query-buffer-len.patch
nscd-netgroup-tryagain.patch
nscd-netgroup-wildcards.patch
nscd-server-user.patch
nscd-track-startup-failures.patch
nscd.conf
nscd.service
nss-db-path.patch
nss-dns-buffer-overflow.patch
nss-dns-getnetbyname.patch
nss-dns-infinite-loop.patch
nss-dns-memleak-2.patch
nss-dns-memleak.patch
nss-files-long-lines.patch
nss-nis-stack-use.patch
nss-separate-state-getXXent.patch
nsswitch.conf
open-o-tmpfile-mode.patch
pldd-wait-ptrace-stop.patch
powerpc-opt-power8.patch
ppc64-copysign.patch
ppc64le-profiling.patch
pre_checkin.sh
psfaa.patch
pthread-mutex-trylock-elision.patch
pthread-mutexattr-gettype-kind.patch
refactor-nan-parsing.patch
regcomp-memory-leak.patch
reinitialize-dl_load_write_lock.patch
res-send-fd-reuse.patch
resolv-assertion-failure.patch
resolv-dont-ignore-second-answer.patch
resolv-mem-leak.patch
resolv-nameserver-handling.patch
s390-revert-abi-change.patch
send-dg-buffer-overflow.patch
setlocale-directory-traversal.patch
sin-sign.patch
strftime-range-check.patch
strxfrm-l-memory-handling.patch
tls-dtor-list-pointer-mangling.patch
wordexp-wrde-nocmd.patch
wscanf-buffer-overflow.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ glibc-testsuite.spec ++++++
++++ 1491 lines (skipped)
glibc-utils.spec: same change
glibc.spec: same change
++++++ aarch64-initial-frame.patch ++++++
2014-11-11 Renlin Li
[BZ #17555]
* ports/sysdeps/aarch64/start.S (_start): Delete x29 overwritten
assignment.
Index: glibc-2.19/ports/sysdeps/aarch64/start.S
===================================================================
--- glibc-2.19.orig/ports/sysdeps/aarch64/start.S
+++ glibc-2.19/ports/sysdeps/aarch64/start.S
@@ -47,7 +47,6 @@ _start:
/* Create an initial frame with 0 LR and FP */
mov x29, #0
mov x30, #0
- mov x29, sp
/* Setup rtld_fini in argument register */
mov x5, x0
++++++ aarch64-local-multiple-threads.patch ++++++
2014-05-21 Richard Henderson
* sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
(SINGLE_THREAD_P): Use the correct width load. Fold an add
into the ldr offset.
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
@@ -162,9 +162,8 @@ extern int __local_multiple_threads attr
# else
# define SINGLE_THREAD_P \
adrp x16, __local_multiple_threads; \
- add x16, x16, #:lo12:__local_multiple_threads; \
- ldr x16, [x16]; \
- cmp x16, 0;
+ ldr w16, [x16, :lo12:__local_multiple_threads]; \
+ cmp w16, 0;
# endif
# else
/* There is no __local_multiple_threads for librt, so use the TCB. */
@@ -180,12 +179,12 @@ extern int __local_multiple_threads attr
cfi_rel_offset (x30, 8); \
bl __read_tp; \
sub x0, x0, PTHREAD_SIZEOF; \
- ldr x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET]; \
+ ldr w16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET]; \
ldp x0, x30, [sp], 16; \
cfi_restore (x0); \
cfi_restore (x30); \
cfi_adjust_cfa_offset (-16); \
- cmp x16, 0
+ cmp w16, 0
# define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
# endif
# endif
++++++ aarch64-setcontext.patch ++++++
From 4dc40de1ed58a1de5d960e59f20a04191f6820c9 Mon Sep 17 00:00:00 2001
From: Will Newton
Date: Wed, 12 Mar 2014 16:14:51 +0000
Subject: [PATCH 1/3] aarch64: Re-implement setcontext without rt_sigreturn
syscall
The current implementation of setcontext uses rt_sigreturn to restore
the contents of registers. This contrasts with the way most other
architectures implement setcontext:
powerpc64, mips, tile:
Call rt_sigreturn if context was created by a call to a signal handler,
otherwise restore in user code.
powerpc32:
Call swapcontext system call and don't call sigreturn or rt_sigreturn.
x86_64, sparc, hppa, sh, ia64, m68k, s390, arm:
Only support restoring "synchronous" contexts, that is contexts
created by getcontext, and restoring in user code and don't call
sigreturn or rt_sigreturn.
alpha:
Call sigreturn (but not rt_sigreturn) in all cases to do the restore.
The text of the setcontext manpage suggests that the requirement to be
able to restore a signal handler created context has been dropped from
SUSv2:
If the context was obtained by a call to a signal handler, then old
standard text says that "program execution continues with the program
instruction following the instruction interrupted by the signal".
However, this sentence was removed in SUSv2, and the present verdict
is "the result is unspecified".
Implementing setcontext by calling rt_sigreturn unconditionally causes
problems when used with sigaltstack as in BZ #16629. On this basis it
seems that aarch64 is broken and that new ports should only support
restoring contexts created with getcontext and do not need to call
rt_sigreturn at all.
This patch re-implements the aarch64 setcontext function to restore
the context in user code in a similar manner to x86_64 and other ports.
ChangeLog:
2014-03-13 Will Newton
[BZ #16629]
* sysdeps/unix/sysv/linux/aarch64/setcontext.S (__setcontext):
Re-implement to restore registers in user code and avoid
rt_sigreturn system call.
---
sysdeps/unix/sysv/linux/aarch64/setcontext.S | 147 +++++++++++++++++----------
1 file changed, 92 insertions(+), 55 deletions(-)
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S
@@ -22,68 +22,105 @@
#include "ucontext_i.h"
#include "ucontext-internal.h"
-/* int setcontext (const ucontext_t *ucp) */
+/* int __setcontext (const ucontext_t *ucp)
- .text
-
-ENTRY(__setcontext)
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
- /* Create a signal frame on the stack:
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
- fp
- lr
- ...
- sp-> rt_sigframe
- */
-
- stp x29, x30, [sp, -16]!
- cfi_adjust_cfa_offset (16)
- cfi_rel_offset (x29, 0)
- cfi_rel_offset (x30, 8)
-
- mov x29, sp
- cfi_def_cfa_register (x29)
-
- /* Allocate space for the sigcontext. */
- mov w3, #((RT_SIGFRAME_SIZE + SP_ALIGN_SIZE) & SP_ALIGN_MASK)
- sub sp, sp, x3
-
- /* Compute the base address of the ucontext structure. */
- add x1, sp, #RT_SIGFRAME_UCONTEXT
-
- /* Only ucontext is required in the frame, *copy* it in. */
-
-#if UCONTEXT_SIZE % 16
-#error The implementation of setcontext.S assumes sizeof(ucontext_t) % 16 == 0
-#endif
-
- mov x2, #UCONTEXT_SIZE / 16
-0:
- ldp x3, x4, [x0], #16
- stp x3, x4, [x1], #16
- sub x2, x2, 1
- cbnz x2, 0b
+ .text
- /* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe. */
- mov x8, SYS_ify (rt_sigreturn)
+ENTRY (__setcontext)
+ /* Save a copy of UCP. */
+ mov x9, x0
+
+ /* Set the signal mask with
+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
+ mov x0, #SIG_SETMASK
+ add x1, x9, #UCONTEXT_SIGMASK
+ mov x2, #0
+ mov x3, #_NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
svc 0
-
- /* Ooops we failed. Recover the stack */
-
- mov sp, x29
- cfi_def_cfa_register (sp)
-
- ldp x29, x30, [sp], 16
- cfi_adjust_cfa_offset (16)
- cfi_restore (x29)
- cfi_restore (x30)
- b C_SYMBOL_NAME(__syscall_error)
-
+ cbz x0, 1f
+ b C_SYMBOL_NAME (__syscall_error)
+1:
+ /* Restore the general purpose registers. */
+ mov x0, x9
+ cfi_def_cfa (x0, 0)
+ cfi_offset (x18, oX0 + 18 * SZREG)
+ cfi_offset (x19, oX0 + 19 * SZREG)
+ cfi_offset (x20, oX0 + 20 * SZREG)
+ cfi_offset (x21, oX0 + 21 * SZREG)
+ cfi_offset (x22, oX0 + 22 * SZREG)
+ cfi_offset (x23, oX0 + 23 * SZREG)
+ cfi_offset (x24, oX0 + 24 * SZREG)
+ cfi_offset (x25, oX0 + 25 * SZREG)
+ cfi_offset (x26, oX0 + 26 * SZREG)
+ cfi_offset (x27, oX0 + 27 * SZREG)
+ cfi_offset (x28, oX0 + 28 * SZREG)
+ cfi_offset (x29, oX0 + 29 * SZREG)
+ cfi_offset (x30, oX0 + 30 * SZREG)
+
+ cfi_offset ( d8, oV0 + 8 * SZVREG)
+ cfi_offset ( d9, oV0 + 9 * SZVREG)
+ cfi_offset (d10, oV0 + 10 * SZVREG)
+ cfi_offset (d11, oV0 + 11 * SZVREG)
+ cfi_offset (d12, oV0 + 12 * SZVREG)
+ cfi_offset (d13, oV0 + 13 * SZVREG)
+ cfi_offset (d14, oV0 + 14 * SZVREG)
+ cfi_offset (d15, oV0 + 15 * SZVREG)
+ ldp x18, x19, [x0, oX0 + 18 * SZREG]
+ ldp x20, x21, [x0, oX0 + 20 * SZREG]
+ ldp x22, x23, [x0, oX0 + 22 * SZREG]
+ ldp x24, x25, [x0, oX0 + 24 * SZREG]
+ ldp x26, x27, [x0, oX0 + 26 * SZREG]
+ ldp x28, x29, [x0, oX0 + 28 * SZREG]
+ ldr x30, [x0, oX0 + 30 * SZREG]
+ ldr x2, [x0, oSP]
+ mov sp, x2
+
+ /* Check for FP SIMD context. */
+ add x2, x0, #oEXTENSION
+
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ ldr w1, [x2, #oHEAD + oMAGIC]
+ cmp w1, w3
+ b.ne 2f
+
+ /* Restore the FP SIMD context. */
+ add x3, x2, #oV0 + 8 * SZVREG
+ ldp d8, d9, [x3], #2 * SZVREG
+ ldp d10, d11, [x3], #2 * SZVREG
+ ldp d12, d13, [x3], #2 * SZVREG
+ ldp d14, d15, [x3], #2 * SZVREG
+
+ add x3, x2, oFPSR
+
+ ldr w4, [x3]
+ msr fpsr, x4
+
+ ldr w4, [x3, oFPCR - oFPSR]
+ msr fpcr, x4
+
+2:
+ ldr x16, [x0, oPC]
+ /* Restore arg registers. */
+ ldp x2, x3, [x0, oX0 + 2 * SZREG]
+ ldp x4, x5, [x0, oX0 + 4 * SZREG]
+ ldp x6, x7, [x0, oX0 + 6 * SZREG]
+ ldp x0, x1, [x0, oX0 + 0 * SZREG]
+ /* Jump to the new pc value. */
+ br x16
PSEUDO_END (__setcontext)
weak_alias (__setcontext, setcontext)
-ENTRY(__startcontext)
+ENTRY (__startcontext)
mov x0, x19
cbnz x0, __setcontext
-1: b HIDDEN_JUMPTARGET(_exit)
-END(__startcontext)
+1: b HIDDEN_JUMPTARGET (_exit)
+END (__startcontext)
++++++ abort-no-flush.patch ++++++
Don't close or flush stdio streams on abort
[BZ #15436]
* stdlib/abort.c (abort): Don't call fflush and __fcloseall.
Index: glibc-2.19/stdlib/abort.c
===================================================================
--- glibc-2.19.orig/stdlib/abort.c
+++ glibc-2.19/stdlib/abort.c
@@ -30,9 +30,6 @@
# define ABORT_INSTRUCTION
#endif
-#include
-#define fflush(s) _IO_flush_all_lockp (0)
-
/* Exported variable to locate abort message in core files etc. */
struct abort_msg_s *__abort_msg __attribute__ ((nocommon));
libc_hidden_def (__abort_msg)
@@ -66,16 +63,8 @@ abort (void)
__sigprocmask (SIG_UNBLOCK, &sigs, (sigset_t *) NULL);
}
- /* Flush all streams. We cannot close them now because the user
- might have registered a handler for SIGABRT. */
- if (stage == 1)
- {
- ++stage;
- fflush (NULL);
- }
-
/* Send signal which possibly calls a user handler. */
- if (stage == 2)
+ if (stage == 1)
{
/* This stage is special: we must allow repeated calls of
`abort' when a user defined handler for SIGABRT is installed.
@@ -93,7 +82,7 @@ abort (void)
}
/* There was a handler installed. Now remove it. */
- if (stage == 3)
+ if (stage == 2)
{
++stage;
memset (&act, '\0', sizeof (struct sigaction));
@@ -103,30 +92,22 @@ abort (void)
__sigaction (SIGABRT, &act, NULL);
}
- /* Now close the streams which also flushes the output the user
- defined handler might has produced. */
- if (stage == 4)
- {
- ++stage;
- __fcloseall ();
- }
-
/* Try again. */
- if (stage == 5)
+ if (stage == 3)
{
++stage;
raise (SIGABRT);
}
/* Now try to abort using the system specific command. */
- if (stage == 6)
+ if (stage == 4)
{
++stage;
ABORT_INSTRUCTION;
}
/* If we can't signal ourselves and the abort instruction failed, exit. */
- if (stage == 7)
+ if (stage == 5)
{
++stage;
_exit (127);
++++++ arm-startcontext.patch ++++++
2016-08-15 Andreas Schwab
[BZ #20435]
* sysdeps/unix/sysv/linux/arm/setcontext.S (__startcontext): Mark
as .cantunwind.
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/arm/setcontext.S
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/arm/setcontext.S
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/arm/setcontext.S
@@ -86,12 +86,19 @@ weak_alias(__setcontext, setcontext)
/* Called when a makecontext() context returns. Start the
context in R4 or fall through to exit(). */
+ /* Unwind descriptors are looked up based on PC - 2, so we have to
+ make sure to mark the instruction preceding the __startcontext
+ label as .cantunwind. */
+ .fnstart
+ .cantunwind
+ nop
ENTRY(__startcontext)
movs r0, r4
bne PLTJMP(__setcontext)
@ New context was 0 - exit
b PLTJMP(HIDDEN_JUMPTARGET(_exit))
+ .fnend
END(__startcontext)
#ifdef PIC
++++++ baselibs.conf ++++++
glibc
arch i586 block!
targettype x86 +/etc/ld.so.conf
targettype x86 "/lib/ld-linux.so.2 -> <prefix>/lib/ld-linux.so.2"
targettype x86 obsoletes "baselibs-x86"
targettype ia32 +/etc/ld.so.conf
targettype ia32 "/lib/ld-linux.so.2 -> <prefix>/lib/ld-linux.so.2"
prereq -glibc-x86
+/usr/lib/getconf/[^g]
glibc-locale
arch i586 block!
+/usr/lib(64)?/gconv/gconv-modules
targettype x86 -/usr/lib(64)?/gconv/gconv-modules
glibc-devel
requires "glibc-<targettype> = %version"
arch i586 block!
+^/usr/include/gnu/stubs-.*\.h$
glibc-devel-static
arch i586 block!
glibc-profile
arch i586 block!
glibc-utils
++++++ bindresvport.blacklist ++++++
#
# This file contains a list of port numbers between 600 and 1024,
# which should not be used by bindresvport. bindresvport is mostly
# called by RPC services. This mostly solves the problem, that a
# RPC service uses a well known port of another service.
#
623 # ASF, used by IPMI on some cards
631 # cups
636 # ldaps
664 # Secure ASF, used by IPMI on some cards
774 # rpasswd
921 # lwresd
993 # imaps
995 # pops
++++++ catopen-unbound-alloca.patch ++++++
2015-08-08 Paul Pluzhnikov
[BZ #17905]
* catgets/Makefile (tst-catgets-mem): New test.
* catgets/catgets.c (catopen): Don't use unbounded alloca.
* catgets/open_catalog.c (__open_catalog): Likewise.
* catgets/tst-catgets.c (do_bz17905): Test unbounded alloca.
Index: glibc-2.19/catgets/Makefile
===================================================================
--- glibc-2.19.orig/catgets/Makefile
+++ glibc-2.19/catgets/Makefile
@@ -46,13 +46,16 @@ CPPFLAGS-gencat = -DNOT_IN_libc
generated = de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \
test-gencat.h
+generated += tst-catgets.mtrace tst-catgets-mem.out
+
generated-dirs = de
-tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de
+tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace
ifeq ($(run-built-tests),yes)
tests: $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
- $(objpfx)test-gencat.out
+ $(objpfx)test-gencat.out \
+ $(objpfx)tst-catgets-mem.out
# This test just checks whether the program produces any error or not.
# The result is not tested.
$(objpfx)test1.cat: test1.msg $(objpfx)gencat
@@ -80,4 +83,8 @@ $(objpfx)test-gencat.out: test-gencat.sh
$(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat
GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
$(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@
+
+$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \
+ $(evaluate-test)
endif
Index: glibc-2.19/catgets/catgets.c
===================================================================
--- glibc-2.19.orig/catgets/catgets.c
+++ glibc-2.19/catgets/catgets.c
@@ -16,7 +16,6 @@
License along with the GNU C Library; if not, see
http://www.gnu.org/licenses/. */
-#include
#include
#include
#include
@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag)
__nl_catd result;
const char *env_var = NULL;
const char *nlspath = NULL;
+ char *tmp = NULL;
if (strchr (cat_name, '/') == NULL)
{
@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag)
{
/* Append the system dependent directory. */
size_t len = strlen (nlspath) + 1 + sizeof NLSPATH;
- char *tmp = alloca (len);
+ tmp = malloc (len);
+
+ if (__glibc_unlikely (tmp == NULL))
+ return (nl_catd) -1;
__stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
nlspath = tmp;
@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag)
result = (__nl_catd) malloc (sizeof (*result));
if (result == NULL)
- /* We cannot get enough memory. */
- return (nl_catd) -1;
-
- if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
+ {
+ /* We cannot get enough memory. */
+ result = (nl_catd) -1;
+ }
+ else if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
{
/* Couldn't open the file. */
free ((void *) result);
- return (nl_catd) -1;
+ result = (nl_catd) -1;
}
+ free (tmp);
return (nl_catd) result;
}
Index: glibc-2.19/catgets/open_catalog.c
===================================================================
--- glibc-2.19.orig/catgets/open_catalog.c
+++ glibc-2.19/catgets/open_catalog.c
@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, co
size_t tab_size;
const char *lastp;
int result = -1;
+ char *buf = NULL;
if (strchr (cat_name, '/') != NULL || nlspath == NULL)
fd = open_not_cancel_2 (cat_name, O_RDONLY);
@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, co
if (__builtin_expect (bufact + (n) >= bufmax, 0)) \
{ \
char *old_buf = buf; \
- bufmax += 256 + (n); \
- buf = (char *) alloca (bufmax); \
- memcpy (buf, old_buf, bufact); \
+ bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax; \
+ buf = realloc (buf, bufmax); \
+ if (__glibc_unlikely (buf == NULL)) \
+ { \
+ free (old_buf); \
+ return -1; \
+ } \
}
/* The RUN_NLSPATH variable contains a colon separated list of
descriptions where we expect to find catalogs. We have to
recognize certain % substitutions and stop when we found the
first existing file. */
- char *buf;
size_t bufact;
- size_t bufmax;
+ size_t bufmax = 0;
size_t len;
- buf = NULL;
- bufmax = 0;
-
fd = -1;
while (*run_nlspath != '\0')
{
@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, co
/* Avoid dealing with directories and block devices */
if (__builtin_expect (fd, 0) < 0)
- return -1;
+ {
+ free (buf);
+ return -1;
+ }
if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0)
goto close_unlock_return;
@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, co
/* Release the lock again. */
close_unlock_return:
close_not_cancel_no_status (fd);
+ free (buf);
return result;
}
Index: glibc-2.19/catgets/tst-catgets.c
===================================================================
--- glibc-2.19.orig/catgets/tst-catgets.c
+++ glibc-2.19/catgets/tst-catgets.c
@@ -1,7 +1,10 @@
+#include
#include
#include
#include
+#include
#include
+#include
static const char *msgs[] =
@@ -12,6 +15,33 @@ static const char *msgs[] =
};
#define nmsgs (sizeof (msgs) / sizeof (msgs[0]))
+
+/* Test for unbounded alloca. */
+static int
+do_bz17905 (void)
+{
+ char *buf;
+ struct rlimit rl;
+ nl_catd result;
+
+ const int sz = 1024 * 1024;
+
+ getrlimit (RLIMIT_STACK, &rl);
+ rl.rlim_cur = sz;
+ setrlimit (RLIMIT_STACK, &rl);
+
+ buf = malloc (sz + 1);
+ memset (buf, 'A', sz);
+ buf[sz] = '\0';
+ setenv ("NLSPATH", buf, 1);
+
+ result = catopen (buf, NL_CAT_LOCALE);
+ assert (result == (nl_catd) -1);
+
+ free (buf);
+ return 0;
+}
+
#define ROUNDS 5
int
@@ -62,5 +92,6 @@ main (void)
}
}
+ result += do_bz17905 ();
return result;
}
++++++ check-build.sh ++++++
#!/bin/bash
# Copyright (c) 2003, 2004, 2011,2012 SUSE Linux Products GmbH, Germany. All rights reserved.
#
# Authors: Thorsten Kukuk
#
if [ `nice` -gt '9' ] ; then
echo "Don't modify nice for building glibc!"
exit 1
fi
# get kernel version
OFS="$IFS" ; IFS=".-" ; version=(`uname -r`) ; IFS="$OIFS"
ARCH=(`uname -m`)
if test ${version[0]} -gt 2 ; then
: # okay
elif test ${version[0]} -lt 2 -o ${version[1]} -lt 6 -o ${version[2]} -lt 16 ; then
echo "FATAL: kernel too old, need kernel >= 2.6.16 for this package" 1>&2
exit 1
elif $ARCH -eq 'x86_64' ; then
if test ${version[0]} -lt 2 -o ${version[1]} -lt 6 -o ${version[2]} -lt 32 ; then
echo "FATAL: kernel too old, need kernel >= 2.6.32 for this package" 1>&2
exit 1
fi
fi
exit 0
++++++ check-pf-alloca.patch ++++++
* sysdeps/unix/sysv/linux/check_pf.c (make_request): Add out_fail2
label to be used after in6ailist is initialized.
[BZ #16002]
* sysdeps/unix/sysv/linux/check_pf.c (make_request): Use
alloca_account and account alloca use for struct in6ailist.
Index: glibc-2.19/sysdeps/unix/sysv/linux/check_pf.c
===================================================================
--- glibc-2.19.orig/sysdeps/unix/sysv/linux/check_pf.c
+++ glibc-2.19/sysdeps/unix/sysv/linux/check_pf.c
@@ -106,6 +106,11 @@ cache_valid_p (void)
static struct cached_data *
make_request (int fd, pid_t pid)
{
+ struct cached_data *result = NULL;
+
+ size_t result_len = 0;
+ size_t result_cap = 32;
+
struct req
{
struct nlmsghdr nlh;
@@ -137,19 +142,9 @@ make_request (int fd, pid_t pid)
#else
const size_t buf_size = __getpagesize ();
#endif
- bool use_malloc = false;
char *buf;
- if (__libc_use_alloca (buf_size))
- buf = alloca (buf_size);
- else
- {
- buf = malloc (buf_size);
- if (buf != NULL)
- use_malloc = true;
- else
- goto out_fail;
- }
+ buf = alloca (buf_size);
struct iovec iov = { buf, buf_size };
@@ -159,12 +154,7 @@ make_request (int fd, pid_t pid)
goto out_fail;
bool done = false;
- struct in6ailist
- {
- struct in6addrinfo info;
- struct in6ailist *next;
- } *in6ailist = NULL;
- size_t in6ailistlen = 0;
+
bool seen_ipv4 = false;
bool seen_ipv6 = false;
@@ -239,28 +229,36 @@ make_request (int fd, pid_t pid)
}
}
- struct in6ailist *newp = alloca (sizeof (*newp));
- newp->info.flags = (((ifam->ifa_flags
- & (IFA_F_DEPRECATED
- | IFA_F_OPTIMISTIC))
- ? in6ai_deprecated : 0)
- | ((ifam->ifa_flags
- & IFA_F_HOMEADDRESS)
- ? in6ai_homeaddress : 0));
- newp->info.prefixlen = ifam->ifa_prefixlen;
- newp->info.index = ifam->ifa_index;
+ if (result_len == 0 || result_len == result_cap)
+ {
+ result_cap = 2 * result_cap;
+ result = realloc (result, sizeof (*result)
+ + result_cap * sizeof (struct in6addrinfo));
+ }
+
+ if (!result)
+ goto out_fail;
+
+ struct in6addrinfo *info = &result->in6ai[result_len++];
+
+ info->flags = (((ifam->ifa_flags
+ & (IFA_F_DEPRECATED
+ | IFA_F_OPTIMISTIC))
+ ? in6ai_deprecated : 0)
+ | ((ifam->ifa_flags
+ & IFA_F_HOMEADDRESS)
+ ? in6ai_homeaddress : 0));
+ info->prefixlen = ifam->ifa_prefixlen;
+ info->index = ifam->ifa_index;
if (ifam->ifa_family == AF_INET)
{
- newp->info.addr[0] = 0;
- newp->info.addr[1] = 0;
- newp->info.addr[2] = htonl (0xffff);
- newp->info.addr[3] = *(const in_addr_t *) address;
+ info->addr[0] = 0;
+ info->addr[1] = 0;
+ info->addr[2] = htonl (0xffff);
+ info->addr[3] = *(const in_addr_t *) address;
}
else
- memcpy (newp->info.addr, address, sizeof (newp->info.addr));
- newp->next = in6ailist;
- in6ailist = newp;
- ++in6ailistlen;
+ memcpy (info->addr, address, sizeof (info->addr));
}
else if (nlmh->nlmsg_type == NLMSG_DONE)
/* We found the end, leave the loop. */
@@ -269,42 +267,29 @@ make_request (int fd, pid_t pid)
}
while (! done);
- struct cached_data *result;
- if (seen_ipv6 && in6ailist != NULL)
+ if (seen_ipv6 && result != NULL)
{
- result = malloc (sizeof (*result)
- + in6ailistlen * sizeof (struct in6addrinfo));
- if (result == NULL)
- goto out_fail;
-
result->timestamp = get_nl_timestamp ();
result->usecnt = 2;
result->seen_ipv4 = seen_ipv4;
result->seen_ipv6 = true;
- result->in6ailen = in6ailistlen;
-
- do
- {
- result->in6ai[--in6ailistlen] = in6ailist->info;
- in6ailist = in6ailist->next;
- }
- while (in6ailist != NULL);
+ result->in6ailen = result_len;
}
else
{
+ free (result);
+
atomic_add (&noai6ai_cached.usecnt, 2);
noai6ai_cached.seen_ipv4 = seen_ipv4;
noai6ai_cached.seen_ipv6 = seen_ipv6;
result = &noai6ai_cached;
}
- if (use_malloc)
- free (buf);
return result;
-out_fail:
- if (use_malloc)
- free (buf);
+ out_fail:
+
+ free (result);
return NULL;
}
++++++ clntudp-call-alloca.patch ++++++
2016-05-23 Florian Weimer
CVE-2016-4429
[BZ #20112]
* sunrpc/clnt_udp.c (clntudp_call): Use malloc/free for the error
payload.
Index: glibc-2.19/sunrpc/clnt_udp.c
===================================================================
--- glibc-2.19.orig/sunrpc/clnt_udp.c
+++ glibc-2.19/sunrpc/clnt_udp.c
@@ -420,9 +420,15 @@ send_again:
struct sock_extended_err *e;
struct sockaddr_in err_addr;
struct iovec iov;
- char *cbuf = (char *) alloca (outlen + 256);
+ char *cbuf = malloc (outlen + 256);
int ret;
+ if (cbuf == NULL)
+ {
+ cu->cu_error.re_errno = errno;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
iov.iov_base = cbuf + 256;
iov.iov_len = outlen;
msg.msg_name = (void *) &err_addr;
@@ -447,10 +453,12 @@ send_again:
cmsg = CMSG_NXTHDR (&msg, cmsg))
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
{
+ free (cbuf);
e = (struct sock_extended_err *) CMSG_DATA(cmsg);
cu->cu_error.re_errno = e->ee_errno;
return (cu->cu_error.re_status = RPC_CANTRECV);
}
+ free (cbuf);
}
#endif
do
++++++ crypt_blowfish-1.2-hack_around_arm.diff ++++++
--- x86.S
+++ x86.S
@@ -199,5 +199,5 @@
#endif
#if defined(__ELF__) && defined(__linux__)
-.section .note.GNU-stack,"",@progbits
+.section .note.GNU-stack,"",%progbits
#endif
++++++ crypt_blowfish-1.2-sha.diff ++++++
From 1c581a8364ab18a6938f3153d7bea793d06a4652 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel
Date: Thu, 25 Aug 2011 14:00:38 +0200
Subject: [PATCH crypt_blowfish] support for sha256 and sha512
---
crypt.3 | 14 +++++++++++++
crypt_gensalt.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
wrapper.c | 23 +++++++++++++++++++++
3 files changed, 95 insertions(+), 0 deletions(-)
Index: crypt_blowfish-1.2/crypt.3
===================================================================
--- crypt_blowfish-1.2.orig/crypt.3
+++ crypt_blowfish-1.2/crypt.3
@@ -399,6 +399,20 @@ too low for the currently available hard
.hash "$1$" "\e$1\e$[^$]{1,8}\e$[./0-9A-Za-z]{22}" unlimited 8 "" 128 "6 to 48" 1000
.PP
.ti -2
+.B SHA256 based
+.br
+This is Ulrich Drepper's SHA256-based password hashing method originally
+developed for Linux.
+.hash "$5$" "\e$5\e$(rounds=[0-9]{1,9}\e$)?([./0-9A-Za-z]{1,16})?\e$[./0-9A-Za-z]{43}" unlimited 8 "" 256 "0 to 96" "1000 to 999999999 (default 5000)"
+.PP
+.ti -2
+.B SHA512 based
+.br
+This is Ulrich Drepper's SHA512-based password hashing method originally
+developed for Linux.
+.hash "$6$" "\e$6\e$(rounds=[0-9]{1,9}\e$)?([./0-9A-Za-z]{1,16})?\e$[./0-9A-Za-z]{86}" unlimited 8 "" 512 "0 to 96" "1000 to 999999999 (default 5000)"
+.PP
+.ti -2
.BR "OpenBSD-style Blowfish-based" " (" bcrypt )
.br
.B bcrypt
Index: crypt_blowfish-1.2/crypt_gensalt.c
===================================================================
--- crypt_blowfish-1.2.orig/crypt_gensalt.c
+++ crypt_blowfish-1.2/crypt_gensalt.c
@@ -19,6 +19,7 @@
*/
#include
+#include
#include
#ifndef __set_errno
@@ -122,3 +123,60 @@ char *_crypt_gensalt_md5_rn(const char *
return output;
}
+
+#define SHA2_SALT_LEN_MAX 16
+#define SHA2_ROUNDS_MIN 1000
+#define SHA2_ROUNDS_MAX 999999999
+char *_crypt_gensalt_sha2_rn (const char *prefix, unsigned long count,
+ const char *input, int size, char *output, int output_size)
+
+{
+ char *o = output;
+ const char *i = input;
+ unsigned needed = 3 + MIN(size/3*4, SHA2_SALT_LEN_MAX) + 1;
+
+ if (size < 3 || output_size < needed)
+ goto error;
+
+ size = MIN(size, SHA2_SALT_LEN_MAX/4*3);
+
+ o[0] = prefix[0];
+ o[1] = prefix[1];
+ o[2] = prefix[2];
+ o += 3;
+
+ if (count) {
+ count = MAX(SHA2_ROUNDS_MIN, MIN(count, SHA2_ROUNDS_MAX));
+ int n = snprintf (o, output_size-3, "rounds=%ld$", count);
+ if (n < 0 || n >= output_size-3)
+ goto error;
+ needed += n;
+ o += n;
+ }
+
+ if (output_size < needed)
+ goto error;
+
+ while (size >= 3) {
+ unsigned long value =
+ (unsigned long)(unsigned char)i[0] |
+ ((unsigned long)(unsigned char)i[1] << 8) |
+ ((unsigned long)(unsigned char)i[2] << 16);
+ o[0] = _crypt_itoa64[value & 0x3f];
+ o[1] = _crypt_itoa64[(value >> 6) & 0x3f];
+ o[2] = _crypt_itoa64[(value >> 12) & 0x3f];
+ o[3] = _crypt_itoa64[(value >> 18) & 0x3f];
+ size -= 3;
+ i += 3;
+ o += 3;
+ }
+ o[0] = '\0';
+
+ return output;
+
+error:
+ if (output_size > 0)
+ output[0] = '\0';
+ errno = ENOMEM;
+ return NULL;
+}
Index: crypt_blowfish-1.2/crypt_gensalt.h
===================================================================
--- crypt_blowfish-1.2.orig/crypt_gensalt.h
+++ crypt_blowfish-1.2/crypt_gensalt.h
@@ -26,5 +26,7 @@ extern char *_crypt_gensalt_extended_rn(
const char *input, int size, char *output, int output_size);
extern char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
const char *input, int size, char *output, int output_size);
+extern char *_crypt_gensalt_sha2_rn(const char *prefix, unsigned long count,
+ const char *input, int size, char *output, int output_size);
#endif
Index: crypt_blowfish-1.2/wrapper.c
===================================================================
--- crypt_blowfish-1.2.orig/wrapper.c
+++ crypt_blowfish-1.2/wrapper.c
@@ -50,6 +50,10 @@
#include "crypt.h"
extern char *__md5_crypt_r(const char *key, const char *salt,
char *buffer, int buflen);
+extern char *__sha256_crypt_r (const char *key, const char *salt,
+ char *buffer, int buflen);
+extern char *__sha512_crypt_r (const char *key, const char *salt,
+ char *buffer, int buflen);
/* crypt-entry.c needs to be patched to define __des_crypt_r rather than
* __crypt_r, and not define crypt_r and crypt at all */
extern char *__des_crypt_r(const char *key, const char *salt,
@@ -112,6 +116,10 @@ static char *_crypt_retval_magic(char *r
char *__crypt_rn(__const char *key, __const char *setting,
void *data, int size)
{
+ if (setting[0] == '$' && setting[1] == '6')
+ return __sha512_crypt_r(key, setting, (char *)data, size);
+ if (setting[0] == '$' && setting[1] == '5')
+ return __sha256_crypt_r(key, setting, (char *)data, size);
if (setting[0] == '$' && setting[1] == '2')
return _crypt_blowfish_rn(key, setting, (char *)data, size);
if (setting[0] == '$' && setting[1] == '1')
@@ -129,6 +137,16 @@ char *__crypt_rn(__const char *key, __co
char *__crypt_ra(__const char *key, __const char *setting,
void **data, int *size)
{
+ if (setting[0] == '$' && setting[1] == '6') {
+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
+ return NULL;
+ return __sha512_crypt_r(key, setting, (char *)*data, *size);
+ }
+ if (setting[0] == '$' && setting[1] == '5') {
+ if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
+ return NULL;
+ return __sha256_crypt_r(key, setting, (char *)*data, *size);
+ }
if (setting[0] == '$' && setting[1] == '2') {
if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
return NULL;
@@ -210,6 +228,9 @@ char *__crypt_gensalt_rn(const char *pre
return NULL;
}
+ if (!strncmp(prefix, "$5$", 3) || !strncmp(prefix, "$6$", 3))
+ use = _crypt_gensalt_sha2_rn;
+ else
if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2y$", 4))
use = _crypt_gensalt_blowfish_rn;
else
++++++ crypt_blowfish-const.patch ++++++
Index: crypt_blowfish-1.2/crypt_blowfish.c
===================================================================
--- crypt_blowfish-1.2.orig/crypt_blowfish.c
+++ crypt_blowfish-1.2/crypt_blowfish.c
@@ -81,7 +81,7 @@ typedef struct {
* Magic IV for 64 Blowfish encryptions that we do at the end.
* The string is "OrpheanBeholderScryDoubt" on big-endian.
*/
-static BF_word BF_magic_w[6] = {
+static const BF_word BF_magic_w[6] = {
0x4F727068, 0x65616E42, 0x65686F6C,
0x64657253, 0x63727944, 0x6F756274
};
@@ -89,7 +89,7 @@ static BF_word BF_magic_w[6] = {
/*
* P-box and S-box tables initialized with digits of Pi.
*/
-static BF_ctx BF_init_state = {
+static const BF_ctx BF_init_state = {
{
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
@@ -361,10 +361,10 @@ static BF_ctx BF_init_state = {
}
};
-static unsigned char BF_itoa64[64 + 1] =
+static const unsigned char BF_itoa64[64 + 1] =
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-static unsigned char BF_atoi64[0x60] = {
+static const unsigned char BF_atoi64[0x60] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
@@ -440,8 +440,8 @@ static void BF_encode(char *dst, const B
static void BF_swap(BF_word *x, int count)
{
- static int endianness_check = 1;
- char *is_little_endian = (char *)&endianness_check;
+ static const int endianness_check = 1;
+ const char *is_little_endian = (const char *)&endianness_check;
BF_word tmp;
if (*is_little_endian)
++++++ crypt_blowfish-gensalt.patch ++++++
Index: crypt_blowfish-1.2/crypt_blowfish.c
===================================================================
--- crypt_blowfish-1.2.orig/crypt_blowfish.c
+++ crypt_blowfish-1.2/crypt_blowfish.c
@@ -872,31 +872,3 @@ char *_crypt_blowfish_rn(const char *key
__set_errno(EINVAL); /* pretend we don't support this hash type */
return NULL;
}
-
-char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
- const char *input, int size, char *output, int output_size)
-{
- if (size < 16 || output_size < 7 + 22 + 1 ||
- (count && (count < 4 || count > 31)) ||
- prefix[0] != '$' || prefix[1] != '2' ||
- (prefix[2] != 'a' && prefix[2] != 'y')) {
- if (output_size > 0) output[0] = '\0';
- __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
- return NULL;
- }
-
- if (!count) count = 5;
-
- output[0] = '$';
- output[1] = '2';
- output[2] = prefix[2];
- output[3] = '$';
- output[4] = '0' + count / 10;
- output[5] = '0' + count % 10;
- output[6] = '$';
-
- BF_encode(&output[7], (const BF_word *)input, 16);
- output[7 + 22] = '\0';
-
- return output;
-}
Index: crypt_blowfish-1.2/crypt_blowfish.h
===================================================================
--- crypt_blowfish-1.2.orig/crypt_blowfish.h
+++ crypt_blowfish-1.2/crypt_blowfish.h
@@ -20,8 +20,5 @@
extern int _crypt_output_magic(const char *setting, char *output, int size);
extern char *_crypt_blowfish_rn(const char *key, const char *setting,
char *output, int size);
-extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
- unsigned long count,
- const char *input, int size, char *output, int output_size);
#endif
Index: crypt_blowfish-1.2/crypt_gensalt.c
===================================================================
--- crypt_blowfish-1.2.orig/crypt_gensalt.c
+++ crypt_blowfish-1.2/crypt_gensalt.c
@@ -180,3 +180,69 @@ error:
errno = ENOMEM;
return NULL;
}
+
+
+typedef unsigned int BF_word;
+
+static const unsigned char BF_itoa64[64 + 1] =
+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static void BF_encode(char *dst, const BF_word *src, int size)
+{
+ const unsigned char *sptr = (const unsigned char *)src;
+ const unsigned char *end = sptr + size;
+ unsigned char *dptr = (unsigned char *)dst;
+ unsigned int c1, c2;
+
+ do {
+ c1 = *sptr++;
+ *dptr++ = BF_itoa64[c1 >> 2];
+ c1 = (c1 & 0x03) << 4;
+ if (sptr >= end) {
+ *dptr++ = BF_itoa64[c1];
+ break;
+ }
+
+ c2 = *sptr++;
+ c1 |= c2 >> 4;
+ *dptr++ = BF_itoa64[c1];
+ c1 = (c2 & 0x0f) << 2;
+ if (sptr >= end) {
+ *dptr++ = BF_itoa64[c1];
+ break;
+ }
+
+ c2 = *sptr++;
+ c1 |= c2 >> 6;
+ *dptr++ = BF_itoa64[c1];
+ *dptr++ = BF_itoa64[c2 & 0x3f];
+ } while (sptr < end);
+}
+
+char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
+ const char *input, int size, char *output, int output_size)
+{
+ if (size < 16 || output_size < 7 + 22 + 1 ||
+ (count && (count < 4 || count > 31)) ||
+ prefix[0] != '$' || prefix[1] != '2' ||
+ (prefix[2] != 'a' && prefix[2] != 'y')) {
+ if (output_size > 0) output[0] = '\0';
+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
+ return NULL;
+ }
+
+ if (!count) count = 5;
+
+ output[0] = '$';
+ output[1] = '2';
+ output[2] = prefix[2];
+ output[3] = '$';
+ output[4] = '0' + count / 10;
+ output[5] = '0' + count % 10;
+ output[6] = '$';
+
+ BF_encode(&output[7], (const BF_word *)input, 16);
+ output[7 + 22] = '\0';
+
+ return output;
+}
Index: crypt_blowfish-1.2/crypt_gensalt.h
===================================================================
--- crypt_blowfish-1.2.orig/crypt_gensalt.h
+++ crypt_blowfish-1.2/crypt_gensalt.h
@@ -28,5 +28,8 @@ extern char *_crypt_gensalt_md5_rn(const
const char *input, int size, char *output, int output_size);
extern char *_crypt_gensalt_sha2_rn(const char *prefix, unsigned long count,
const char *input, int size, char *output, int output_size);
+extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
+ unsigned long count,
+ const char *input, int size, char *output, int output_size);
#endif
Index: crypt_blowfish-1.2/wrapper-gensalt.c
===================================================================
--- /dev/null
+++ crypt_blowfish-1.2/wrapper-gensalt.c
@@ -0,0 +1,113 @@
+/*
+ * Written by Solar Designer <solar at openwall.com> in 2000-2011.
+ * No copyright is claimed, and the software is hereby placed in the public
+ * domain. In case this attempt to disclaim copyright and place the software
+ * in the public domain is deemed null and void, then the software is
+ * Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See crypt_blowfish.c for more information.
+ */
+
+#include
+#include
+
+#include
+#ifndef __set_errno
+#define __set_errno(val) errno = (val)
+#endif
+
+#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1)
+
+#if defined(__GLIBC__) && defined(_LIBC)
+#define __SKIP_GNU
+#endif
+#include "ow-crypt.h"
+
+#include "crypt_gensalt.h"
+
+#if !(defined(__GLIBC__) && defined(_LIBC))
+#define __crypt_gensalt_rn crypt_gensalt_rn
+#define __crypt_gensalt_ra crypt_gensalt_ra
+#define __crypt_gensalt crypt_gensalt
+#endif
+
+char *__crypt_gensalt_rn(const char *prefix, unsigned long count,
+ const char *input, int size, char *output, int output_size)
+{
+ char *(*use)(const char *_prefix, unsigned long _count,
+ const char *_input, int _size,
+ char *_output, int _output_size);
+
+ /* This may be supported on some platforms in the future */
+ if (!input) {
+ __set_errno(EINVAL);
+ return NULL;
+ }
+
+ if (!strncmp(prefix, "$5$", 3) || !strncmp(prefix, "$6$", 3))
+ use = _crypt_gensalt_sha2_rn;
+ else
+ if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2y$", 4))
+ use = _crypt_gensalt_blowfish_rn;
+ else
+ if (!strncmp(prefix, "$1$", 3))
+ use = _crypt_gensalt_md5_rn;
+ else
+ if (prefix[0] == '_')
+ use = _crypt_gensalt_extended_rn;
+ else
+ if (!prefix[0] ||
+ (prefix[0] && prefix[1] &&
+ memchr(_crypt_itoa64, prefix[0], 64) &&
+ memchr(_crypt_itoa64, prefix[1], 64)))
+ use = _crypt_gensalt_traditional_rn;
+ else {
+ __set_errno(EINVAL);
+ return NULL;
+ }
+
+ return use(prefix, count, input, size, output, output_size);
+}
+
+char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
+ const char *input, int size)
+{
+ char output[CRYPT_GENSALT_OUTPUT_SIZE];
+ char *retval;
+
+ retval = __crypt_gensalt_rn(prefix, count,
+ input, size, output, sizeof(output));
+
+ if (retval) {
+ retval = strdup(retval);
+#ifndef __GLIBC__
+ /* strdup(3) on glibc sets errno, so we don't need to bother */
+ if (!retval)
+ __set_errno(ENOMEM);
+#endif
+ }
+
+ return retval;
+}
+
+char *__crypt_gensalt(const char *prefix, unsigned long count,
+ const char *input, int size)
+{
+ static char output[CRYPT_GENSALT_OUTPUT_SIZE];
+
+ return __crypt_gensalt_rn(prefix, count,
+ input, size, output, sizeof(output));
+}
+
+#if defined(__GLIBC__) && defined(_LIBC)
+weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn)
+weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra)
+weak_alias(__crypt_gensalt, crypt_gensalt)
+#endif
+
Index: crypt_blowfish-1.2/wrapper.c
===================================================================
--- crypt_blowfish-1.2.orig/wrapper.c
+++ crypt_blowfish-1.2/wrapper.c
@@ -35,7 +35,6 @@
#endif
#define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1)
-#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1)
#if defined(__GLIBC__) && defined(_LIBC)
#define __SKIP_GNU
@@ -43,7 +42,6 @@
#include "ow-crypt.h"
#include "crypt_blowfish.h"
-#include "crypt_gensalt.h"
#if defined(__GLIBC__) && defined(_LIBC)
/* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */
@@ -209,88 +207,11 @@ char *crypt(const char *key, const char
crypt_rn(key, setting, output, sizeof(output)),
setting, output, sizeof(output));
}
-
-#define __crypt_gensalt_rn crypt_gensalt_rn
-#define __crypt_gensalt_ra crypt_gensalt_ra
-#define __crypt_gensalt crypt_gensalt
-#endif
-
-char *__crypt_gensalt_rn(const char *prefix, unsigned long count,
- const char *input, int size, char *output, int output_size)
-{
- char *(*use)(const char *_prefix, unsigned long _count,
- const char *_input, int _size,
- char *_output, int _output_size);
-
- /* This may be supported on some platforms in the future */
- if (!input) {
- __set_errno(EINVAL);
- return NULL;
- }
-
- if (!strncmp(prefix, "$5$", 3) || !strncmp(prefix, "$6$", 3))
- use = _crypt_gensalt_sha2_rn;
- else
- if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2y$", 4))
- use = _crypt_gensalt_blowfish_rn;
- else
- if (!strncmp(prefix, "$1$", 3))
- use = _crypt_gensalt_md5_rn;
- else
- if (prefix[0] == '_')
- use = _crypt_gensalt_extended_rn;
- else
- if (!prefix[0] ||
- (prefix[0] && prefix[1] &&
- memchr(_crypt_itoa64, prefix[0], 64) &&
- memchr(_crypt_itoa64, prefix[1], 64)))
- use = _crypt_gensalt_traditional_rn;
- else {
- __set_errno(EINVAL);
- return NULL;
- }
-
- return use(prefix, count, input, size, output, output_size);
-}
-
-char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
- const char *input, int size)
-{
- char output[CRYPT_GENSALT_OUTPUT_SIZE];
- char *retval;
-
- retval = __crypt_gensalt_rn(prefix, count,
- input, size, output, sizeof(output));
-
- if (retval) {
- retval = strdup(retval);
-#ifndef __GLIBC__
- /* strdup(3) on glibc sets errno, so we don't need to bother */
- if (!retval)
- __set_errno(ENOMEM);
#endif
- }
-
- return retval;
-}
-
-char *__crypt_gensalt(const char *prefix, unsigned long count,
- const char *input, int size)
-{
- static char output[CRYPT_GENSALT_OUTPUT_SIZE];
-
- return __crypt_gensalt_rn(prefix, count,
- input, size, output, sizeof(output));
-}
#if defined(__GLIBC__) && defined(_LIBC)
-weak_alias(__crypt_rn, crypt_rn)
-weak_alias(__crypt_ra, crypt_ra)
weak_alias(__crypt_r, crypt_r)
weak_alias(__crypt, crypt)
-weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn)
-weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra)
-weak_alias(__crypt_gensalt, crypt_gensalt)
weak_alias(crypt, fcrypt)
#endif
++++++ define-clock-tai.patch ++++++
2014-11-24 Ryan Cumming
[BZ #17608]
* sysdeps/unix/sysv/linux/bits/time.h: Define CLOCK_TAI.
Index: glibc-2.19/sysdeps/unix/sysv/linux/bits/time.h
===================================================================
--- glibc-2.19.orig/sysdeps/unix/sysv/linux/bits/time.h
+++ glibc-2.19/sysdeps/unix/sysv/linux/bits/time.h
@@ -77,6 +77,8 @@ extern long int __sysconf (int);
# define CLOCK_REALTIME_ALARM 8
/* Like CLOCK_BOOTTIME but also wakes suspended system. */
# define CLOCK_BOOTTIME_ALARM 9
+/* Like CLOCK_REALTIME but in International Atomic Time. */
+# define CLOCK_TAI 11
/* Flag to indicate time is absolute. */
# define TIMER_ABSTIME 1
++++++ disable-gconv-translit-modules.patch ++++++
2014-08-21 Florian Weimer
[BZ #17187]
* iconv/gconv_trans.c (struct known_trans, search_tree, lock,
trans_compare, open_translit, __gconv_translit_find):
Remove module loading code.
Index: glibc-2.19/iconv/gconv_trans.c
===================================================================
--- glibc-2.19.orig/iconv/gconv_trans.c
+++ glibc-2.19/iconv/gconv_trans.c
@@ -238,181 +238,11 @@ __gconv_transliterate (struct __gconv_st
return __GCONV_ILLEGAL_INPUT;
}
-
-/* Structure to represent results of found (or not) transliteration
- modules. */
-struct known_trans
-{
- /* This structure must remain the first member. */
- struct trans_struct info;
-
- char *fname;
- void *handle;
- int open_count;
-};
-
-
-/* Tree with results of previous calls to __gconv_translit_find. */
-static void *search_tree;
-
-/* We modify global data. */
-__libc_lock_define_initialized (static, lock);
-
-
-/* Compare two transliteration entries. */
-static int
-trans_compare (const void *p1, const void *p2)
-{
- const struct known_trans *s1 = (const struct known_trans *) p1;
- const struct known_trans *s2 = (const struct known_trans *) p2;
-
- return strcmp (s1->info.name, s2->info.name);
-}
-
-
-/* Open (maybe reopen) the module named in the struct. Get the function
- and data structure pointers we need. */
-static int
-open_translit (struct known_trans *trans)
-{
- __gconv_trans_query_fct queryfct;
-
- trans->handle = __libc_dlopen (trans->fname);
- if (trans->handle == NULL)
- /* Not available. */
- return 1;
-
- /* Find the required symbol. */
- queryfct = __libc_dlsym (trans->handle, "gconv_trans_context");
- if (queryfct == NULL)
- {
- /* We cannot live with that. */
- close_and_out:
- __libc_dlclose (trans->handle);
- trans->handle = NULL;
- return 1;
- }
-
- /* Get the context. */
- if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames)
- != 0)
- goto close_and_out;
-
- /* Of course we also have to have the actual function. */
- trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans");
- if (trans->info.trans_fct == NULL)
- goto close_and_out;
-
- /* Now the optional functions. */
- trans->info.trans_init_fct =
- __libc_dlsym (trans->handle, "gconv_trans_init");
- trans->info.trans_context_fct =
- __libc_dlsym (trans->handle, "gconv_trans_context");
- trans->info.trans_end_fct =
- __libc_dlsym (trans->handle, "gconv_trans_end");
-
- trans->open_count = 1;
-
- return 0;
-}
-
-
int
internal_function
__gconv_translit_find (struct trans_struct *trans)
{
- struct known_trans **found;
- const struct path_elem *runp;
- int res = 1;
-
- /* We have to have a name. */
- assert (trans->name != NULL);
-
- /* Acquire the lock. */
- __libc_lock_lock (lock);
-
- /* See whether we know this module already. */
- found = __tfind (trans, &search_tree, trans_compare);
- if (found != NULL)
- {
- /* Is this module available? */
- if ((*found)->handle != NULL)
- {
- /* Maybe we have to reopen the file. */
- if ((*found)->handle != (void *) -1)
- /* The object is not unloaded. */
- res = 0;
- else if (open_translit (*found) == 0)
- {
- /* Copy the data. */
- *trans = (*found)->info;
- (*found)->open_count++;
- res = 0;
- }
- }
- }
- else
- {
- size_t name_len = strlen (trans->name) + 1;
- int need_so = 0;
- struct known_trans *newp;
-
- /* We have to continue looking for the module. */
- if (__gconv_path_elem == NULL)
- __gconv_get_path ();
-
- /* See whether we have to append .so. */
- if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0)
- need_so = 1;
-
- /* Create a new entry. */
- newp = (struct known_trans *) malloc (sizeof (struct known_trans)
- + (__gconv_max_path_elem_len
- + name_len + 3)
- + name_len);
- if (newp != NULL)
- {
- char *cp;
-
- /* Clear the struct. */
- memset (newp, '\0', sizeof (struct known_trans));
-
- /* Store a copy of the module name. */
- newp->info.name = cp = (char *) (newp + 1);
- cp = __mempcpy (cp, trans->name, name_len);
-
- newp->fname = cp;
-
- /* Search in all the directories. */
- for (runp = __gconv_path_elem; runp->name != NULL; ++runp)
- {
- cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name),
- trans->name, name_len);
- if (need_so)
- memcpy (cp, ".so", sizeof (".so"));
-
- if (open_translit (newp) == 0)
- {
- /* We found a module. */
- res = 0;
- break;
- }
- }
-
- if (res)
- newp->fname = NULL;
-
- /* In any case we'll add the entry to our search tree. */
- if (__tsearch (newp, &search_tree, trans_compare) == NULL)
- {
- /* Yickes, this should not happen. Unload the object. */
- res = 1;
- /* XXX unload here. */
- }
- }
- }
-
- __libc_lock_unlock (lock);
-
- return res;
+ /* This function always fails. Transliteration module loading is
+ not implemented. */
+ return 1;
}
++++++ dt-ppc64-num.patch ++++++
2014-07-14 Alan Modra
[BZ #17153]
* elf/elf.h (DT_PPC64_NUM): Correct value.
* NEWS: Add to fixed bug list.
Index: glibc-2.19/elf/elf.h
===================================================================
--- glibc-2.19.orig/elf/elf.h
+++ glibc-2.19/elf/elf.h
@@ -2283,7 +2283,7 @@ typedef Elf32_Addr Elf32_Conflict;
#define DT_PPC64_OPD (DT_LOPROC + 1)
#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
#define DT_PPC64_OPT (DT_LOPROC + 3)
-#define DT_PPC64_NUM 3
+#define DT_PPC64_NUM 4
/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */
#define PPC64_OPT_TLS 1
++++++ errorcheck-mutex-no-elision.patch ++++++
From acef98c897335f28924d6da4d4d153e268624566 Mon Sep 17 00:00:00 2001
From: Andreas Schwab
Date: Wed, 13 Jan 2016 16:04:42 +0100
Subject: [PATCH] Don't do lock elision on an error checking mutex (bug 17514)
Error checking mutexes are not supposed to be subject to lock elision.
That would defeat the error checking nature of the mutex because lock
elision doesn't record ownership.
[BZ #17514]
* nptl/pthread_mutex_timedlock.c (pthread_mutex_timedlock)
<case PTHREAD_MUTEX_ERRORCHECK_NP>: Don't do lock elision.
* nptl/Makefile (tests): Add tst-mutex-errorcheck.
* nptl/tst-mutex-errorcheck.c: New file.
---
nptl/Makefile | 2 +-
nptl/pthread_mutex_timedlock.c | 3 ++-
nptl/tst-mutex-errorcheck.c | 61 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 nptl/tst-mutex-errorcheck.c
Index: glibc-2.19/nptl/Makefile
===================================================================
--- glibc-2.19.orig/nptl/Makefile
+++ glibc-2.19/nptl/Makefile
@@ -267,6 +267,7 @@ tests = tst-typesizes \
tst-abstime \
tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
tst-getpid1 tst-getpid2 tst-getpid3 \
+ tst-mutex-errorcheck \
tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99)
xtests = tst-setuid1 tst-setuid1-static tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
test-srcs = tst-oddstacklimit
Index: glibc-2.19/nptl/pthread_mutex_timedlock.c
===================================================================
--- glibc-2.19.orig/nptl/pthread_mutex_timedlock.c
+++ glibc-2.19/nptl/pthread_mutex_timedlock.c
@@ -87,7 +87,8 @@ pthread_mutex_timedlock (mutex, abstime)
if (__builtin_expect (mutex->__data.__owner == id, 0))
return EDEADLK;
- /* FALLTHROUGH */
+ /* Don't do lock elision on an error checking mutex. */
+ goto simple;
case PTHREAD_MUTEX_TIMED_NP:
FORCE_ELISION (mutex, goto elision);
Index: glibc-2.19/nptl/tst-mutex-errorcheck.c
===================================================================
--- /dev/null
+++ glibc-2.19/nptl/tst-mutex-errorcheck.c
@@ -0,0 +1,61 @@
+/* Check that error checking mutexes are not subject to lock elision.
+ Copyright (C) 2016 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
+#include
+#include
+#include
+
+static int
+do_test (void)
+{
+ struct timespec tms = { 0 };
+ pthread_mutex_t mutex;
+ pthread_mutexattr_t mutexattr;
+ int ret = 0;
+
+ if (pthread_mutexattr_init (&mutexattr) != 0)
+ return 1;
+ if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0)
+ return 1;
+
+ if (pthread_mutex_init (&mutex, &mutexattr) != 0)
+ return 1;
+ if (pthread_mutexattr_destroy (&mutexattr) != 0)
+ return 1;
+
+ /* The call to pthread_mutex_timedlock erroneously enabled lock elision
+ on the mutex, which then triggered an assertion failure in
+ pthread_mutex_unlock. It would also defeat the error checking nature
+ of the mutex. */
+ if (pthread_mutex_timedlock (&mutex, &tms) != 0)
+ return 1;
+ if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK)
+ {
+ printf ("Failed error checking on locked mutex\n");
+ ret = 1;
+ }
+
+ if (pthread_mutex_unlock (&mutex) != 0)
+ ret = 1;
+
+ return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
++++++ fix-locking-in-_IO_cleanup.patch ++++++
Always do locking when accessing streams
[BZ #15142]
* libio/genops.c (_IO_list_all_stamp): Delete. All uses removed.
(_IO_flush_all_all_lockp): Delete.
(_IO_flush_all): Replace with body of _IO_flush_all_all_lockp.
Always do locking.
(_IO_unbuffer_write): Always do locking.
(_IO_cleanup): Call _IO_flush_all instead of _IO_flush_all_lockp.
* libio/libioP.h (_IO_flush_all_all_lockp): Remove declaration.
diff --git a/libio/genops.c b/libio/genops.c
index e0ce8cc..9def1d4 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -38,10 +38,6 @@
static _IO_lock_t list_all_lock = _IO_lock_initializer;
#endif
-/* Used to signal modifications to the list of FILE decriptors. */
-static int _IO_list_all_stamp;
-
-
static _IO_FILE *run_fp;
#ifdef _IO_MTSAFE_IO
@@ -70,16 +66,12 @@ _IO_un_link (fp)
if (_IO_list_all == NULL)
;
else if (fp == _IO_list_all)
- {
- _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
- ++_IO_list_all_stamp;
- }
+ _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
else
for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain)
if (*f == (_IO_FILE *) fp)
{
*f = fp->file._chain;
- ++_IO_list_all_stamp;
break;
}
fp->file._flags &= ~_IO_LINKED;
@@ -108,7 +100,6 @@ _IO_link_in (fp)
#endif
fp->file._chain = (_IO_FILE *) _IO_list_all;
_IO_list_all = fp;
- ++_IO_list_all_stamp;
#ifdef _IO_MTSAFE_IO
_IO_funlockfile ((_IO_FILE *) fp);
run_fp = NULL;
@@ -818,25 +809,20 @@ _IO_get_column (fp)
int
-_IO_flush_all_lockp (int do_lock)
+_IO_flush_all (void)
{
int result = 0;
struct _IO_FILE *fp;
- int last_stamp;
#ifdef _IO_MTSAFE_IO
- __libc_cleanup_region_start (do_lock, flush_cleanup, NULL);
- if (do_lock)
- _IO_lock_lock (list_all_lock);
+ _IO_cleanup_region_start_noarg (flush_cleanup);
+ _IO_lock_lock (list_all_lock);
#endif
- last_stamp = _IO_list_all_stamp;
- fp = (_IO_FILE *) _IO_list_all;
- while (fp != NULL)
+ for (fp = (_IO_FILE *) _IO_list_all; fp != NULL; fp = fp->_chain)
{
run_fp = fp;
- if (do_lock)
- _IO_flockfile (fp);
+ _IO_flockfile (fp);
if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
@@ -848,52 +834,30 @@ _IO_flush_all_lockp (int do_lock)
&& _IO_OVERFLOW (fp, EOF) == EOF)
result = EOF;
- if (do_lock)
- _IO_funlockfile (fp);
+ _IO_funlockfile (fp);
run_fp = NULL;
-
- if (last_stamp != _IO_list_all_stamp)
- {
- /* Something was added to the list. Start all over again. */
- fp = (_IO_FILE *) _IO_list_all;
- last_stamp = _IO_list_all_stamp;
- }
- else
- fp = fp->_chain;
}
#ifdef _IO_MTSAFE_IO
- if (do_lock)
- _IO_lock_unlock (list_all_lock);
- __libc_cleanup_region_end (0);
+ _IO_lock_unlock (list_all_lock);
+ _IO_cleanup_region_end (0);
#endif
return result;
}
-
-
-int
-_IO_flush_all (void)
-{
- /* We want locking. */
- return _IO_flush_all_lockp (1);
-}
libc_hidden_def (_IO_flush_all)
void
_IO_flush_all_linebuffered (void)
{
struct _IO_FILE *fp;
- int last_stamp;
#ifdef _IO_MTSAFE_IO
_IO_cleanup_region_start_noarg (flush_cleanup);
_IO_lock_lock (list_all_lock);
#endif
- last_stamp = _IO_list_all_stamp;
- fp = (_IO_FILE *) _IO_list_all;
- while (fp != NULL)
+ for (fp = (_IO_FILE *) _IO_list_all; fp != NULL; fp = fp->_chain)
{
run_fp = fp;
_IO_flockfile (fp);
@@ -903,15 +867,6 @@ _IO_flush_all_linebuffered (void)
_IO_funlockfile (fp);
run_fp = NULL;
-
- if (last_stamp != _IO_list_all_stamp)
- {
- /* Something was added to the list. Start all over again. */
- fp = (_IO_FILE *) _IO_list_all;
- last_stamp = _IO_list_all_stamp;
- }
- else
- fp = fp->_chain;
}
#ifdef _IO_MTSAFE_IO
@@ -947,6 +902,12 @@ static void
_IO_unbuffer_write (void)
{
struct _IO_FILE *fp;
+
+#ifdef _IO_MTSAFE_IO
+ _IO_cleanup_region_start_noarg (flush_cleanup);
+ _IO_lock_lock (list_all_lock);
+#endif
+
for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
{
if (! (fp->_flags & _IO_UNBUFFERED)
@@ -956,15 +917,8 @@ _IO_unbuffer_write (void)
&& fp->_mode != 0)
{
#ifdef _IO_MTSAFE_IO
- int cnt;
-#define MAXTRIES 2
- for (cnt = 0; cnt < MAXTRIES; ++cnt)
- if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
- break;
- else
- /* Give the other thread time to finish up its use of the
- stream. */
- __sched_yield ();
+ run_fp = fp;
+ _IO_flockfile (fp);
#endif
if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
@@ -980,8 +934,8 @@ _IO_unbuffer_write (void)
_IO_SETBUF (fp, NULL, 0);
#ifdef _IO_MTSAFE_IO
- if (cnt < MAXTRIES && fp->_lock != NULL)
- _IO_lock_unlock (*fp->_lock);
+ _IO_funlockfile (fp);
+ run_fp = NULL;
#endif
}
@@ -989,6 +943,11 @@ _IO_unbuffer_write (void)
used. */
fp->_mode = -1;
}
+
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_unlock (list_all_lock);
+ _IO_cleanup_region_end (0);
+#endif
}
@@ -1008,9 +967,7 @@ libc_freeres_fn (buffer_free)
int
_IO_cleanup (void)
{
- /* We do *not* want locking. Some threads might use streams but
- that is their problem, we flush them underneath them. */
- int result = _IO_flush_all_lockp (0);
+ int result = _IO_flush_all ();
/* We currently don't have a reliable mechanism for making sure that
C++ static destructors are executed in the correct order.
diff --git a/libio/libioP.h b/libio/libioP.h
index 8a7b85b..3e3a724 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -488,7 +488,6 @@ extern int _IO_new_do_write (_IO_FILE *, const char *, _IO_size_t);
extern int _IO_old_do_write (_IO_FILE *, const char *, _IO_size_t);
extern int _IO_wdo_write (_IO_FILE *, const wchar_t *, _IO_size_t);
libc_hidden_proto (_IO_wdo_write)
-extern int _IO_flush_all_lockp (int);
extern int _IO_flush_all (void);
libc_hidden_proto (_IO_flush_all)
extern int _IO_cleanup (void);
--
1.9.1
++++++ fnmatch-read-eos.patch ++++++
2015-03-02 Paul Pluzhnikov
[BZ #18036]
* posix/fnmatch_loop.c (END): Detect invalid pattern.
* posix/tst-fnmatch3.c (do_bz18036): Add test case.
2015-02-26 Andreas Schwab
[BZ #18032]
* posix/fnmatch_loop.c (FCT): Remove extra increment when skipping
over collating symbol inside a bracket expression. Minor cleanup.
* posix/tst-fnmatch3.c (do_test): Add test case.
2014-06-18 Andreas Schwab
[BZ #17062]
* posix/fnmatch_loop.c (FCT): Rerrange loop for skipping over rest
of a bracket expr not to run off the end of the string.
* posix/Makefile (tests): Add tst-fnmatch3.
* posix/tst-fnmatch3.c: New file.
Index: glibc-2.19/posix/Makefile
===================================================================
--- glibc-2.19.orig/posix/Makefile
+++ glibc-2.19/posix/Makefile
@@ -86,7 +86,8 @@ tests := tstgetopt testfnm runtests run
tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
- tst-pathconf tst-getaddrinfo4
+ tst-pathconf tst-getaddrinfo4 \
+ tst-fnmatch3
xtests := bug-ga2
ifeq (yes,$(build-shared))
test-srcs := globtest
Index: glibc-2.19/posix/fnmatch_loop.c
===================================================================
--- glibc-2.19.orig/posix/fnmatch_loop.c
+++ glibc-2.19/posix/fnmatch_loop.c
@@ -899,11 +899,8 @@ FCT (pattern, string, string_end, no_lea
matched:
/* Skip the rest of the [...] that already matched. */
- do
+ while ((c = *p++) != L (']'))
{
- ignore_next:
- c = *p++;
-
if (c == L('\0'))
/* [... (unterminated) loses. */
return FNM_NOMATCH;
@@ -931,12 +928,11 @@ FCT (pattern, string, string_end, no_lea
if (c < L('a') || c >= L('z'))
{
- p = startp;
- goto ignore_next;
+ p = startp - 2;
+ break;
}
}
p += 2;
- c = *p++;
}
else if (c == L('[') && *p == L('='))
{
@@ -947,25 +943,21 @@ FCT (pattern, string, string_end, no_lea
if (c != L('=') || p[1] != L(']'))
return FNM_NOMATCH;
p += 2;
- c = *p++;
}
else if (c == L('[') && *p == L('.'))
{
- ++p;
while (1)
{
c = *++p;
- if (c == '\0')
+ if (c == L('\0'))
return FNM_NOMATCH;
- if (*p == L('.') && p[1] == L(']'))
+ if (c == L('.') && p[1] == L(']'))
break;
}
p += 2;
- c = *p++;
}
}
- while (c != L(']'));
if (not)
return FNM_NOMATCH;
}
@@ -1045,7 +1037,12 @@ END (const CHAR *pattern)
}
else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
|| *p == L('!')) && p[1] == L('('))
- p = END (p + 1);
+ {
+ p = END (p + 1);
+ if (*p == L('\0'))
+ /* This is an invalid pattern. */
+ return pattern;
+ }
else if (*p == L(')'))
break;
Index: glibc-2.19/posix/tst-fnmatch3.c
===================================================================
--- /dev/null
+++ glibc-2.19/posix/tst-fnmatch3.c
@@ -0,0 +1,52 @@
+/* Test for fnmatch not reading past the end of the pattern.
+ Copyright (C) 2014 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
+#include
+#include
+#include
+
+int
+do_bz18036 (void)
+{
+ const char p[] = "**(!()";
+ const int pagesize = getpagesize ();
+
+ char *pattern = mmap (0, 2 * pagesize, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if (pattern == MAP_FAILED) return 1;
+
+ mprotect (pattern + pagesize, pagesize, PROT_NONE);
+ memset (pattern, ' ', pagesize);
+ strcpy (pattern, p);
+
+ return fnmatch (pattern, p, FNM_EXTMATCH);
+}
+
+int
+do_test (void)
+{
+ if (fnmatch ("[[:alpha:]'[:alpha:]\0]", "a", 0) != FNM_NOMATCH)
+ return 1;
+ if (fnmatch ("[a[.\0.]]", "a", 0) != FNM_NOMATCH)
+ return 1;
+ return do_bz18036 ();
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
++++++ getaddrinfo-hostent-conv-stack-overflow.patch ++++++
2016-04-29 Florian Weimer
[BZ #20010]
CVE-2016-3706
* sysdeps/posix/getaddrinfo.c
(convert_hostent_to_gaih_addrtuple): New function.
(gethosts): Call convert_hostent_to_gaih_addrtuple.
(gaih_inet): Use convert_hostent_to_gaih_addrtuple to convert
AF_INET data.
Index: glibc-2.19/sysdeps/posix/getaddrinfo.c
===================================================================
--- glibc-2.19.orig/sysdeps/posix/getaddrinfo.c
+++ glibc-2.19/sysdeps/posix/getaddrinfo.c
@@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename,
return 0;
}
+/* Convert struct hostent to a list of struct gaih_addrtuple objects.
+ h_name is not copied, and the struct hostent object must not be
+ deallocated prematurely. *RESULT must be NULL or a pointer to an
+ object allocated using malloc, which is freed. */
+static bool
+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
+ int family,
+ struct hostent *h,
+ struct gaih_addrtuple **result)
+{
+ free (*result);
+ *result = NULL;
+
+ /* Count the number of addresses in h->h_addr_list. */
+ size_t count = 0;
+ for (char **p = h->h_addr_list; *p != NULL; ++p)
+ ++count;
+
+ /* Report no data if no addresses are available, or if the incoming
+ address size is larger than what we can store. */
+ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
+ return true;
+
+ struct gaih_addrtuple *array = calloc (count, sizeof (*array));
+ if (array == NULL)
+ return false;
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ if (family == AF_INET && req->ai_family == AF_INET6)
+ {
+ /* Perform address mapping. */
+ array[i].family = AF_INET6;
+ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
+ array[i].addr[2] = htonl (0xffff);
+ }
+ else
+ {
+ array[i].family = family;
+ memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
+ }
+ array[i].next = array + i + 1;
+ }
+ array[0].name = h->h_name;
+ array[count - 1].next = NULL;
+
+ *result = array;
+ return true;
+}
+
#define gethosts(_family, _type) \
{ \
- int i; \
int herrno; \
struct hostent th; \
struct hostent *h; \
@@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename,
} \
else if (h != NULL) \
{ \
- for (i = 0; h->h_addr_list[i]; i++) \
+ /* Make sure that addrmem can be freed. */ \
+ if (!malloc_addrmem) \
+ addrmem = NULL; \
+ if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
{ \
- if (*pat == NULL) \
- { \
- *pat = __alloca (sizeof (struct gaih_addrtuple)); \
- (*pat)->scopeid = 0; \
- } \
- uint32_t *addr = (*pat)->addr; \
- (*pat)->next = NULL; \
- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
- if (_family == AF_INET && req->ai_family == AF_INET6) \
- { \
- (*pat)->family = AF_INET6; \
- addr[3] = *(uint32_t *) h->h_addr_list[i]; \
- addr[2] = htonl (0xffff); \
- addr[1] = 0; \
- addr[0] = 0; \
- } \
- else \
- { \
- (*pat)->family = _family; \
- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
- } \
- pat = &((*pat)->next); \
+ _res.options |= old_res_options & RES_USE_INET6; \
+ result = -EAI_SYSTEM; \
+ goto free_and_return; \
} \
+ *pat = addrmem; \
+ /* The conversion uses malloc unconditionally. */ \
+ malloc_addrmem = true; \
\
if (localcanon != NULL && canon == NULL) \
canon = strdupa (localcanon); \
\
- if (_family == AF_INET6 && i > 0) \
+ if (_family == AF_INET6 && *pat != NULL) \
got_ipv6 = true; \
} \
}
@@ -612,44 +648,16 @@ gaih_inet (const char *name, const struc
{
if (h != NULL)
{
- int i;
- /* We found data, count the number of addresses. */
- for (i = 0; h->h_addr_list[i]; ++i)
- ;
- if (i > 0 && *pat != NULL)
- --i;
-
- if (__libc_use_alloca (alloca_used
- + i * sizeof (struct gaih_addrtuple)))
- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
- alloca_used);
- else
+ /* We found data, convert it. */
+ if (!convert_hostent_to_gaih_addrtuple
+ (req, AF_INET, h, &addrmem))
{
- addrmem = malloc (i
- * sizeof (struct gaih_addrtuple));
- if (addrmem == NULL)
- {
- result = -EAI_MEMORY;
- goto free_and_return;
- }
- malloc_addrmem = true;
- }
-
- /* Now convert it into the list. */
- struct gaih_addrtuple *addrfree = addrmem;
- for (i = 0; h->h_addr_list[i]; ++i)
- {
- if (*pat == NULL)
- {
- *pat = addrfree++;
- (*pat)->scopeid = 0;
- }
- (*pat)->next = NULL;
- (*pat)->family = AF_INET;
- memcpy ((*pat)->addr, h->h_addr_list[i],
- h->h_length);
- pat = &((*pat)->next);
+ result = -EAI_MEMORY;
+ goto free_and_return;
}
+ *pat = addrmem;
+ /* The conversion uses malloc unconditionally. */
+ malloc_addrmem = true;
}
}
else
++++++ getaddrinfo-ipv6-sanity.diff ++++++
Index: glibc-2.18.90/sysdeps/posix/getaddrinfo.c
===================================================================
--- glibc-2.18.90.orig/sysdeps/posix/getaddrinfo.c
+++ glibc-2.18.90/sysdeps/posix/getaddrinfo.c
@@ -286,7 +286,7 @@ extern service_user *__nss_hosts_databas
static int
gaih_inet (const char *name, const struct gaih_service *service,
const struct addrinfo *req, struct addrinfo **pai,
- unsigned int *naddrs)
+ unsigned int *naddrs, bool usable_ipv6)
{
const struct gaih_typeproto *tp = gaih_inet_typeproto;
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
@@ -855,7 +855,10 @@ gaih_inet (const char *name, const struc
if (req->ai_family == PF_UNSPEC)
fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
- if (fct4 != NULL)
+ /* If we don't want ipv6, don't use gethostbyname4_r,
+ as it's using T_UNSPEC to libc_res_nsearch, which always
+ create T_A and T_AAAA queries. */
+ if (usable_ipv6 && fct4 != NULL)
{
int herrno;
@@ -958,7 +961,7 @@ gaih_inet (const char *name, const struc
if (fct != NULL)
{
if (req->ai_family == AF_INET6
- || req->ai_family == AF_UNSPEC)
+ || (req->ai_family == AF_UNSPEC && usable_ipv6))
{
gethosts (AF_INET6, struct in6_addr);
no_inet6_data = no_data;
@@ -2418,7 +2421,11 @@ getaddrinfo (const char *name, const cha
if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
|| hints->ai_family == AF_INET6)
{
- last_i = gaih_inet (name, pservice, hints, end, &naddrs);
+ if (!check_pf_called)
+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
+ check_pf_called = true;
+
+ last_i = gaih_inet (name, pservice, hints, end, &naddrs, seen_ipv6);
if (last_i != 0)
{
freeaddrinfo (p);
++++++ getaddrinfo-uninit-result.patch ++++++
* sysdeps/posix/getaddrinfo.c (gaih_inet): Properly skip over
non-matching result from nscd.
Index: glibc-2.19/sysdeps/posix/getaddrinfo.c
===================================================================
--- glibc-2.19.orig/sysdeps/posix/getaddrinfo.c
+++ glibc-2.19/sysdeps/posix/getaddrinfo.c
@@ -712,6 +712,18 @@ gaih_inet (const char *name, const struc
{
socklen_t size = (air->family[i] == AF_INET
? INADDRSZ : IN6ADDRSZ);
+
+ if (!((air->family[i] == AF_INET
+ && req->ai_family == AF_INET6
+ && (req->ai_flags & AI_V4MAPPED) != 0)
+ || req->ai_family == AF_UNSPEC
+ || air->family[i] == req->ai_family))
+ {
+ /* Skip over non-matching result. */
+ addrs += size;
+ continue;
+ }
+
if (*pat == NULL)
{
*pat = addrfree++;
++++++ glibc-2.14-crypt.diff ++++++
Index: glibc-2.19/Versions.def
===================================================================
--- glibc-2.19.orig/Versions.def
+++ glibc-2.19/Versions.def
@@ -45,6 +45,9 @@ libc {
libcrypt {
GLIBC_2.0
}
+libowcrypt {
+ OW_CRYPT_1.0
+}
libdl {
GLIBC_2.0
GLIBC_2.1
Index: glibc-2.19/crypt/Makefile
===================================================================
--- glibc-2.19.orig/crypt/Makefile
+++ glibc-2.19/crypt/Makefile
@@ -21,14 +21,18 @@
subdir := crypt
headers := crypt.h
+headers += gnu-crypt.h ow-crypt.h
-extra-libs := libcrypt
+extra-libs := libcrypt libowcrypt
extra-libs-others := $(extra-libs)
libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
crypt_util
-tests := cert md5c-test sha256c-test sha512c-test badsalttest
+libcrypt-routines += crypt_blowfish x86 wrapper
+libowcrypt-routines := crypt_gensalt wrapper-gensalt
+
+tests := cert md5c-test sha256c-test sha512c-test
include ../Makeconfig
Index: glibc-2.19/crypt/Versions
===================================================================
--- glibc-2.19.orig/crypt/Versions
+++ glibc-2.19/crypt/Versions
@@ -3,3 +3,8 @@ libcrypt {
crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
}
}
+libowcrypt {
+ OW_CRYPT_1.0 {
+ crypt_gensalt; crypt_gensalt_rn; crypt_gensalt_ra;
+ }
+}
Index: glibc-2.19/crypt/crypt-entry.c
===================================================================
--- glibc-2.19.orig/crypt/crypt-entry.c
+++ glibc-2.19/crypt/crypt-entry.c
@@ -81,7 +81,7 @@ extern struct crypt_data _ufc_foobar;
*/
char *
-__crypt_r (key, salt, data)
+__des_crypt_r (key, salt, data)
const char *key;
const char *salt;
struct crypt_data * __restrict data;
@@ -155,6 +155,7 @@ __crypt_r (key, salt, data)
_ufc_output_conversion_r (res[0], res[1], salt, data);
return data->crypt_3_buf;
}
+#if 0
weak_alias (__crypt_r, crypt_r)
char *
@@ -197,3 +198,4 @@ __fcrypt (key, salt)
return crypt (key, salt);
}
#endif
+#endif
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/alpha/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/alpha/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/arm/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/arm/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/ia64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/ia64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/m68k/coldfire/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/m68k/m680x0/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/mips/mips32/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/mips/mips64/n32/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/mips/mips64/n64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/tile/tilepro/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/shlib-versions
===================================================================
--- glibc-2.19.orig/shlib-versions
+++ glibc-2.19/shlib-versions
@@ -93,6 +93,7 @@ sh.*-.*-linux.* ld=ld-linux.so.2 GLIBC_
# This defines the shared library version numbers we will install.
.*-.*-.* libcrypt=1
+.*-.*-.* libowcrypt=1
# The gross patch for programs assuming broken locale implementations.
sh.*-.*-.* libBrokenLocale=1 GLIBC_2.2
Index: glibc-2.19/sysdeps/unix/sysv/linux/i386/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/i386/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libowcrypt-le.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libowcrypt-le.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/sh/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/sh/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/sparc/sparc32/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/x86_64/64/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/x86_64/64/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
Index: glibc-2.19/sysdeps/unix/sysv/linux/x86_64/x32/nptl/libowcrypt.abilist
===================================================================
--- /dev/null
+++ glibc-2.19/sysdeps/unix/sysv/linux/x86_64/x32/nptl/libowcrypt.abilist
@@ -0,0 +1,5 @@
+OW_CRYPT_1.0
+ OW_CRYPT_1.0 A
+ crypt_gensalt F
+ crypt_gensalt_ra F
+ crypt_gensalt_rn F
++++++ glibc-2.2-sunrpc.diff ++++++
For details see:
http://sourceware.org/bugzilla/show_bug.cgi?id=5379
Index: glibc-2.17.90/sunrpc/clnt_udp.c
===================================================================
--- glibc-2.17.90.orig/sunrpc/clnt_udp.c
+++ glibc-2.17.90/sunrpc/clnt_udp.c
@@ -308,6 +308,7 @@ clntudp_call (cl, proc, xargs, argsp, xr
XDR *xdrs;
int outlen = 0;
int inlen;
+ int pollresult;
socklen_t fromlen;
struct pollfd fd;
int milliseconds = (cu->cu_wait.tv_sec * 1000) +
@@ -378,37 +379,36 @@ send_again:
anyup = 0;
for (;;)
{
- switch (__poll (&fd, 1, milliseconds))
+ switch (pollresult = __poll (&fd, 1, milliseconds))
{
-
case 0:
- if (anyup == 0)
- {
- anyup = is_network_up (cu->cu_sock);
- if (!anyup)
- return (cu->cu_error.re_status = RPC_CANTRECV);
- }
-
- time_waited.tv_sec += cu->cu_wait.tv_sec;
- time_waited.tv_usec += cu->cu_wait.tv_usec;
- while (time_waited.tv_usec >= 1000000)
- {
- time_waited.tv_sec++;
- time_waited.tv_usec -= 1000000;
- }
- if ((time_waited.tv_sec < timeout.tv_sec) ||
- ((time_waited.tv_sec == timeout.tv_sec) &&
- (time_waited.tv_usec < timeout.tv_usec)))
- goto send_again;
- return (cu->cu_error.re_status = RPC_TIMEDOUT);
-
- /*
- * buggy in other cases because time_waited is not being
- * updated.
- */
case -1:
- if (errno == EINTR)
- continue;
+ if (pollresult == 0 || errno == EINTR) {
+ if (anyup == 0)
+ {
+ anyup = is_network_up (cu->cu_sock);
+ if (!anyup)
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
+ time_waited.tv_sec += cu->cu_wait.tv_sec;
+ time_waited.tv_usec += cu->cu_wait.tv_usec;
+ while (time_waited.tv_usec >= 1000000)
+ {
+ time_waited.tv_sec++;
+ time_waited.tv_usec -= 1000000;
+ }
+ if ((time_waited.tv_sec < timeout.tv_sec) ||
+ ((time_waited.tv_sec == timeout.tv_sec) &&
+ (time_waited.tv_usec < timeout.tv_usec)))
+ if (pollresult == 0)
+ goto send_again;
+ else
+ continue;
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+
+ /* errno != EINTR */
cu->cu_error.re_errno = errno;
return (cu->cu_error.re_status = RPC_CANTRECV);
}
++++++ glibc-2.3.2.no_archive.diff ++++++
Wed Jun 4 14:29:07 CEST 2003 - kukuk@suse.de
- Make --no-archive default for localedef
Index: glibc-2.18.90/locale/programs/localedef.c
===================================================================
--- glibc-2.18.90.orig/locale/programs/localedef.c
+++ glibc-2.18.90/locale/programs/localedef.c
@@ -81,7 +81,7 @@ const char *alias_file;
static struct localedef_t *locales;
/* If true don't add locale data to archive. */
-bool no_archive;
+bool no_archive = true;
/* If true add named locales to archive. */
static bool add_to_archive;
@@ -112,6 +112,7 @@ void (*argp_program_version_hook) (FILE
#define OPT_REPLACE 307
#define OPT_DELETE_FROM_ARCHIVE 308
#define OPT_LIST_ARCHIVE 309
+#define OPT_ARCHIVE 310
#define OPT_LITTLE_ENDIAN 400
#define OPT_BIG_ENDIAN 401
@@ -136,6 +137,8 @@ static const struct argp_option options[
N_("Suppress warnings and information messages") },
{ "verbose", 'v', NULL, 0, N_("Print more messages") },
{ NULL, 0, NULL, 0, N_("Archive control:") },
+ { "archive", OPT_ARCHIVE, NULL, 0,
+ N_("Add new data to archive") },
{ "no-archive", OPT_NO_ARCHIVE, NULL, 0,
N_("Don't add new data to archive") },
{ "add-to-archive", OPT_ADD_TO_ARCHIVE, NULL, 0,
@@ -317,6 +320,9 @@ parse_opt (int key, char *arg, struct ar
case OPT_PREFIX:
output_prefix = arg;
break;
+ case OPT_ARCHIVE:
+ no_archive = false;
+ break;
case OPT_NO_ARCHIVE:
no_archive = true;
break;
++++++ glibc-2.3.3-nscd-db-path.diff ++++++
2004-12-09 Thorsten Kukuk
* nscd/nscd.h: Move persistent storage back to /var/run/nscd
Index: glibc-2.17.90/nscd/nscd.h
===================================================================
--- glibc-2.17.90.orig/nscd/nscd.h
+++ glibc-2.17.90/nscd/nscd.h
@@ -112,11 +112,11 @@ struct database_dyn
/* Paths of the file for the persistent storage. */
-#define _PATH_NSCD_PASSWD_DB "/var/db/nscd/passwd"
-#define _PATH_NSCD_GROUP_DB "/var/db/nscd/group"
-#define _PATH_NSCD_HOSTS_DB "/var/db/nscd/hosts"
-#define _PATH_NSCD_SERVICES_DB "/var/db/nscd/services"
-#define _PATH_NSCD_NETGROUP_DB "/var/db/nscd/netgroup"
+#define _PATH_NSCD_PASSWD_DB "/var/run/nscd/passwd"
+#define _PATH_NSCD_GROUP_DB "/var/run/nscd/group"
+#define _PATH_NSCD_HOSTS_DB "/var/run/nscd/hosts"
+#define _PATH_NSCD_SERVICES_DB "/var/run/nscd/services"
+#define _PATH_NSCD_NETGROUP_DB "/var/run/nscd/netgroup"
/* Path used when not using persistent storage. */
#define _PATH_NSCD_XYZ_DB_TMP "/var/run/nscd/dbXXXXXX"
++++++ glibc-2.3.90-langpackdir.diff ++++++
Index: glibc-2.17.90/intl/loadmsgcat.c
===================================================================
--- glibc-2.17.90.orig/intl/loadmsgcat.c
+++ glibc-2.17.90/intl/loadmsgcat.c
@@ -806,8 +806,52 @@ _nl_load_domain (domain_file, domainbind
if (domain_file->filename == NULL)
goto out;
- /* Try to open the addressed file. */
- fd = open (domain_file->filename, O_RDONLY);
+ /* Replace /locale/ with /usr/share/locale-langpack/ */
+ const char *langpackdir = "/usr/share/locale-langpack/";
+ char *filename_langpack = malloc (strlen (domain_file->filename) +
+ strlen (langpackdir));
+ if (filename_langpack != NULL)
+ {
+ char *p = strstr (domain_file->filename, "/locale/");
+ if (p != NULL)
+ {
+ strcpy (filename_langpack, langpackdir);
+ strcpy (&filename_langpack[strlen (langpackdir)],
+ (p+8));
+ if ((fd = open (filename_langpack, O_RDONLY)) == -1)
+ fd = open (domain_file->filename, O_RDONLY);
+ }
+ else
+ /* Try to open the addressed file. */
+ fd = open (domain_file->filename, O_RDONLY);
+
+ free (filename_langpack);
+ }
+ else
+ /* Try to open the addressed file. */
+ fd = open (domain_file->filename, O_RDONLY);
+
+ if (fd == -1)
+ {
+ /* Use the fallback directory. */
+ const char *bundle_dir = "/usr/share/locale-bundle/";
+ char *filename_bundle = malloc (strlen (domain_file->filename) +
+ strlen (bundle_dir));
+ if (filename_bundle != NULL)
+ {
+ char *p = strstr (domain_file->filename, "/locale/");
+ if (p != NULL)
+ {
+ strcpy (filename_bundle, bundle_dir);
+ strcpy (&filename_bundle[strlen (bundle_dir)],
+ (p+8));
+ fd = open (filename_bundle, O_RDONLY);
+ }
+
+ free (filename_bundle);
+ }
+ }
+
if (fd == -1)
goto out;
++++++ glibc-2.3.90-noversion.diff ++++++
Index: glibc-2.17.90/elf/rtld.c
===================================================================
--- glibc-2.17.90.orig/elf/rtld.c
+++ glibc-2.17.90/elf/rtld.c
@@ -1717,6 +1717,53 @@ ERROR: ld.so: object '%s' cannot be load
}
}
+#if defined(__i386__)
+ /*
+ * Modifications by Red Hat Software
+ *
+ * Deal with the broken binaries from the non-versioned ages of glibc.
+ * If a binary does not have version information enabled, we assume that
+ * it is a glibc 2.0 binary and we load a compatibility library to try to
+ * overcome binary incompatibilities.
+ * Blame: gafton@redhat.com
+ */
+#define LIB_NOVERSION "/lib/obsolete/noversion/libNoVersion.so.1"
+
+ if (__builtin_expect (main_map->l_info[DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGIDX (DT_VERNEED)]
+ == NULL, 0)
+ && (main_map->l_info[DT_DEBUG]
+ || !(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)))
+ {
+ struct stat test_st;
+ int test_fd;
+ int can_load;
+
+ HP_TIMING_NOW (start);
+
+ can_load = 1;
+ test_fd = __open (LIB_NOVERSION, O_RDONLY);
+ if (test_fd < 0) {
+ can_load = 0;
+ } else {
+ if (__fxstat (_STAT_VER, test_fd, &test_st) < 0 || test_st.st_size == 0) {
+ can_load = 0;
+ }
+ }
+
+ if (test_fd >= 0) /* open did no fail.. */
+ __close(test_fd); /* avoid fd leaks */
+
+ if (can_load != 0)
+ npreloads += do_preload (LIB_NOVERSION, main_map,
+ "nonversioned binary");
+
+ HP_TIMING_NOW (stop);
+ HP_TIMING_DIFF (diff, start, stop);
+ HP_TIMING_ACCUM_NT (load_time, diff);
+ }
+#endif
+
if (__builtin_expect (*first_preload != NULL, 0))
{
/* Set up PRELOADS with a vector of the preloaded libraries. */
++++++ glibc-2.3.locales.diff.bz2 ++++++
++++ 74380 lines (skipped)
++++++ glibc-2.4-china.diff ++++++
Index: glibc-2.17.90/localedata/locales/zh_TW
===================================================================
--- glibc-2.17.90.orig/localedata/locales/zh_TW
+++ glibc-2.17.90/localedata/locales/zh_TW
@@ -1,7 +1,7 @@
comment_char %
escape_char /
%
-% Chinese language locale for Taiwan R.O.C.
+% Chinese language locale for Taiwan
% charmap: BIG5-CP950
%
% Original Author:
@@ -17,7 +17,7 @@ escape_char /
% Reference: http://wwwold.dkuug.dk/JTC1/SC22/WG20/docs/n690.pdf
LC_IDENTIFICATION
-title "Chinese locale for Taiwan R.O.C."
+title "Chinese locale for Taiwan"
source ""
address ""
contact ""
@@ -25,7 +25,7 @@ email "bug-glibc-locales@gnu.org"
tel ""
fax ""
language "Chinese"
-territory "Taiwan R.O.C."
+territory "Taiwan"
revision "0.2"
date "2000-08-02"
%
++++++ glibc-2.4.90-no_NO.diff ++++++
Index: glibc-2.18.90/intl/locale.alias
===================================================================
--- glibc-2.18.90.orig/intl/locale.alias
+++ glibc-2.18.90/intl/locale.alias
@@ -56,8 +56,6 @@ korean ko_KR.eucKR
korean.euc ko_KR.eucKR
ko_KR ko_KR.eucKR
lithuanian lt_LT.ISO-8859-13
-no_NO nb_NO.ISO-8859-1
-no_NO.ISO-8859-1 nb_NO.ISO-8859-1
norwegian nb_NO.ISO-8859-1
nynorsk nn_NO.ISO-8859-1
polish pl_PL.ISO-8859-2
Index: glibc-2.18.90/localedata/SUPPORTED
===================================================================
--- glibc-2.18.90.orig/localedata/SUPPORTED
+++ glibc-2.18.90/localedata/SUPPORTED
@@ -331,6 +331,8 @@ nl_NL/ISO-8859-1 \
nl_NL@euro/ISO-8859-15 \
nn_NO.UTF-8/UTF-8 \
nn_NO/ISO-8859-1 \
+no_NO.UTF-8/UTF-8 \
+no_NO/ISO-8859-1 \
nr_ZA/UTF-8 \
nso_ZA/UTF-8 \
oc_FR.UTF-8/UTF-8 \
Index: glibc-2.18.90/localedata/locales/no_NO
===================================================================
--- /dev/null
+++ glibc-2.18.90/localedata/locales/no_NO
@@ -0,0 +1,69 @@
+escape_char /
+comment_char %
+
+% Norwegian language locale for Norway
+% Source: Norsk Standardiseringsforbund
+% Address: University Library,
+% Drammensveien 41, N-9242 Oslo, Norge
+% Contact: Kolbjoern Aamboe
+% Tel: +47 - 22859109
+% Fax: +47 - 22434497
+% Email: kolbjorn.aambo@usit.uio.no
+% Language: no
+% Territory: NO
+% Revision: 4.3
+% Date: 1996-10-15
+% Application: general
+% Users: general
+% Repertoiremap: mnemonic.ds
+% Charset: ISO-8859-1
+% Distribution and use is free, also
+% for commercial purposes.
+
+LC_IDENTIFICATION
+copy "nb_NO"
+END LC_IDENTIFICATION
+
+LC_COLLATE
+copy "nb_NO"
+END LC_COLLATE
+
+LC_CTYPE
+copy "nb_NO"
+END LC_CTYPE
+
+LC_MONETARY
+copy "nb_NO"
+END LC_MONETARY
+
+LC_NUMERIC
+copy "nb_NO"
+END LC_NUMERIC
+
+LC_TIME
+copy "nb_NO"
+END LC_TIME
+
+LC_MESSAGES
+copy "nb_NO"
+END LC_MESSAGES
+
+LC_PAPER
+copy "nb_NO"
+END LC_PAPER
+
+LC_TELEPHONE
+copy "nb_NO"
+END LC_TELEPHONE
+
+LC_MEASUREMENT
+copy "nb_NO"
+END LC_MEASUREMENT
+
+LC_NAME
+copy "nb_NO"
+END LC_NAME
+
+LC_ADDRESS
+copy "nb_NO"
+END LC_ADDRESS
++++++ glibc-bindresvport-blacklist.diff ++++++
Index: glibc-2.17.90/sunrpc/bindrsvprt.c
===================================================================
--- glibc-2.17.90.orig/sunrpc/bindrsvprt.c
+++ glibc-2.17.90/sunrpc/bindrsvprt.c
@@ -29,6 +29,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include
+#include
+#include
#include
#include
#include
@@ -42,6 +45,93 @@
*/
__libc_lock_define_initialized (static, lock);
+#define STARTPORT 600
+#define LOWPORT 512
+#define ENDPORT (IPPORT_RESERVED - 1)
+#define NPORTS (ENDPORT - STARTPORT + 1)
+
+/* Read the file /etc/rpc.blacklisted, so that we don't bind to these
+ ports. */
+
+static int blacklist_read;
+static int *list;
+static int list_size = 0;
+
+static void
+load_blacklist (void)
+{
+ FILE *fp;
+ char *buf = NULL;
+ size_t buflen = 0;
+ int size = 0, ptr = 0;
+
+ __libc_lock_lock (lock);
+ if (blacklist_read)
+ goto unlock;
+ blacklist_read = 1;
+
+ fp = fopen ("/etc/bindresvport.blacklist", "r");
+ if (fp == NULL)
+ goto unlock;
+
+ while (!feof_unlocked (fp))
+ {
+ unsigned long port;
+ char *tmp, *cp;
+ ssize_t n = __getline (&buf, &buflen, fp);
+ if (n < 1)
+ break;
+
+ cp = buf;
+ /* Remove comments. */
+ tmp = strchr (cp, '#');
+ if (tmp)
+ *tmp = '\0';
+ /* Remove spaces and tabs. */
+ while (isspace ((unsigned char) *cp))
+ ++cp;
+ /* Ignore empty lines. */
+ if (*cp == '\0')
+ continue;
+ if (cp[strlen (cp) - 1] == '\n')
+ cp[strlen (cp) - 1] = '\0';
+
+ port = strtoul (cp, &tmp, 0);
+ while (isspace ((unsigned char) *tmp))
+ ++tmp;
+ if (*tmp != '\0' || (port == ULONG_MAX && errno == ERANGE))
+ continue;
+
+ /* Don't bother with out-of-range ports. */
+ if (port < LOWPORT || port > ENDPORT)
+ continue;
+
+ if (ptr >= size)
+ {
+ size += 10;
+ int *new_list = realloc (list, size * sizeof (int));
+ if (new_list == NULL)
+ {
+ free (list);
+ list = NULL;
+ free (buf);
+ goto unlock;
+ }
+ list = new_list;
+ }
+
+ list[ptr++] = port;
+ }
+
+ fclose (fp);
+ free (buf);
+ list_size = ptr;
+
+ unlock:
+ __libc_lock_unlock (lock);
+}
+
+
/*
* Bind a socket to a privileged IP port
*/
@@ -52,12 +142,11 @@ bindresvport (int sd, struct sockaddr_in
struct sockaddr_in myaddr;
int i;
-#define STARTPORT 600
-#define LOWPORT 512
-#define ENDPORT (IPPORT_RESERVED - 1)
-#define NPORTS (ENDPORT - STARTPORT + 1)
static short startport = STARTPORT;
+ if (!blacklist_read)
+ load_blacklist ();
+
if (sin == (struct sockaddr_in *) 0)
{
sin = &myaddr;
@@ -75,6 +164,7 @@ bindresvport (int sd, struct sockaddr_in
port = (__getpid () % NPORTS) + STARTPORT;
}
+ __set_errno (EADDRINUSE);
/* Initialize to make gcc happy. */
int res = -1;
@@ -86,12 +176,22 @@ bindresvport (int sd, struct sockaddr_in
again:
for (i = 0; i < nports; ++i)
{
- sin->sin_port = htons (port++);
- if (port > endport)
- port = startport;
+ int j;
+
+ sin->sin_port = htons (port);
+
+ /* Check that this port is not blacklisted. */
+ for (j = 0; j < list_size; j++)
+ if (port == list[j])
+ goto try_next_port;
+
res = __bind (sd, sin, sizeof (struct sockaddr_in));
if (res >= 0 || errno != EADDRINUSE)
break;
+
+ try_next_port:
+ if (++port > endport)
+ port = startport;
}
if (i == nports && startport != LOWPORT)
++++++ glibc-cpusetsize.diff ++++++
Index: glibc-2.17.90/bits/sched.h
===================================================================
--- glibc-2.17.90.orig/bits/sched.h
+++ glibc-2.17.90/bits/sched.h
@@ -52,7 +52,7 @@ struct __sched_param
#if defined _SCHED_H && !defined __cpu_set_t_defined
# define __cpu_set_t_defined
/* Size definition for CPU sets. */
-# define __CPU_SETSIZE 1024
+# define __CPU_SETSIZE 4096
# define __NCPUBITS (8 * sizeof (__cpu_mask))
/* Type for array elements in 'cpu_set_t'. */
Index: glibc-2.17.90/sysdeps/unix/sysv/linux/bits/sched.h
===================================================================
--- glibc-2.17.90.orig/sysdeps/unix/sysv/linux/bits/sched.h
+++ glibc-2.17.90/sysdeps/unix/sysv/linux/bits/sched.h
@@ -111,7 +111,7 @@ struct __sched_param
#if defined _SCHED_H && !defined __cpu_set_t_defined
# define __cpu_set_t_defined
/* Size definition for CPU sets. */
-# define __CPU_SETSIZE 1024
+# define __CPU_SETSIZE 4096
# define __NCPUBITS (8 * sizeof (__cpu_mask))
/* Type for array elements in 'cpu_set_t'. */
++++++ glibc-fix-double-loopback.diff ++++++
This fixes the problem of getent ahosts localhost returning 127.0.0.1
_twice_ on systems that have no ipv6 interfaces up (hence are regarded
as ipv4 only by the lookup code), but still have localhost entries for
::1 and 127.0.0.1 in /etc/hosts (like most current systems).
Remapping ::1 to 127.0.0.1 is bogus when /etc/hosts is correct.
bnc #684534, #606980
http://sources.redhat.com/bugzilla/show_bug.cgi?id=4980
Index: glibc-2.17.90/nss/nss_files/files-hosts.c
===================================================================
--- glibc-2.17.90.orig/nss/nss_files/files-hosts.c
+++ glibc-2.17.90/nss/nss_files/files-hosts.c
@@ -68,11 +68,6 @@ LINE_PARSER
{
if (IN6_IS_ADDR_V4MAPPED (entdata->host_addr))
memcpy (entdata->host_addr, entdata->host_addr + 12, INADDRSZ);
- else if (IN6_IS_ADDR_LOOPBACK (entdata->host_addr))
- {
- in_addr_t localhost = htonl (INADDR_LOOPBACK);
- memcpy (entdata->host_addr, &localhost, sizeof (localhost));
- }
else
/* Illegal address: ignore line. */
return 0;
++++++ glibc-memset-nontemporal.diff ++++++
Fix for bnc #868622, slow memset for large block sizes.
diff --git a/sysdeps/x86_64/memset.S b/sysdeps/x86_64/memset.S
index db4fb84..9c42018 100644
--- a/sysdeps/x86_64/memset.S
+++ b/sysdeps/x86_64/memset.S
@@ -84,6 +84,9 @@ L(loop_start):
movdqu %xmm8, -48(%rdi,%rdx)
movdqu %xmm8, 48(%rdi)
movdqu %xmm8, -64(%rdi,%rdx)
+ mov __x86_shared_cache_size(%rip),%r9d # The largest cache size
+ cmp %r9,%rdx
+ ja L(nt_move)
addq %rdi, %rdx
andq $-64, %rdx
cmpq %rdx, %rcx
@@ -99,6 +102,23 @@ L(loop):
jne L(loop)
rep
ret
+L(nt_move):
+ addq %rdi, %rdx
+ andq $-64, %rdx
+ cmpq %rdx, %rcx
+ je L(return)
+ .p2align 4
+L(nt_loop):
+ movntdq %xmm8, (%rcx)
+ movntdq %xmm8, 16(%rcx)
+ movntdq %xmm8, 32(%rcx)
+ movntdq %xmm8, 48(%rcx)
+ addq $64, %rcx
+ cmpq %rcx, %rdx
+ jne L(nt_loop)
+ sfence
+ rep
+ ret
L(less_16_bytes):
movq %xmm8, %rcx
testb $24, %dl
++++++ glibc-nodate.patch ++++++
Index: glibc-2.17.90/csu/Makefile
===================================================================
--- glibc-2.17.90.orig/csu/Makefile
+++ glibc-2.17.90/csu/Makefile
@@ -162,8 +162,8 @@ $(objpfx)version-info.h: $(common-objpfx
if [ -z "$$os" ]; then \
os=Linux; \
fi; \
- printf '"Compiled on a %s %s system on %s.\\n"\n' \
- "$$os" "$$version" "`date +%Y-%m-%d`";; \
+ printf '"Compiled on a %s %s system.\\n"\n' \
+ "$$os" "$$version";; \
*) ;; \
esac; \
files="$(all-Banner-files)"; \
Index: glibc-2.17.90/nscd/nscd_stat.c
===================================================================
--- glibc-2.17.90.orig/nscd/nscd_stat.c
+++ glibc-2.17.90/nscd/nscd_stat.c
@@ -36,8 +36,13 @@
#endif /* HAVE_SELINUX */
-/* We use this to make sure the receiver is the same. */
+/* We use this to make sure the receiver is the same. Capture mtime
+ of this file if possible. */
+#if defined(__TIMESTAMP__)
+static const char compilation[21] = __TIMESTAMP__;
+#else
static const char compilation[21] = __DATE__ " " __TIME__;
+#endif
/* Statistic data for one database. */
struct dbstat
++++++ glibc-nscd.conf.patch ++++++
Index: glibc-2.17.90/nscd/nscd.conf
===================================================================
--- glibc-2.17.90.orig/nscd/nscd.conf
+++ glibc-2.17.90/nscd/nscd.conf
@@ -61,11 +61,11 @@
auto-propagate group yes
enable-cache hosts yes
- positive-time-to-live hosts 3600
- negative-time-to-live hosts 20
+ positive-time-to-live hosts 600
+ negative-time-to-live hosts 0
suggested-size hosts 211
check-files hosts yes
- persistent hosts yes
+ persistent hosts no
shared hosts yes
max-db-size hosts 33554432
++++++ glibc-resolv-mdnshint.diff ++++++
Index: glibc-2.17.90/resolv/res_hconf.c
===================================================================
--- glibc-2.17.90.orig/resolv/res_hconf.c
+++ glibc-2.17.90/resolv/res_hconf.c
@@ -240,9 +240,12 @@ parse_line (const char *fname, int line_
if (c == NULL)
{
char *buf;
+ char *hint = "";
- if (__asprintf (&buf, _("%s: line %d: bad command `%s'\n"),
- fname, line_num, start) < 0)
+ if (__strncasecmp (start, "mdns", len) == 0 && len == 4)
+ hint = "Multicast DNS is now configured in /etc/nsswitch.conf instead.\nSee also the package and manpage of nss-mdns.\n";
+ if (__asprintf (&buf, _("%s: line %d: bad command `%s'\n%s"),
+ fname, line_num, start, hint) < 0)
return;
__fxprintf (NULL, "%s", buf);
++++++ glibc-resolv-reload.diff ++++++
From libc-alpha-return-22754-pasky=ucw.cz@sourceware.org Tue Mar 16 00:47:00 2010
Return-Path:
X-Original-To: pasky@pasky.or.cz
Delivered-To: pasky@pasky.or.cz
Received: from nikam.ms.mff.cuni.cz (nikam-dmz.ms.mff.cuni.cz [195.113.20.16])
by machine.or.cz (Postfix) with ESMTPS id C1B8586202A
for ; Tue, 16 Mar 2010 00:47:00 +0100 (CET)
Received: by nikam.ms.mff.cuni.cz (Postfix)
id 9CDEC9AC7A4; Tue, 16 Mar 2010 00:47:00 +0100 (CET)
Delivered-To: pasky@kam.mff.cuni.cz
Received: from jabberwock.ucw.cz (jabberwock.ucw.cz [89.250.246.4])
by nikam.ms.mff.cuni.cz (Postfix) with ESMTP id 99F0E9AC77B
for ; Tue, 16 Mar 2010 00:47:00 +0100 (CET)
Received: from sourceware.org (server1.sourceware.org [209.132.180.131])
by jabberwock.ucw.cz (Postfix) with SMTP id 14E1ACF040
for ; Tue, 16 Mar 2010 00:46:59 +0100 (CET)
Received: (qmail 18956 invoked by alias); 15 Mar 2010 23:46:58 -0000
Delivered-To: moderator for libc-alpha@sourceware.org
Received: (qmail 15843 invoked by uid 22791); 15 Mar 2010 17:23:15 -0000
X-SWARE-Spam-Status: No, hits=-2.6 required=5.0
tests=BAYES_00
X-Spam-Check-By: sourceware.org
Message-ID: <4B9E6CFA.7020002@riot.org>
Date: Mon, 15 Mar 2010 18:23:06 +0100
From: Sebastian Kienzl
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
MIME-Version: 1.0
To: libc-alpha@sourceware.org
Subject: Reloading of /etc/resolv.conf
Content-Type: multipart/mixed;
boundary="------------060407080409020101000002"
Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm
Precedence: bulk
List-Id:
List-Unsubscribe: mailto:libc-alpha-unsubscribe-pasky=ucw.cz@sourceware.org
List-Subscribe: mailto:libc-alpha-subscribe@sourceware.org
List-Archive: http://sourceware.org/ml/libc-alpha/
List-Post: mailto:libc-alpha@sourceware.org
List-Help: mailto:libc-alpha-help@sourceware.org, http://sourceware.org/ml/#faqs
Sender: libc-alpha-owner@sourceware.org
Delivered-To: mailing list libc-alpha@sourceware.org
This is a multi-part message in MIME format.
--------------060407080409020101000002
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Hello!
There's a patch in the wild against the resolver which makes it reload
/etc/resolv.conf on change, see
http://sources.redhat.com/ml/libc-alpha/2004-09/msg00130.html
However, this patch actually doesn't work properly for multi-threaded
programs, as only one thread will notice the change and refresh its
resolver state. I've attached a proper patch. It's for 2.5 but it should
work with current versions, too.
Even though the patch may not be interesting for upstream, I decided to
let you know about this problem, since the mentioned patch seems to be
used by at least Debian and Ubuntu.
Regards,
Seb.
--------------060407080409020101000002
Content-Type: text/plain;
name="glibc-2.5-resolvconf.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="glibc-2.5-resolvconf.patch"
Index: glibc-2.17.90/resolv/res_libc.c
===================================================================
--- glibc-2.17.90.orig/resolv/res_libc.c
+++ glibc-2.17.90/resolv/res_libc.c
@@ -22,7 +22,7 @@
#include
#include
#include
-
+#include
/* The following bit is copied from res_data.c (where it is #ifdef'ed
out) since res_init() should go into libc.so but the rest of that
@@ -89,12 +89,34 @@ res_init(void) {
return (__res_vinit(&_res, 1));
}
+static time_t resconf_mtime;
+__libc_lock_define_initialized (static, resconf_mtime_lock);
+
+/* Check if the modification time of resolv.conf has changed.
+ If so, have all threads re-initialize their resolver states */
+static void
+__res_check_resconf (void)
+{
+ struct stat statbuf;
+ if (stat (_PATH_RESCONF, &statbuf) == 0) {
+ __libc_lock_lock (resconf_mtime_lock);
+ if (statbuf.st_mtime != resconf_mtime) {
+ resconf_mtime = statbuf.st_mtime;
+ atomicinclock (lock);
+ atomicinc (__res_initstamp);
+ atomicincunlock (lock);
+ }
+ __libc_lock_unlock (resconf_mtime_lock);
+ }
+}
+
/* Initialize resp if RES_INIT is not yet set or if res_init in some other
thread requested re-initializing. */
int
__res_maybe_init (res_state resp, int preinit)
{
if (resp->options & RES_INIT) {
+ __res_check_resconf ();
if (__res_initstamp != resp->_u._ext.initstamp) {
if (resp->nscount > 0)
__res_iclose (resp, true);
++++++ glibc-testsuite.patch ++++++
test-lfs runs for ever on ReiserFS. Let's disable it completely.
Index: glibc-2.17.90/io/Makefile
===================================================================
--- glibc-2.17.90.orig/io/Makefile
+++ glibc-2.17.90/io/Makefile
@@ -63,7 +63,7 @@ static-only-routines = stat fstat lstat
others := pwd
test-srcs := ftwtest
-tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
+tests := test-utime test-stat test-stat2 tst-getcwd \
tst-fcntl bug-ftw1 bug-ftw2 bug-ftw3 bug-ftw4 tst-statvfs \
tst-openat tst-unlinkat tst-fstatat tst-futimesat \
tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
++++++ glibc-version.diff ++++++
Index: glibc-2.17.90/csu/version.c
===================================================================
--- glibc-2.17.90.orig/csu/version.c
+++ glibc-2.17.90/csu/version.c
@@ -24,11 +24,12 @@ static const char __libc_release[] = REL
static const char __libc_version[] = VERSION;
static const char banner[] =
-"GNU C Library "PKGVERSION RELEASE" release version "VERSION", by Roland McGrath et al.\n\
+"GNU C Library "PKGVERSION RELEASE" release version "VERSION" (git "GITID"), by Roland McGrath et al.\n\
Copyright (C) 2014 Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
PARTICULAR PURPOSE.\n\
+Configured for "CONFHOST".\n\
Compiled by GNU CC version "__VERSION__".\n"
#include "version-info.h"
#ifdef LIBC_ABIS_STRING
++++++ glibc.rpmlintrc ++++++
addFilter(".*glibc-profile.* devel-file-in-non-devel-package.*/usr/lib.*/lib.*_p.a")
addFilter(".*glibc.* incorrect-fsf-address")
# False positive - glibc implements gethostbyname
addFilter(".*binary-or-shlib-calls-gethostbyname")
# We do need to keep the symtab (see comments in glibc.spec), so this is intented:
addFilter(".*unstripped-binary-or-object.*")
# The duplication is intented:
addFilter(".*files-duplicate /usr/lib64/libbsd-compat.a /usr/lib.*/libg.a")
# ld.so is special:
addFilter(".*shared-lib-without-dependency-information /lib.*/ld-2.*.so")
# Handled via glibc_post_upgrade:
addFilter(".*permissions-missing-postin missing %set_permissions /usr/.*pt_chown in %post")
# Do not require permissions, this will lead to a cycle (bnc#700925):
addFilter("glibc\..*: permissions-missing-requires")
# We will not rename glibc to follow the shlib policy
addFilter("shlib-policy-missing-suffix")
# The dynamic linker and libnsl call exit - this is fine
addFilter(".*shared-lib-calls-exit.*")
# The man-pages package contains a number of man pages for programs that come
# with glibc, therefore do not warn about them
addFilter(".*glibc.*no-manual-page-for-binary getent")
addFilter(".*glibc.*no-manual-page-for-binary iconv")
addFilter(".*glibc.*no-manual-page-for-binary ldd")
addFilter(".*glibc.*no-manual-page-for-binary ldconfig")
addFilter(".*nscd.*no-manual-page-for-binary nscd")
++++++ glibc_post_upgrade.c ++++++
/* skeleton based on version from Fedora Core 3 */
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define verbose_exec(failcode, path...) \
do \
{ \
char *const arr[] = { path, NULL }; \
vexec (failcode, arr); \
} while (0)
__attribute__((noinline)) void vexec (int failcode, char *const path[]);
__attribute__((noinline)) void says (const char *str);
__attribute__((noinline)) void sayn (long num);
__attribute__((noinline)) void message (char *const path[]);
__attribute__((noinline)) int check_elf (const char *name);
int
main (void)
{
char initpath[256];
struct stat root, init_root;
/* First, get rid of platform-optimized libraries. We remove any we have
ever built, since otherwise we might end up using some old leftover
libraries when new ones aren't installed in their place anymore. */
#ifdef REMOVE_TLS_DIRS
const char *library[] = {"libc.so.6", "libc.so.6.1", "libm.so.6",
"libm.so.6.1", "librt.so.1", "librtkaio.so.1",
"libpthread.so.0", "libthread_db.so.1"};
const char *remove_dir[] = {
#ifdef __i386__
"/lib/i686/",
#endif
#ifdef __powerpc64__
#ifdef REMOVE_PPC_OPTIMIZE_POWER4
"/lib64/power4/",
"/lib64/ppc970/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_POWER5
"/lib64/power5/",
"/lib64/power5+/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_POWER6
"/lib64/power6/",
"/lib64/power6x/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_POWER7
"/lib64/power7/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_CELL
"/lib64/ppc-cell-be/",
#endif
#endif /* __powerpc64__ */
#ifdef __powerpc__
#ifdef REMOVE_PPC_OPTIMIZE_POWER4
"/lib/power4/",
"/lib/ppc970/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_POWER5
"/lib/power5/",
"/lib/power5+/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_POWER6
"/lib/power6/",
"/lib/power6x/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_POWER7
"/lib/power7/",
#endif
#ifdef REMOVE_PPC_OPTIMIZE_CELL
"/lib/ppc-cell-be/",
#endif
#endif /* __powerpc__ */
LIBDIR"/tls/" };
int i, j;
for (i = 0; i < sizeof (remove_dir) / sizeof (remove_dir[0]); ++i)
for (j = 0; j < sizeof (library) / sizeof (library[0]); j++)
{
char buf[strlen (remove_dir[i]) + strlen (library[j]) + 1];
char readlink_buf[(strlen (remove_dir[i]) + strlen (library[j])) * 2 + 30];
ssize_t len;
char *cp;
cp = stpcpy (buf, remove_dir[i]);
strcpy (cp, library[j]);
/* This file could be a symlink to library-%{version}.so, so check
this and don't remove only the link, but also the library itself. */
cp = stpcpy (readlink_buf, remove_dir[i]);
if ((len = readlink (buf, cp, (sizeof (readlink_buf)
- (cp - readlink_buf) - 1))) > 0)
{
cp[len] = '\0';
if (cp[0] != '/') cp = readlink_buf;
unlink (cp);
}
unlink (buf);
}
#endif
/* If installing bi-arch glibc, rpm sometimes doesn't unpack all files
before running one of the lib's %post scriptlet. /sbin/ldconfig will
then be run by the other arch's %post. */
if (access ("/sbin/ldconfig", X_OK) == 0)
verbose_exec (110, "/sbin/ldconfig", "/sbin/ldconfig", "-X");
if (utimes (GCONV_MODULES_DIR "/gconv-modules.cache", NULL) == 0)
{
#ifndef ICONVCONFIG
#define ICONVCONFIG "/usr/sbin/iconvconfig"
#endif
verbose_exec (113, ICONVCONFIG, "/usr/sbin/iconvconfig",
"-o", GCONV_MODULES_DIR"/gconv-modules.cache",
"--nostdlib", GCONV_MODULES_DIR);
}
/* Check if telinit is available and the init fifo as well. */
if (access ("/sbin/telinit", X_OK) || access ("/dev/initctl", F_OK))
_exit (0);
/* Check if we are not inside of some chroot, because we'd just
timeout and leave /etc/initrunlvl. */
if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
readlink ("/proc/1/root", initpath, 256) <= 0 ||
access ("/.buildenv", F_OK) == 0 || /* XEN build */
stat ("/proc/1/root", &init_root) < 0 ||
stat ("/", &root) < 0 ||
init_root.st_dev != root.st_dev || init_root.st_ino != root.st_ino)
_exit (0);
if (check_elf ("/proc/1/exe"))
verbose_exec (116, "/sbin/telinit", "/sbin/telinit", "u");
#if 0
/* Check if we can safely condrestart sshd. */
if (access ("/sbin/service", X_OK) == 0
&& access ("/usr/sbin/sshd", X_OK) == 0
&& access ("/bin/bash", X_OK) == 0)
{
if (check_elf ("/usr/sbin/sshd"))
verbose_exec (121, "/sbin/service", "/sbin/service", "sshd", "condrestart");
}
#endif
_exit(0);
}
void
vexec (int failcode, char *const path[])
{
pid_t pid;
int status, save_errno;
pid = vfork ();
if (pid == 0)
{
execv (path[0], path + 1);
save_errno = errno;
message (path);
says (" exec failed with errno ");
sayn (save_errno);
says ("\n");
_exit (failcode);
}
else if (pid < 0)
{
save_errno = errno;
message (path);
says (" fork failed with errno ");
sayn (save_errno);
says ("\n");
_exit (failcode + 1);
}
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
{
message (path);
says (" child terminated abnormally\n");
_exit (failcode + 2);
}
if (WEXITSTATUS (status))
{
message (path);
says (" child exited with exit code ");
sayn (WEXITSTATUS (status));
says ("\n");
_exit (WEXITSTATUS (status));
}
}
void
says (const char *str)
{
write (1, str, strlen (str));
}
void
sayn (long num)
{
char string[sizeof (long) * 3 + 1];
char *p = string + sizeof (string) - 1;
*p = '\0';
if (num == 0)
*--p = '0';
else
while (num)
{
*--p = '0' + num % 10;
num = num / 10;
}
says (p);
}
void
message (char *const path[])
{
says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
says (path[0]);
}
int
check_elf (const char *name)
{
/* Play safe, if we can't open or read, assume it might be
ELF for the current arch. */
int ret = 1;
int fd = open (name, O_RDONLY);
if (fd >= 0)
{
Elf32_Ehdr ehdr;
if (read (fd, &ehdr, offsetof (Elf32_Ehdr, e_version))
== offsetof (Elf32_Ehdr, e_version))
{
ret = 0;
if (ehdr.e_ident[EI_CLASS]
== (sizeof (long) == 8 ? ELFCLASS64 : ELFCLASS32))
{
#if defined __i386__
ret = ehdr.e_machine == EM_386;
#elif defined __x86_64__
ret = ehdr.e_machine == EM_X86_64;
#elif defined __ia64__
ret = ehdr.e_machine == EM_IA_64;
#elif defined __powerpc64__
ret = ehdr.e_machine == EM_PPC64;
#elif defined __powerpc__
ret = ehdr.e_machine == EM_PPC;
#elif defined __s390__ || defined __s390x__
ret = ehdr.e_machine == EM_S390;
#elif defined __x86_64__
ret = ehdr.e_machine == EM_X86_64;
#elif defined __sparc__
if (sizeof (long) == 8)
ret = ehdr.e_machine == EM_SPARCV9;
else
ret = (ehdr.e_machine == EM_SPARC
|| ehdr.e_machine == EM_SPARC32PLUS);
#else
ret = 1;
#endif
}
}
close (fd);
}
return ret;
}
#ifdef SMALL_BINARY
int __libc_multiple_threads __attribute__((nocommon));
int __libc_enable_asynccancel (void) { return 0; }
void __libc_disable_asynccancel (int x) { }
void __libc_csu_init (void) { }
void __libc_csu_fini (void) { }
pid_t __fork (void) { return -1; }
char thr_buf[65536];
#ifndef __powerpc__
int
__libc_start_main (int (*main) (void), int argc, char **argv,
void (*init) (void), void (*fini) (void),
void (*rtld_fini) (void), void * stack_end)
#else
struct startup_info
{
void *sda_base;
int (*main) (int, char **, char **, void *);
int (*init) (int, char **, char **, void *);
void (*fini) (void);
};
int
__libc_start_main (int argc, char **ubp_av, char **ubp_ev,
void *auxvec, void (*rtld_fini) (void),
struct startup_info *stinfo,
char **stack_on_entry)
#endif
{
#if defined __ia64__ || defined __powerpc64__
register void *r13 __asm ("r13") = thr_buf + 32768;
__asm ("" : : "r" (r13));
#elif defined __sparc__
register void *g6 __asm ("g6") = thr_buf + 32768;
# ifdef __arch64__
__thread_self = thr_buf + 32768;
# else
register void *__thread_self __asm ("g7") = thr_buf + 32768;
# endif
__asm ("" : : "r" (g6), "r" (__thread_self));
#elif defined __s390__ && !defined __s390x__
__asm ("sar %%a0,%0" : : "d" (thr_buf + 32768));
#elif defined __s390x__
__asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf + 32768) : "0");
#elif defined __powerpc__ && !defined __powerpc64__
register void *r2 __asm ("r2") = thr_buf + 32768;
__asm ("" : : "r" (r2));
#endif
main();
return 0;
}
#endif
++++++ glob-altdirfunc.patch ++++++
2016-05-04 Florian Weimer
[BZ #19779]
CVE-2016-1234
Avoid copying names of directory entries.
* posix/glob.c (DIRENT_MUST_BE, DIRENT_MIGHT_BE_SYMLINK)
(DIRENT_MIGHT_BE_DIR, CONVERT_D_INO, CONVERT_D_TYPE)
(CONVERT_DIRENT_DIRENT64, REAL_DIR_ENTRY): Remove macros.
(struct readdir_result): New type.
(D_TYPE_TO_RESULT, D_INO_TO_RESULT, READDIR_RESULT_INITIALIZER)
(GL_READDIR): New macros.
(readdir_result_might_be_symlink, readdir_result_might_be_dir)
(convert_dirent, convert_dirent64): New functions.
(glob_in_dir): Use struct readdir_result. Call convert_dirent or
convert_dirent64. Adjust references to the readdir result.
* sysdeps/unix/sysv/linux/i386/glob64.c:
(convert_dirent, GL_READDIR): Redefine for second file inclusion.
* posix/bug-glob2.c (LONG_NAME): Define.
(filesystem): Add LONG_NAME.
(my_DIR): Increase the size of room_for_dirent.
2016-04-29 Florian Weimer
glob: Simplify and document the interface for the GLOB_ALTDIRFUNC
callback function gl_readdir.
* posix/glob.c (NAMELEN, CONVERT_D_NAMLEN): Remove.
(CONVERT_DIRENT_DIRENT64): Use strcpy instead of memcpy.
(glob_in_dir): Remove len. Use strdup instead of malloc and
memcpy to copy the name.
* manual/pattern.texi (Calling Glob): Document requirements for
implementations of the gl_readdir callback function.
* manual/examples/mkdirent.c: New example.
* posix/bug-glob2.c (my_readdir): Set d_ino to 1 unconditionally,
per the manual guidance.
* posix/tst-gnuglob.c (my_readdir): Likewise.
Index: glibc-2.19/manual/examples/mkdirent.c
===================================================================
--- /dev/null
+++ glibc-2.19/manual/examples/mkdirent.c
@@ -0,0 +1,42 @@
+/* Example for creating a struct dirent object for use with glob.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, if not, see http://www.gnu.org/licenses/.
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+struct dirent *
+mkdirent (const char *name)
+{
+ size_t dirent_size = offsetof (struct dirent, d_name) + 1;
+ size_t name_length = strlen (name);
+ size_t total_size = dirent_size + name_length;
+ if (total_size < dirent_size)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ struct dirent *result = malloc (total_size);
+ if (result == NULL)
+ return NULL;
+ result->d_type = DT_UNKNOWN;
+ result->d_ino = 1; /* Do not skip this entry. */
+ memcpy (result->d_name, name, name_length + 1);
+ return result;
+}
Index: glibc-2.19/manual/pattern.texi
===================================================================
--- glibc-2.19.orig/manual/pattern.texi
+++ glibc-2.19/manual/pattern.texi
@@ -237,7 +237,44 @@ function used to read the contents of a
@code{GLOB_ALTDIRFUNC} bit is set in the flag parameter. The type of
this field is @w{@code{struct dirent *(*) (void *)}}.
-This is a GNU extension.
+An implementation of @code{gl_readdir} needs to initialize the following
+members of the @code{struct dirent} object:
+
+@table @code
+@item d_type
+This member should be set to the file type of the entry if it is known.
+Otherwise, the value @code{DT_UNKNOWN} can be used. The @code{glob}
+function may use the specified file type to avoid callbacks in cases
+where the file type indicates that the data is not required.
+
+@item d_ino
+This member needs to be non-zero, otherwise @code{glob} may skip the
+current entry and call the @code{gl_readdir} callback function again to
+retrieve another entry.
+
+@item d_name
+This member must be set to the name of the entry. It must be
+null-terminated.
+@end table
+
+The example below shows how to allocate a @code{struct dirent} object
+containing a given name.
+
+@smallexample
+@include mkdirent.c.texi
+@end smallexample
+
+The @code{glob} function reads the @code{struct dirent} members listed
+above and makes a copy of the file name in the @code{d_name} member
+immediately after the @code{gl_readdir} callback function returns.
+Future invocations of any of the callback functions may dealloacte or
+reuse the buffer. It is the responsibility of the caller of the
+@code{glob} function to allocate and deallocate the buffer, around the
+call to @code{glob} or using the callback functions. For example, an
+application could allocate the buffer in the @code{gl_readdir} callback
+function, and deallocate it in the @code{gl_closedir} callback function.
+
+The @code{gl_readdir} member is a GNU extension.
@item gl_opendir
The address of an alternative implementation of the @code{opendir}
Index: glibc-2.19/posix/bug-glob2.c
===================================================================
--- glibc-2.19.orig/posix/bug-glob2.c
+++ glibc-2.19/posix/bug-glob2.c
@@ -40,6 +40,17 @@
# define PRINTF(fmt, args...)
#endif
+#define LONG_NAME \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
static struct
{
@@ -58,6 +69,7 @@ static struct
{ ".", 3, DT_DIR, 0755 },
{ "..", 3, DT_DIR, 0755 },
{ "a", 3, DT_REG, 0644 },
+ { LONG_NAME, 3, DT_REG, 0644 },
{ "unreadable", 2, DT_DIR, 0111 },
{ ".", 3, DT_DIR, 0111 },
{ "..", 3, DT_DIR, 0755 },
@@ -75,7 +87,7 @@ typedef struct
int level;
int idx;
struct dirent d;
- char room_for_dirent[NAME_MAX];
+ char room_for_dirent[sizeof (LONG_NAME)];
} my_DIR;
@@ -193,7 +205,7 @@ my_readdir (void *gdir)
return NULL;
}
- dir->d.d_ino = dir->idx;
+ dir->d.d_ino = 1; /* glob should not skip this entry. */
#ifdef _DIRENT_HAVE_D_TYPE
dir->d.d_type = filesystem[dir->idx].type;
Index: glibc-2.19/posix/glob.c
===================================================================
--- glibc-2.19.orig/posix/glob.c
+++ glibc-2.19/posix/glob.c
@@ -24,7 +24,9 @@
#include
#include
#include
+#include
#include
+#include
/* Outcomment the following line for production quality code. */
/* #define NDEBUG 1 */
@@ -57,10 +59,8 @@
#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
# include
-# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include
# endif
@@ -75,82 +75,8 @@
# endif /* HAVE_VMSDIR_H */
#endif
-
-/* In GNU systems, defines this macro for us. */
-#ifdef _D_NAMLEN
-# undef NAMLEN
-# define NAMLEN(d) _D_NAMLEN(d)
-#endif
-
-/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
- if the `d_type' member for `struct dirent' is available.
- HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
-#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
-/* True if the directory entry D must be of type T. */
-# define DIRENT_MUST_BE(d, t) ((d)->d_type == (t))
-
-/* True if the directory entry D might be a symbolic link. */
-# define DIRENT_MIGHT_BE_SYMLINK(d) \
- ((d)->d_type == DT_UNKNOWN || (d)->d_type == DT_LNK)
-
-/* True if the directory entry D might be a directory. */
-# define DIRENT_MIGHT_BE_DIR(d) \
- ((d)->d_type == DT_DIR || DIRENT_MIGHT_BE_SYMLINK (d))
-
-#else /* !HAVE_D_TYPE */
-# define DIRENT_MUST_BE(d, t) false
-# define DIRENT_MIGHT_BE_SYMLINK(d) true
-# define DIRENT_MIGHT_BE_DIR(d) true
-#endif /* HAVE_D_TYPE */
-
-/* If the system has the `struct dirent64' type we use it internally. */
-#if defined _LIBC && !defined COMPILE_GLOB64
-# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
-# define CONVERT_D_NAMLEN(d64, d32)
-# else
-# define CONVERT_D_NAMLEN(d64, d32) \
- (d64)->d_namlen = (d32)->d_namlen;
-# endif
-
-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
-# define CONVERT_D_INO(d64, d32)
-# else
-# define CONVERT_D_INO(d64, d32) \
- (d64)->d_ino = (d32)->d_ino;
-# endif
-
-# ifdef _DIRENT_HAVE_D_TYPE
-# define CONVERT_D_TYPE(d64, d32) \
- (d64)->d_type = (d32)->d_type;
-# else
-# define CONVERT_D_TYPE(d64, d32)
-# endif
-
-# define CONVERT_DIRENT_DIRENT64(d64, d32) \
- memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
- CONVERT_D_NAMLEN (d64, d32) \
- CONVERT_D_INO (d64, d32) \
- CONVERT_D_TYPE (d64, d32)
-#endif
-
-
-#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
-/* Posix does not require that the d_ino field be present, and some
- systems do not provide it. */
-# define REAL_DIR_ENTRY(dp) 1
-#else
-# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
-#endif /* POSIX */
-
#include
#include
-
-/* NAME_MAX is usually defined in or . */
-#include
-#ifndef NAME_MAX
-# define NAME_MAX (sizeof (((struct dirent *) 0)->d_name))
-#endif
-
#include
#ifdef _LIBC
@@ -195,8 +121,111 @@
static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
+/* A representation of a directory entry which does not depend on the
+ layout of struct dirent, or the size of ino_t. */
+struct readdir_result
+{
+ const char *name;
+# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+ uint8_t type;
+# endif
+ bool skip_entry;
+};
+
+# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+/* Initializer based on the d_type member of struct dirent. */
+# define D_TYPE_TO_RESULT(source) (source)->d_type,
+
+/* True if the directory entry D might be a symbolic link. */
+static bool
+readdir_result_might_be_symlink (struct readdir_result d)
+{
+ return d.type == DT_UNKNOWN || d.type == DT_LNK;
+}
+
+/* True if the directory entry D might be a directory. */
+static bool
+readdir_result_might_be_dir (struct readdir_result d)
+{
+ return d.type == DT_DIR || readdir_result_might_be_symlink (d);
+}
+# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
+# define D_TYPE_TO_RESULT(source)
+
+/* If we do not have type information, symbolic links and directories
+ are always a possibility. */
+
+static bool
+readdir_result_might_be_symlink (struct readdir_result d)
+{
+ return true;
+}
+
+static bool
+readdir_result_might_be_dir (struct readdir_result d)
+{
+ return true;
+}
+
+# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
+
+# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
+/* Initializer for skip_entry. POSIX does not require that the d_ino
+ field be present, and some systems do not provide it. */
+# define D_INO_TO_RESULT(source) false,
+# else
+# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
+# endif
+
+/* Construct an initializer for a struct readdir_result object from a
+ struct dirent *. No copy of the name is made. */
+#define READDIR_RESULT_INITIALIZER(source) \
+ { \
+ source->d_name, \
+ D_TYPE_TO_RESULT (source) \
+ D_INO_TO_RESULT (source) \
+ }
+
#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
+/* Call gl_readdir on STREAM. This macro can be overridden to reduce
+ type safety if an old interface version needs to be supported. */
+#ifndef GL_READDIR
+# define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
+#endif
+
+/* Extract name and type from directory entry. No copy of the name is
+ made. If SOURCE is NULL, result name is NULL. Keep in sync with
+ convert_dirent64 below. */
+static struct readdir_result
+convert_dirent (const struct dirent *source)
+{
+ if (source == NULL)
+ {
+ struct readdir_result result = { NULL, };
+ return result;
+ }
+ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
+ return result;
+}
+
+#ifndef COMPILE_GLOB64
+/* Like convert_dirent, but works on struct dirent64 instead. Keep in
+ sync with convert_dirent above. */
+static struct readdir_result
+convert_dirent64 (const struct dirent64 *source)
+{
+ if (source == NULL)
+ {
+ struct readdir_result result = { NULL, };
+ return result;
+ }
+ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
+ return result;
+}
+#endif
+
+
#ifndef attribute_hidden
# define attribute_hidden
#endif
@@ -1561,56 +1590,36 @@ glob_in_dir (const char *pattern, const
while (1)
{
- const char *name;
- size_t len;
-#if defined _LIBC && !defined COMPILE_GLOB64
- struct dirent64 *d;
- union
- {
- struct dirent64 d64;
- char room [offsetof (struct dirent64, d_name[0])
- + NAME_MAX + 1];
- }
- d64buf;
-
- if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
- {
- struct dirent *d32 = (*pglob->gl_readdir) (stream);
- if (d32 != NULL)
- {
- CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
- d = &d64buf.d64;
- }
- else
- d = NULL;
- }
- else
- d = __readdir64 (stream);
+ struct readdir_result d;
+ {
+ if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
+ d = convert_dirent (GL_READDIR (pglob, stream));
+ else
+ {
+#ifdef COMPILE_GLOB64
+ d = convert_dirent (__readdir (stream));
#else
- struct dirent *d = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
- ? ((struct dirent *)
- (*pglob->gl_readdir) (stream))
- : __readdir (stream));
+ d = convert_dirent64 (__readdir64 (stream));
#endif
- if (d == NULL)
+ }
+ }
+ if (d.name == NULL)
break;
- if (! REAL_DIR_ENTRY (d))
+ if (d.skip_entry)
continue;
/* If we shall match only directories use the information
provided by the dirent call if possible. */
- if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
+ if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d))
continue;
- name = d->d_name;
-
- if (fnmatch (pattern, name, fnm_flags) == 0)
+ if (fnmatch (pattern, d.name, fnm_flags) == 0)
{
/* If the file we found is a symlink we have to
make sure the target file exists. */
- if (!DIRENT_MIGHT_BE_SYMLINK (d)
- || link_exists_p (dfd, directory, dirlen, name, pglob,
- flags))
+ if (!readdir_result_might_be_symlink (d)
+ || link_exists_p (dfd, directory, dirlen, d.name,
+ pglob, flags))
{
if (cur == names->count)
{
@@ -1630,12 +1639,10 @@ glob_in_dir (const char *pattern, const
names = newnames;
cur = 0;
}
- len = NAMLEN (d);
- names->name[cur] = (char *) malloc (len + 1);
+ names->name[cur] = strdup (d.name);
if (names->name[cur] == NULL)
goto memory_error;
- *((char *) mempcpy (names->name[cur++], name, len))
- = '\0';
+ ++cur;
++nfound;
}
}
Index: glibc-2.19/posix/tst-gnuglob.c
===================================================================
--- glibc-2.19.orig/posix/tst-gnuglob.c
+++ glibc-2.19/posix/tst-gnuglob.c
@@ -211,7 +211,7 @@ my_readdir (void *gdir)
return NULL;
}
- dir->d.d_ino = dir->idx;
+ dir->d.d_ino = 1; /* glob should not skip this entry. */
#ifdef _DIRENT_HAVE_D_TYPE
dir->d.d_type = filesystem[dir->idx].type;
Index: glibc-2.19/sysdeps/unix/sysv/linux/i386/glob64.c
===================================================================
--- glibc-2.19.orig/sysdeps/unix/sysv/linux/i386/glob64.c
+++ glibc-2.19/sysdeps/unix/sysv/linux/i386/glob64.c
@@ -1,3 +1,21 @@
+/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
+ Copyright (C) 1998-2016 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
#include
#include
@@ -38,11 +56,15 @@ int __old_glob64 (const char *__pattern,
#undef dirent
#define dirent __old_dirent64
+#undef GL_READDIR
+# define GL_READDIR(pglob, stream) \
+ ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
#undef __readdir
#define __readdir(dirp) __old_readdir64 (dirp)
#undef glob
#define glob(pattern, flags, errfunc, pglob) \
__old_glob64 (pattern, flags, errfunc, pglob)
+#define convert_dirent __old_convert_dirent
#define glob_in_dir __old_glob_in_dir
#define GLOB_ATTRIBUTE attribute_compat_text_section
++++++ hcreate-overflow-check.patch ++++++
2016-01-27 Paul Eggert
[BZ #18240]
* misc/hsearch_r.c (isprime, __hcreate_r): Protect against
unsigned int wraparound.
2016-01-27 Florian Weimer
[BZ #18240]
* misc/bug18240.c: New test.
* misc/Makefile (tests): Add it.
2015-08-25 Ondřej Bílka
[BZ #18240]
* misc/hsearch_r.c (__hcreate_r): Handle overflow.
Index: glibc-2.19/misc/Makefile
===================================================================
--- glibc-2.19.orig/misc/Makefile
+++ glibc-2.19/misc/Makefile
@@ -76,7 +76,8 @@ install-lib := libg.a
gpl2lgpl := error.c error.h
tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
+ tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
+ bug18240
ifeq ($(run-built-tests),yes)
tests: $(objpfx)tst-error1-mem
endif
Index: glibc-2.19/misc/bug18240.c
===================================================================
--- /dev/null
+++ glibc-2.19/misc/bug18240.c
@@ -0,0 +1,75 @@
+/* Test integer wraparound in hcreate.
+ Copyright (C) 2016 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
+#include
+#include
+#include
+#include
+#include
+
+static void
+test_size (size_t size)
+{
+ int res = hcreate (size);
+ if (res == 0)
+ {
+ if (errno == ENOMEM)
+ return;
+ printf ("error: hcreate (%zu): %m\n", size);
+ exit (1);
+ }
+ char *keys[100];
+ for (int i = 0; i < 100; ++i)
+ {
+ if (asprintf (keys + i, "%d", i) < 0)
+ {
+ printf ("error: asprintf: %m\n");
+ exit (1);
+ }
+ ENTRY e = { keys[i], (char *) "value" };
+ if (hsearch (e, ENTER) == NULL)
+ {
+ printf ("error: hsearch (\"%s\"): %m\n", keys[i]);
+ exit (1);
+ }
+ }
+ hdestroy ();
+
+ for (int i = 0; i < 100; ++i)
+ free (keys[i]);
+}
+
+static int
+do_test (void)
+{
+ test_size (500);
+ test_size (-1);
+ test_size (-3);
+ test_size (INT_MAX - 2);
+ test_size (INT_MAX - 1);
+ test_size (INT_MAX);
+ test_size (((unsigned) INT_MAX) + 1);
+ test_size (UINT_MAX - 2);
+ test_size (UINT_MAX - 1);
+ test_size (UINT_MAX);
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: glibc-2.19/misc/hsearch_r.c
===================================================================
--- glibc-2.19.orig/misc/hsearch_r.c
+++ glibc-2.19/misc/hsearch_r.c
@@ -19,7 +19,7 @@
#include
#include
#include
-
+#include
#include
/* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
@@ -46,15 +46,12 @@ static int
isprime (unsigned int number)
{
/* no even number will be passed */
- unsigned int div = 3;
-
- while (div * div < number && number % div != 0)
- div += 2;
-
- return number % div != 0;
+ for (unsigned int div = 3; div <= number / div; div += 2)
+ if (number % div == 0)
+ return 0;
+ return 1;
}
-
/* Before using the hash table we must allocate memory for it.
Test for an existing table are done. We allocate one element
more as the found prime number says. This is done for more effective
@@ -81,10 +78,19 @@ hcreate_r (nel, htab)
use will not work. */
if (nel < 3)
nel = 3;
- /* Change nel to the first prime number not smaller as nel. */
- nel |= 1; /* make odd */
- while (!isprime (nel))
- nel += 2;
+
+ /* Change nel to the first prime number in the range [nel, UINT_MAX - 2],
+ The '- 2' means 'nel += 2' cannot overflow. */
+ for (nel |= 1; ; nel += 2)
+ {
+ if (UINT_MAX - 2 < nel)
+ {
+ __set_errno (ENOMEM);
+ return 0;
+ }
+ if (isprime (nel))
+ break;
+ }
htab->size = nel;
htab->filled = 0;
++++++ ibm-long-double-frexpl.patch ++++++
2014-04-16 Alan Modra
[BZ #16740]
[BZ #16619]
* sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Rewrite.
* math/libm-test.inc (frexp_test_data): Add tests.
Index: glibc-2.19/math/libm-test.inc
===================================================================
--- glibc-2.19.orig/math/libm-test.inc
+++ glibc-2.19/math/libm-test.inc
@@ -8723,6 +8723,15 @@ static const struct test_f_f1_data frexp
TEST_fI_f1 (frexp, 12.8L, 0.8L, 4, NO_INEXACT_EXCEPTION),
TEST_fI_f1 (frexp, -27.34L, -0.854375L, 5, NO_INEXACT_EXCEPTION),
+
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+ TEST_fI_f1 (frexp, 1.0L-0x1p-106L, 1.0L-0x1p-106L, 0, NO_INEXACT_EXCEPTION),
+ TEST_fI_f1 (frexp, 1.0L, 0.5L, 1, NO_INEXACT_EXCEPTION),
+ TEST_fI_f1 (frexp, 1.0L+0x1p-105L, 0.5L+0x1p-106L, 1, NO_INEXACT_EXCEPTION),
+ TEST_fI_f1 (frexp, -1.0L+0x1p-106L, -1.0L+0x1p-106L, 0, NO_INEXACT_EXCEPTION),
+ TEST_fI_f1 (frexp, -1.0L, -0.5L, 1, NO_INEXACT_EXCEPTION),
+ TEST_fI_f1 (frexp, -1.0L-0x1p-105L, -0.5L-0x1p-106L, 1, NO_INEXACT_EXCEPTION),
+#endif
};
static void
Index: glibc-2.19/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
===================================================================
--- glibc-2.19.orig/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
+++ glibc-2.19/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
@@ -31,57 +31,115 @@ static char rcsid[] = "$NetBSD: $";
#include
#include
-static const long double
-two107 = 162259276829213363391578010288128.0; /* 0x4670000000000000, 0 */
-
long double __frexpl(long double x, int *eptr)
{
- uint64_t hx, lx, ix, ixl;
- int64_t explo;
- double xhi, xlo;
-
- ldbl_unpack (x, &xhi, &xlo);
- EXTRACT_WORDS64 (hx, xhi);
- EXTRACT_WORDS64 (lx, xlo);
- ixl = 0x7fffffffffffffffULL&lx;
- ix = 0x7fffffffffffffffULL&hx;
- *eptr = 0;
- if(ix>=0x7ff0000000000000ULL||ix==0) return x; /* 0,inf,nan */
- if (ix<0x0010000000000000ULL) { /* subnormal */
- x *= two107;
- xhi = ldbl_high (x);
- EXTRACT_WORDS64 (hx, xhi);
- ix = hx&0x7fffffffffffffffULL;
- *eptr = -107;
+ uint64_t hx, lx, ix, ixl;
+ int64_t explo, expon;
+ double xhi, xlo;
+
+ ldbl_unpack (x, &xhi, &xlo);
+ EXTRACT_WORDS64 (hx, xhi);
+ EXTRACT_WORDS64 (lx, xlo);
+ ixl = 0x7fffffffffffffffULL & lx;
+ ix = 0x7fffffffffffffffULL & hx;
+ expon = 0;
+ if (ix >= 0x7ff0000000000000ULL || ix == 0)
+ {
+ /* 0,inf,nan. */
+ *eptr = expon;
+ return x;
+ }
+ expon = ix >> 52;
+ if (expon == 0)
+ {
+ /* Denormal high double, the low double must be 0.0. */
+ int cnt;
+
+ /* Normalize. */
+ if (sizeof (ix) == sizeof (long))
+ cnt = __builtin_clzl (ix);
+ else if ((ix >> 32) != 0)
+ cnt = __builtin_clzl ((long) (ix >> 32));
+ else
+ cnt = __builtin_clzl ((long) ix) + 32;
+ cnt = cnt - 12;
+ expon -= cnt;
+ ix <<= cnt + 1;
+ }
+ expon -= 1022;
+ ix &= 0x000fffffffffffffULL;
+ hx &= 0x8000000000000000ULL;
+ hx |= (1022LL << 52) | ix;
+
+ if (ixl != 0)
+ {
+ /* If the high double is an exact power of two and the low
+ double has the opposite sign, then the exponent calculated
+ from the high double is one too big. */
+ if (ix == 0
+ && (int64_t) (hx ^ lx) < 0)
+ {
+ hx += 1L << 52;
+ expon -= 1;
+ }
+
+ explo = ixl >> 52;
+ if (explo == 0)
+ {
+ /* The low double started out as a denormal. Normalize its
+ mantissa and adjust the exponent. */
+ int cnt;
+
+ if (sizeof (ixl) == sizeof (long))
+ cnt = __builtin_clzl (ixl);
+ else if ((ixl >> 32) != 0)
+ cnt = __builtin_clzl ((long) (ixl >> 32));
+ else
+ cnt = __builtin_clzl ((long) ixl) + 32;
+ cnt = cnt - 12;
+ explo -= cnt;
+ ixl <<= cnt + 1;
+ }
+
+ /* With variable precision we can't assume much about the
+ magnitude of the returned low double. It may even be a
+ denormal. */
+ explo -= expon;
+ ixl &= 0x000fffffffffffffULL;
+ lx &= 0x8000000000000000ULL;
+ if (explo <= 0)
+ {
+ /* Handle denormal low double. */
+ if (explo > -52)
+ {
+ ixl |= 1LL << 52;
+ ixl >>= 1 - explo;
+ }
+ else
+ {
+ ixl = 0;
+ lx = 0;
+ if ((hx & 0x7ff0000000000000ULL) == (1023LL << 52))
+ {
+ /* Oops, the adjustment we made above for values a
+ little smaller than powers of two turned out to
+ be wrong since the returned low double will be
+ zero. This can happen if the input was
+ something weird like 0x1p1000 - 0x1p-1000. */
+ hx -= 1L << 52;
+ expon += 1;
+ }
+ }
+ explo = 0;
}
- *eptr += (ix>>52)-1022;
+ lx |= (explo << 52) | ixl;
+ }
- if (ixl != 0ULL) {
- explo = (ixl>>52) - (ix>>52) + 0x3fe;
- if ((ixl&0x7ff0000000000000ULL) == 0LL) {
- /* the lower double is a denormal so we need to correct its
- mantissa and perhaps its exponent. */
- int cnt;
-
- if (sizeof (ixl) == sizeof (long))
- cnt = __builtin_clzl (ixl);
- else if ((ixl >> 32) != 0)
- cnt = __builtin_clzl ((long) (ixl >> 32));
- else
- cnt = __builtin_clzl ((long) ixl) + 32;
- cnt = cnt - 12;
- lx = (lx&0x8000000000000000ULL) | ((explo-cnt)<<52)
- | ((ixl<<(cnt+1))&0x000fffffffffffffULL);
- } else
- lx = (lx&0x800fffffffffffffULL) | (explo<<52);
- } else
- lx = 0ULL;
-
- hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL;
- INSERT_WORDS64 (xhi, hx);
- INSERT_WORDS64 (xlo, lx);
- x = ldbl_pack (xhi, xlo);
- return x;
+ INSERT_WORDS64 (xhi, hx);
+ INSERT_WORDS64 (xlo, lx);
+ x = ldbl_pack (xhi, xlo);
+ *eptr = expon;
+ return x;
}
#ifdef IS_IN_libm
long_double_symbol (libm, __frexpl, frexpl);
++++++ ibm-long-double-math.patch ++++++
2014-03-14 Adhemerval Zanella
[BZ #16707]
* sysdeps/powerpc/powerpc64/fpu/s_roundl.S: Remove wrong
implementation.
* math/libm-test.inc (round_test_data): Add more tests.
[BZ #16706]
* sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S: Remove wrong
implementation.
* math/libm-test.inc (nearbyint_test_data): Add more tests.
[BZ #16701]
* sysdeps/powerpc/powerpc64/fpu/s_ceill.S: Remove wrong
implementation.
* math/libm-test.inc (ceil_test_data): Add more tests.
Index: glibc-2.19/math/libm-test.inc
===================================================================
--- glibc-2.19.orig/math/libm-test.inc
+++ glibc-2.19/math/libm-test.inc
@@ -6000,6 +6000,15 @@ static const struct test_f_f_data ceil_t
TEST_f_f (ceil, -72057594037927936.75L, -72057594037927936.0L),
TEST_f_f (ceil, -72057594037927937.5L, -72057594037927937.0L),
+ /* Check cases where first double is a exact integer higher than 2^52 and
+ the precision is determined by second long double for IBM long double. */
+ TEST_f_f (ceil, 34503599627370498.515625L, 34503599627370499.0L),
+ TEST_f_f (ceil, -34503599627370498.515625L, -34503599627370498.0L),
+# if LDBL_MANT_DIG >= 106
+ TEST_f_f (ceil, 1192568192774434123539907640624.484375L, 1192568192774434123539907640625.0L),
+ TEST_f_f (ceil, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+
TEST_f_f (ceil, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L),
TEST_f_f (ceil, 10141204801825835211973625643008.25L, 10141204801825835211973625643009.0L),
TEST_f_f (ceil, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L),
@@ -10495,6 +10504,16 @@ static const struct test_f_f_data nearby
TEST_f_f (nearbyint, -562949953421312.75, -562949953421313.0, NO_INEXACT_EXCEPTION),
TEST_f_f (nearbyint, -1125899906842624.75, -1125899906842625.0, NO_INEXACT_EXCEPTION),
#endif
+#ifdef TEST_LDOUBLE
+ /* Check cases where first double is a exact integer higher than 2^52 and
+ the precision is determined by second long double for IBM long double. */
+ TEST_f_f (nearbyint, 34503599627370498.515625L, 34503599627370499.0L),
+ TEST_f_f (nearbyint, -34503599627370498.515625L, -34503599627370499.0L),
+# if LDBL_MANT_DIG >= 106
+ TEST_f_f (nearbyint, 1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
+ TEST_f_f (nearbyint, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+#endif
};
static void
@@ -11792,6 +11811,15 @@ static const struct test_f_f_data round_
TEST_f_f (round, -72057594037927936.75L, -72057594037927937.0L),
TEST_f_f (round, -72057594037927937.5L, -72057594037927938.0L),
+ /* Check cases where first double is a exact integer higher than 2^52 and
+ the precision is determined by second long double for IBM long double. */
+ TEST_f_f (round, 34503599627370498.515625L, 34503599627370499.0L),
+ TEST_f_f (round, -34503599627370498.515625L, -34503599627370499.0L),
+# if LDBL_MANT_DIG >= 106
+ TEST_f_f (round, 1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
+ TEST_f_f (round, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+
TEST_f_f (round, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L),
TEST_f_f (round, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L),
TEST_f_f (round, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L),
Index: glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_ceill.S
===================================================================
--- glibc-2.19.orig/sysdeps/powerpc/powerpc64/fpu/s_ceill.S
+++ /dev/null
@@ -1,132 +0,0 @@
-/* s_ceill.S IBM extended format long double version.
- Copyright (C) 2004-2014 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
-#include
-
- .section ".toc","aw"
-.LC0: /* 2**52 */
- .tc FD_43300000_0[TC],0x4330000000000000
-
- .section ".text"
-
-/* long double [fp1,fp2] ceill (long double x [fp1,fp2])
- IEEE 1003.1 ceil function.
-
- PowerPC64 long double uses the IBM extended format which is
- represented two 64-floating point double values. The values are
- non-overlapping giving an effective precision of 106 bits. The first
- double contains the high order bits of mantissa and is always ceiled
- to represent a normal ceiling of long double to double. Since the
- long double value is sum of the high and low values, the low double
- normally has the opposite sign to compensate for the this ceiling.
-
- For long double there are two cases:
- 1) |x| < 2**52, all the integer bits are in the high double.
- ceil the high double and set the low double to -0.0.
- 2) |x| >= 2**52, ceiling involves both doubles.
- See the comment before label .L2 for details.
- */
-
-ENTRY (__ceill)
- mffs fp11 /* Save current FPU rounding mode. */
- lfd fp13,.LC0@toc(2)
- fabs fp0,fp1
- fabs fp9,fp2
- fsub fp12,fp13,fp13 /* generate 0.0 */
- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
- bnl- cr7,.L2
- mtfsfi 7,2 /* Set rounding mode toward +inf. */
- fneg fp2,fp12
- ble- cr6,.L1
- fadd fp1,fp1,fp13 /* x+= TWO52; */
- fsub fp1,fp1,fp13 /* x-= TWO52; */
- fabs fp1,fp1 /* if (x == 0.0) */
-.L0:
- mtfsf 0x01,fp11 /* restore previous rounding mode. */
- blr /* x = 0.0; */
-.L1:
- bge- cr6,.L0 /* if (x < 0.0) */
- fsub fp1,fp1,fp13 /* x-= TWO52; */
- fadd fp1,fp1,fp13 /* x+= TWO52; */
- fcmpu cr5,fp1,fp12 /* if (x > 0.0) */
- mtfsf 0x01,fp11 /* restore previous rounding mode. */
- fnabs fp1,fp1 /* if (x == 0.0) */
- blr /* x = -0.0; */
-
-/* The high double is > TWO52 so we need to round the low double and
- perhaps the high double. In this case we have to round the low
- double and handle any adjustment to the high double that may be
- caused by rounding (up). This is complicated by the fact that the
- high double may already be rounded and the low double may have the
- opposite sign to compensate.This gets a bit tricky so we use the
- following algorithm:
-
- tau = floor(x_high/TWO52);
- x0 = x_high - tau;
- x1 = x_low + tau;
- r1 = rint(x1);
- y_high = x0 + r1;
- y_low = x0 - y_high + r1;
- return y; */
-.L2:
- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
- bgelr- cr7 /* return x; */
- beqlr- cr0
- mtfsfi 7,2 /* Set rounding mode toward +inf. */
- fdiv fp8,fp1,fp13 /* x_high/TWO52 */
-
- bng- cr6,.L6 /* if (x > 0.0) */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
- bng cr5,.L4 /* if (x_low > 0.0) */
- fmr fp3,fp1
- fmr fp4,fp2
- b .L5
-.L4: /* if (x_low < 0.0) */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-.L5:
- fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */
- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
- b .L9
-.L6: /* if (x < 0.0) */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
- bnl cr5,.L7 /* if (x_low < 0.0) */
- fmr fp3,fp1
- fmr fp4,fp2
- b .L8
-.L7: /* if (x_low > 0.0) */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-.L8:
- fsub fp5,fp4,fp13 /* r1-= TWO52; */
- fadd fp5,fp5,fp13 /* r1+= TWO52; */
-.L9:
- mtfsf 0x01,fp11 /* restore previous rounding mode. */
- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
- fadd fp2,fp2,fp5
- blr
-END (__ceill)
-
-long_double_symbol (libm, __ceill, ceill)
Index: glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S
===================================================================
--- glibc-2.19.orig/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* nearbyint long double.
- IBM extended format long double version.
- Copyright (C) 2004-2014 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
-#include
-
- .section ".toc","aw"
-.LC0: /* 2**52 */
- .tc FD_43300000_0[TC],0x4330000000000000
- .section ".text"
-
-/* long double [fp1,fp2] nearbyintl (long double x [fp1,fp2])
- IEEE 1003.1 nearbyintl function. nearbyintl is similar to the rintl
- but does raise the "inexact" exception. This implementation is
- based on rintl but explicitly masks the inexact exception on entry
- and clears any pending inexact before restoring the exception mask
- on exit.
-
- PowerPC64 long double uses the IBM extended format which is
- represented two 64-floating point double values. The values are
- non-overlapping giving an effective precision of 106 bits. The first
- double contains the high order bits of mantissa and is always rounded
- to represent a normal rounding of long double to double. Since the
- long double value is sum of the high and low values, the low double
- normally has the opposite sign to compensate for the this rounding.
-
- For long double there are two cases:
- 1) |x| < 2**52, all the integer bits are in the high double.
- floor the high double and set the low double to -0.0.
- 2) |x| >= 2**52, Rounding involves both doubles.
- See the comment before label .L2 for details.
- */
-ENTRY (__nearbyintl)
- mffs fp11 /* Save current FPSCR. */
- lfd fp13,.LC0@toc(2)
- fabs fp0,fp1
- mtfsb0 28 /* Disable "inexact" exceptions. */
- fsub fp12,fp13,fp13 /* generate 0.0 */
- fabs fp9,fp2
- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
- bnl- cr7,.L2
- fmr fp2,fp12
- bng- cr6,.L4
- fadd fp1,fp1,fp13 /* x+= TWO52; */
- fsub fp1,fp1,fp13 /* x-= TWO52; */
- b .L9
-.L4:
- bnl- cr6,.L9 /* if (x < 0.0) */
- fsub fp1,fp13,fp1 /* x = TWO52 - x; */
- fsub fp0,fp1,fp13 /* x = - (x - TWO52); */
- fneg fp1,fp0
-.L9:
- mtfsb0 6 /* Clear any pending "inexact" exceptions. */
- mtfsf 0x01,fp11 /* restore exception mask. */
- blr
-
-/* The high double is > TWO52 so we need to round the low double and
- perhaps the high double. This gets a bit tricky so we use the
- following algorithm:
-
- tau = floor(x_high/TWO52);
- x0 = x_high - tau;
- x1 = x_low + tau;
- r1 = nearbyint(x1);
- y_high = x0 + r1;
- y_low = r1 - tau;
- return y; */
-.L2:
- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
- bge- cr7,.L9 /* return x; */
- beq- cr0,.L9
- fdiv fp8,fp1,fp13 /* x_high/TWO52 */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-
- fcmpu cr6,fp4,fp12 /* if (x1 > 0.0) */
- bng- cr6,.L8
- fadd fp5,fp4,fp13 /* r1 = x1 + TWO52; */
- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
- b .L6
-.L8:
- fmr fp5,fp4
- bge- cr6,.L6 /* if (x1 < 0.0) */
- fsub fp5,fp13,fp4 /* r1 = TWO52 - x1; */
- fsub fp0,fp5,fp13 /* r1 = - (r1 - TWO52); */
- fneg fp5,fp0
-.L6:
- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
- fsub fp2,fp5,fp8 /* y_low = r1 - tau; */
- b .L9
-END (__nearbyintl)
-
-long_double_symbol (libm, __nearbyintl, nearbyintl)
Index: glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_roundl.S
===================================================================
--- glibc-2.19.orig/sysdeps/powerpc/powerpc64/fpu/s_roundl.S
+++ /dev/null
@@ -1,132 +0,0 @@
-/* long double round function.
- IBM extended format long double version.
- Copyright (C) 2004-2014 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
-#include
-
- .section ".toc","aw"
-.LC0: /* 2**52 */
- .tc FD_43300000_0[TC],0x4330000000000000
-.LC1: /* 0.5 */
- .tc FD_3fe00000_0[TC],0x3fe0000000000000
- .section ".text"
-
-/* long double [fp1,fp2] roundl (long double x [fp1,fp2])
- IEEE 1003.1 round function. IEEE specifies "round to the nearest
- integer value, rounding halfway cases away from zero, regardless of
- the current rounding mode." However PowerPC Architecture defines
- "Round to Nearest" as "Choose the best approximation. In case of a
- tie, choose the one that is even (least significant bit o).".
- So we can't use the PowerPC "Round to Nearest" mode. Instead we set
- "Round toward Zero" mode and round by adding +-0.5 before rounding
- to the integer value. */
-
-ENTRY (__roundl)
- mffs fp11 /* Save current FPU rounding mode. */
- lfd fp13,.LC0@toc(2)
- fabs fp0,fp1
- fabs fp9,fp2
- fsub fp12,fp13,fp13 /* generate 0.0 */
- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */
- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */
- bnl- cr7,.L2
- mtfsfi 7,1 /* Set rounding mode toward 0. */
- lfd fp10,.LC1@toc(2)
- ble- cr6,.L1
- fneg fp2,fp12
- fadd fp1,fp1,fp10 /* x+= 0.5; */
- fadd fp1,fp1,fp13 /* x+= TWO52; */
- fsub fp1,fp1,fp13 /* x-= TWO52; */
- fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */
-.L0:
- mtfsf 0x01,fp11 /* restore previous rounding mode. */
- blr
-.L1:
- fsub fp9,fp1,fp10 /* x-= 0.5; */
- fneg fp2,fp12
- bge- cr6,.L0 /* if (x < 0.0) */
- fsub fp1,fp9,fp13 /* x-= TWO52; */
- fadd fp1,fp1,fp13 /* x+= TWO52; */
- fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */
- mtfsf 0x01,fp11 /* restore previous rounding mode. */
- blr
-
-/* The high double is > TWO52 so we need to round the low double and
- perhaps the high double. In this case we have to round the low
- double and handle any adjustment to the high double that may be
- caused by rounding (up). This is complicated by the fact that the
- high double may already be rounded and the low double may have the
- opposite sign to compensate.This gets a bit tricky so we use the
- following algorithm:
-
- tau = floor(x_high/TWO52);
- x0 = x_high - tau;
- x1 = x_low + tau;
- r1 = rint(x1);
- y_high = x0 + r1;
- y_low = x0 - y_high + r1;
- return y; */
-.L2:
- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */
- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */
- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */
- lfd fp10,.LC1@toc(2)
- bgelr- cr7 /* return x; */
- beqlr- cr0
- mtfsfi 7,1 /* Set rounding mode toward 0. */
- fdiv fp8,fp1,fp13 /* x_high/TWO52 */
-
- bng- cr6,.L6 /* if (x > 0.0) */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
- bng cr5,.L4 /* if (x_low > 0.0) */
- fmr fp3,fp1
- fmr fp4,fp2
- b .L5
-.L4: /* if (x_low < 0.0) */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-.L5:
- fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */
- fadd fp5,fp5,fp13 /* r1 = r1 + TWO52; */
- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */
- b .L9
-.L6: /* if (x < 0.0) */
- fctidz fp0,fp8
- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */
- bnl cr5,.L7 /* if (x_low < 0.0) */
- fmr fp3,fp1
- fmr fp4,fp2
- b .L8
-.L7: /* if (x_low > 0.0) */
- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */
- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */
-.L8:
- fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */
- fsub fp5,fp5,fp13 /* r1-= TWO52; */
- fadd fp5,fp5,fp13 /* r1+= TWO52; */
-.L9:
- mtfsf 0x01,fp11 /* restore previous rounding mode. */
- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */
- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */
- fadd fp2,fp2,fp5
- blr
-END (__roundl)
-
-long_double_symbol (libm, __roundl, roundl)
++++++ ibm93x-redundant-shift-si.patch ++++++
Avoid redundant shift character in iconv output at block boundary (bug #17197)
[BZ #17197]
* iconvdata/ibm930.c (BODY for TO_LOOP): Record current DBCS state
immediately after emitting SI.
* iconvdata/ibm933.c (BODY for TO_LOOP): Likewise.
* iconvdata/ibm935.c (BODY for TO_LOOP): Likewise.
* iconvdata/ibm937.c (BODY for TO_LOOP): Likewise.
* iconvdata/ibm939.c (BODY for TO_LOOP): Likewise.
* iconvdata/bug-iconv10.c: New file.
* iconvdata/Makefile (tests): Add bug-iconv10.
($(objpfx)bug-iconv10.out): New rule.
Index: glibc-2.19/iconvdata/Makefile
===================================================================
--- glibc-2.19.orig/iconvdata/Makefile
+++ glibc-2.19/iconvdata/Makefile
@@ -67,7 +67,8 @@ include ../Makeconfig
ifeq (yes,$(build-shared))
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
- tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9
+ tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
+ bug-iconv10
ifeq ($(have-thread-library),yes)
tests += bug-iconv3
endif
@@ -295,6 +296,8 @@ $(objpfx)tst-iconv4.out: $(objpfx)gconv-
$(addprefix $(objpfx),$(modules.so))
$(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so))
+$(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \
+ $(addprefix $(objpfx),$(modules.so))
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \
Index: glibc-2.19/iconvdata/bug-iconv10.c
===================================================================
--- /dev/null
+++ glibc-2.19/iconvdata/bug-iconv10.c
@@ -0,0 +1,60 @@
+/* bug 17197: check for redundant shift character at block boundary. */
+#include
+#include
+#include
+#include
+#include
+#include
+
+static int
+do_test (void)
+{
+ iconv_t cd = iconv_open ("IBM930", "UTF-8");
+ if (cd == (iconv_t) -1)
+ {
+ puts ("iconv_open failed");
+ return 1;
+ }
+
+ char instr1[] = "\xc2\xa6.";
+ const char expstr1[4] = "\016Bj\017";
+ const char expstr2[] = "K";
+ char outstr[4];
+ size_t inlen = sizeof (instr1);
+ size_t outlen = sizeof (outstr);
+ char *inptr = instr1;
+ char *outptr = outstr;
+ size_t r = iconv (cd, &inptr, &inlen, &outptr, &outlen);
+ if (r != -1
+ || errno != E2BIG
+ || inlen != sizeof (instr1) - 2
+ || inptr != instr1 + 2
+ || outlen != 0
+ || memcmp (outstr, expstr1, sizeof (expstr1)) != 0)
+ {
+ puts ("wrong first conversion");
+ return 1;
+ }
+
+ outlen = sizeof (outstr);
+ outptr = outstr;
+ r = iconv (cd, &inptr, &inlen, &outptr, &outlen);
+ if (r != 0
+ || inlen != 0
+ || outlen != sizeof (outstr) - sizeof (expstr2)
+ || memcmp (outstr, expstr2, sizeof (expstr2)) != 0)
+ {
+ puts ("wrong second conversion");
+ return 1;
+ }
+
+ if (iconv_close (cd) != 0)
+ {
+ puts ("iconv_close failed");
+ return 1;
+ }
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Index: glibc-2.19/iconvdata/ibm930.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm930.c
+++ glibc-2.19/iconvdata/ibm930.c
@@ -255,6 +255,7 @@ enum
break; \
} \
*outptr++ = SI; \
+ curcs = sb; \
} \
\
if (__builtin_expect (outptr + 1 > outend, 0)) \
@@ -268,7 +269,6 @@ enum
*outptr++ = 0x5b; \
else \
*outptr++ = cp[0]; \
- curcs = sb; \
} \
\
/* Now that we wrote the output increment the input pointer. */ \
Index: glibc-2.19/iconvdata/ibm933.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm933.c
+++ glibc-2.19/iconvdata/ibm933.c
@@ -254,6 +254,7 @@ enum
break; \
} \
*outptr++ = SI; \
+ curcs = sb; \
} \
\
if (__builtin_expect (outptr + 1 > outend, 0)) \
@@ -262,7 +263,6 @@ enum
break; \
} \
*outptr++ = cp[0]; \
- curcs = sb; \
} \
\
/* Now that we wrote the output increment the input pointer. */ \
Index: glibc-2.19/iconvdata/ibm935.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm935.c
+++ glibc-2.19/iconvdata/ibm935.c
@@ -254,6 +254,7 @@ enum
break; \
} \
*outptr++ = SI; \
+ curcs = sb; \
} \
\
if (__builtin_expect (outptr + 1 > outend, 0)) \
@@ -262,7 +263,6 @@ enum
break; \
} \
*outptr++ = cp[0]; \
- curcs = sb; \
} \
\
/* Now that we wrote the output increment the input pointer. */ \
Index: glibc-2.19/iconvdata/ibm937.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm937.c
+++ glibc-2.19/iconvdata/ibm937.c
@@ -254,6 +254,7 @@ enum
break; \
} \
*outptr++ = SI; \
+ curcs = sb; \
} \
\
if (__builtin_expect (outptr + 1 > outend, 0)) \
@@ -262,7 +263,6 @@ enum
break; \
} \
*outptr++ = cp[0]; \
- curcs = sb; \
} \
\
/* Now that we wrote the output increment the input pointer. */ \
Index: glibc-2.19/iconvdata/ibm939.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm939.c
+++ glibc-2.19/iconvdata/ibm939.c
@@ -254,6 +254,7 @@ enum
break; \
} \
*outptr++ = SI; \
+ curcs = sb; \
} \
\
if (__builtin_expect (outptr + 1 > outend, 0)) \
@@ -267,7 +268,6 @@ enum
*outptr++ = 0xb2; \
else \
*outptr++ = cp[0]; \
- curcs = sb; \
} \
\
/* Now that we wrote the output increment the input pointer. */ \
++++++ iconv-ibm-sentinel-check.patch ++++++
2014-08-29 Florian Weimer
[BZ #17325]
* iconvdata/ibm1364.c (BODY): Fix check for sentinel.
* iconvdata/ibm932.c (BODY): Replace invalid sentinel check with
assert.
* iconvdata/ibm933.c (BODY): Fix check for sentinel.
* iconvdata/ibm935.c (BODY): Likewise.
* iconvdata/ibm937.c (BODY): Likewise.
* iconvdata/ibm939.c (BODY): Likewise.
* iconvdata/ibm943.c (BODY): Replace invalid sentinel check with
assert.
* iconvdata/Makefile (iconv-test.out): Pass module list to test
script.
* iconvdata/run-iconv-test.sh: New test loop for checking for
decoder crashers.
Index: glibc-2.19/iconvdata/Makefile
===================================================================
--- glibc-2.19.orig/iconvdata/Makefile
+++ glibc-2.19/iconvdata/Makefile
@@ -302,6 +302,7 @@ $(objpfx)bug-iconv10.out: $(objpfx)gconv
$(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 \
Index: glibc-2.19/iconvdata/ibm1364.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm1364.c
+++ glibc-2.19/iconvdata/ibm1364.c
@@ -220,7 +220,8 @@ enum
++rp2; \
\
uint32_t res; \
- if (__builtin_expect (ch < rp2->start, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
+ || __builtin_expect (ch < rp2->start, 0) \
|| (res = DB_TO_UCS4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
{ \
Index: glibc-2.19/iconvdata/ibm932.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm932.c
+++ glibc-2.19/iconvdata/ibm932.c
@@ -73,11 +73,12 @@
} \
\
ch = (ch * 0x100) + inptr[1]; \
+ /* ch was less than 0xfd. */ \
+ assert (ch < 0xfd00); \
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
- || __builtin_expect (ch < rp2->start, 0) \
+ if (__builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm932db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, '\1') == 0 && ch !=0)) \
{ \
Index: glibc-2.19/iconvdata/ibm933.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm933.c
+++ glibc-2.19/iconvdata/ibm933.c
@@ -161,7 +161,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm933db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
Index: glibc-2.19/iconvdata/ibm935.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm935.c
+++ glibc-2.19/iconvdata/ibm935.c
@@ -161,7 +161,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm935db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
Index: glibc-2.19/iconvdata/ibm937.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm937.c
+++ glibc-2.19/iconvdata/ibm937.c
@@ -161,7 +161,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm937db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
Index: glibc-2.19/iconvdata/ibm939.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm939.c
+++ glibc-2.19/iconvdata/ibm939.c
@@ -161,7 +161,7 @@ enum
while (ch > rp2->end) \
++rp2; \
\
- if (__builtin_expect (rp2 == NULL, 0) \
+ if (__builtin_expect (rp2->start == 0xffff, 0) \
|| __builtin_expect (ch < rp2->start, 0) \
|| (res = __ibm939db_to_ucs4[ch + rp2->idx], \
__builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \
Index: glibc-2.19/iconvdata/ibm943.c
===================================================================
--- glibc-2.19.orig/iconvdata/ibm943.c
+++ glibc-2.19/iconvdata/ibm943.c
@@ -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)) \
{ \
Index: glibc-2.19/iconvdata/run-iconv-test.sh
===================================================================
--- glibc-2.19.orig/iconvdata/run-iconv-test.sh
+++ glibc-2.19/iconvdata/run-iconv-test.sh
@@ -188,6 +188,24 @@ while read utf8 from filename; do
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
++++++ io-wstr-overflow-integer-overflow.patch ++++++
2015-02-22 Paul Pluzhnikov
[BZ #17269]
* libio/wstrops.c (_IO_wstr_overflow): Guard against integer overflow
(enlarge_userbuf): Likewise.
Index: glibc-2.19/libio/wstrops.c
===================================================================
--- glibc-2.19.orig/libio/wstrops.c
+++ glibc-2.19/libio/wstrops.c
@@ -95,8 +95,11 @@ _IO_wstr_overflow (fp, c)
wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
size_t old_wblen = _IO_wblen (fp);
_IO_size_t new_size = 2 * old_wblen + 100;
- if (new_size < old_wblen)
+
+ if (__glibc_unlikely (new_size < old_wblen)
+ || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
return EOF;
+
new_buf
= (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
* sizeof (wchar_t));
@@ -186,6 +189,9 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64
return 1;
_IO_size_t newsize = offset + 100;
+ if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t)))
+ return 1;
+
wchar_t *oldbuf = wd->_IO_buf_base;
wchar_t *newbuf
= (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
++++++ ld-pointer-guard.patch ++++++
2015-10-15 Florian Weimer
[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.
Index: glibc-2.19/elf/rtld.c
===================================================================
--- glibc-2.19.orig/elf/rtld.c
+++ glibc-2.19/elf/rtld.c
@@ -162,7 +162,6 @@ struct rtld_global_ro _rtld_global_ro at
._dl_hwcap_mask = HWCAP_IMPORTANT,
._dl_lazy = 1,
._dl_fpu_control = _FPU_DEFAULT,
- ._dl_pointer_guard = 1,
._dl_pagesize = EXEC_PAGESIZE,
._dl_inhibit_cache = 0,
@@ -857,15 +856,12 @@ security_init (void)
#endif
/* Set up the pointer guard as well, if necessary. */
- if (GLRO(dl_pointer_guard))
- {
- uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
- stack_chk_guard);
+ uintptr_t pointer_chk_guard
+ = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
#ifdef THREAD_SET_POINTER_GUARD
- THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+ THREAD_SET_POINTER_GUARD (pointer_chk_guard);
#endif
- __pointer_chk_guard_local = pointer_chk_guard;
- }
+ __pointer_chk_guard_local = pointer_chk_guard;
/* We do not need the _dl_random value anymore. The less
information we leave behind, the better, so clear the
@@ -2652,9 +2648,6 @@ process_envvars (enum mode *modep)
GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
break;
}
-
- if (memcmp (envline, "POINTER_GUARD", 13) == 0)
- GLRO(dl_pointer_guard) = envline[14] != '0';
break;
case 14:
Index: glibc-2.19/sysdeps/generic/ldsodefs.h
===================================================================
--- glibc-2.19.orig/sysdeps/generic/ldsodefs.h
+++ glibc-2.19/sysdeps/generic/ldsodefs.h
@@ -590,9 +590,6 @@ struct rtld_global_ro
/* List of auditing interfaces. */
struct audit_ifaces *_dl_audit;
unsigned int _dl_naudit;
-
- /* 0 if internal pointer values should not be guarded, 1 if they should. */
- EXTERN int _dl_pointer_guard;
};
# define __rtld_global_attribute__
# ifdef IS_IN_rtld
++++++ ldd-system-interp.patch ++++++
Never try to execute the file in ldd
Executing a random file is never a good idea. Treat all arguments as if
they are invoked with __libc_enable_secure, and run them through the known
good dynamic linker.
* elf/ldd.bash.in: Always run through the dynamic linker, even if
the file has its own interpreter. Remove unneeded executable
check.
Index: glibc-2.19/elf/ldd.bash.in
===================================================================
--- glibc-2.19.orig/elf/ldd.bash.in
+++ glibc-2.19/elf/ldd.bash.in
@@ -150,8 +150,6 @@ for file do
echo "ldd: ${file}:" $"not regular file" >&2
result=1
elif test -r "$file"; then
- test -x "$file" || echo 'ldd:' $"\
-warning: you do not have execution permission for" "\`$file'" >&2
RTLD=
ret=1
for rtld in ${RTLDLIST}; do
@@ -164,18 +162,6 @@ warning: you do not have execution permi
fi
done
case $ret in
- 0)
- # If the program exits with exit code 5, it means the process has been
- # invoked with __libc_enable_secure. Fall back to running it through
- # the dynamic linker.
- try_trace "$file"
- rc=$?
- if [ $rc = 5 ]; then
- try_trace "$RTLD" "$file"
- rc=$?
- fi
- [ $rc = 0 ] || result=1
- ;;
1)
# This can be a non-ELF binary or no binary at all.
nonelf "$file" || {
@@ -183,7 +169,7 @@ warning: you do not have execution permi
result=1
}
;;
- 2)
+ [02])
try_trace "$RTLD" "$file" || result=1
;;
*)
++++++ manpages.patch ++++++
Index: manpages/locale.alias.5
===================================================================
--- manpages/locale.alias.5.orig
+++ manpages/locale.alias.5
@@ -18,7 +18,7 @@
.SH "NAME"
locale.alias \- Locale name alias data base
.SH "DESCRIPTION"
-The locale.alias database file (/etc/locale.alias) is used by the
+The locale.alias database file (/usr/share/locale/locale.alias) is used by the
.B locale
command and the
.B X Window System
@@ -40,6 +40,6 @@ name, or simpler versions of the POSIX l
Lines beginning with Hash ("#") are treated as comments and ignored.
.SH "SEE ALSO"
-locale(1), localedef(1), locale-gen(8), locale.gen(5)
+locale(1), localedef(1)
.SH "AUTHOR"
Alastair McKinstry
++++++ nextafterl-ibm-ldouble.patch ++++++
2014-04-02 Alan Modra
[BZ #16739]
* sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (__nextafterl): Correct
output when value is near a power of two. Use int64_t for lx and
remove casts. Use decimal rather than hex exponent constants.
Don't use long double multiplication when double will suffice.
* math/libm-test.inc (nextafter_test_data): Add tests.
Index: glibc-2.19/math/libm-test.inc
===================================================================
--- glibc-2.19.orig/math/libm-test.inc
+++ glibc-2.19/math/libm-test.inc
@@ -10528,6 +10528,14 @@ static const struct test_ff_f_data nexta
// XXX Enable once gcc is fixed.
//TEST_ff_f (nextafter, 0x0.00000040000000000000p-16385L, -0.1L, 0x0.0000003ffffffff00000p-16385L),
#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106
+ TEST_ff_f (nextafter, 1.0L, -10.0L, 1.0L-0x1p-106L, NO_EXCEPTION),
+ TEST_ff_f (nextafter, 1.0L, 10.0L, 1.0L+0x1p-105L, NO_EXCEPTION),
+ TEST_ff_f (nextafter, 1.0L-0x1p-106L, 10.0L, 1.0L, NO_EXCEPTION),
+ TEST_ff_f (nextafter, -1.0L, -10.0L, -1.0L-0x1p-105L, NO_EXCEPTION),
+ TEST_ff_f (nextafter, -1.0L, 10.0L, -1.0L+0x1p-106L, NO_EXCEPTION),
+ TEST_ff_f (nextafter, -1.0L+0x1p-106L, -10.0L, -1.0L, NO_EXCEPTION),
+#endif
/* XXX We need the hexadecimal FP number representation here for further
tests. */
Index: glibc-2.19/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
===================================================================
--- glibc-2.19.orig/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
+++ glibc-2.19/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
@@ -30,8 +30,7 @@ static char rcsid[] = "$NetBSD: $";
long double __nextafterl(long double x, long double y)
{
- int64_t hx,hy,ihx,ihy;
- uint64_t lx;
+ int64_t hx, hy, ihx, ihy, lx;
double xhi, xlo, yhi;
ldbl_unpack (x, &xhi, &xlo);
@@ -76,19 +75,28 @@ long double __nextafterl(long double x,
u = math_opt_barrier (x);
x -= __LDBL_DENORM_MIN__;
if (ihx < 0x0360000000000000LL
- || (hx > 0 && (int64_t) lx <= 0)
- || (hx < 0 && (int64_t) lx > 1)) {
+ || (hx > 0 && lx <= 0)
+ || (hx < 0 && lx > 1)) {
u = u * u;
math_force_eval (u); /* raise underflow flag */
}
return x;
}
- if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
- INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52));
- u = yhi;
- u *= 0x1.0000000000000p-105L;
+ /* If the high double is an exact power of two and the low
+ double is the opposite sign, then 1ulp is one less than
+ what we might determine from the high double. Similarly
+ if X is an exact power of two, and positive, because
+ making it a little smaller will result in the exponent
+ decreasing by one and normalisation of the mantissa. */
+ if ((hx & 0x000fffffffffffffLL) == 0
+ && ((lx != 0 && (hx ^ lx) < 0)
+ || (lx == 0 && hx >= 0)))
+ ihx -= 1LL << 52;
+ if (ihx < (106LL << 52)) { /* ulp will denormal */
+ INSERT_WORDS64 (yhi, ihx & (0x7ffLL<<52));
+ u = yhi * 0x1p-105;
} else {
- INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52));
+ INSERT_WORDS64 (yhi, (ihx & (0x7ffLL<<52))-(105LL<<52));
u = yhi;
}
return x - u;
@@ -103,8 +111,8 @@ long double __nextafterl(long double x,
u = math_opt_barrier (x);
x += __LDBL_DENORM_MIN__;
if (ihx < 0x0360000000000000LL
- || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL)
- || (hx < 0 && (int64_t) lx >= 0)) {
+ || (hx > 0 && lx < 0 && lx != 0x8000000000000001LL)
+ || (hx < 0 && lx >= 0)) {
u = u * u;
math_force_eval (u); /* raise underflow flag */
}
@@ -112,12 +120,21 @@ long double __nextafterl(long double x,
x = -0.0L;
return x;
}
- if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
- INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52));
- u = yhi;
- u *= 0x1.0000000000000p-105L;
+ /* If the high double is an exact power of two and the low
+ double is the opposite sign, then 1ulp is one less than
+ what we might determine from the high double. Similarly
+ if X is an exact power of two, and negative, because
+ making it a little larger will result in the exponent
+ decreasing by one and normalisation of the mantissa. */
+ if ((hx & 0x000fffffffffffffLL) == 0
+ && ((lx != 0 && (hx ^ lx) < 0)
+ || (lx == 0 && hx < 0)))
+ ihx -= 1LL << 52;
+ if (ihx < (106LL << 52)) { /* ulp will denormal */
+ INSERT_WORDS64 (yhi, ihx & (0x7ffLL<<52));
+ u = yhi * 0x1p-105;
} else {
- INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52));
+ INSERT_WORDS64 (yhi, (ihx & (0x7ffLL<<52))-(105LL<<52));
u = yhi;
}
return x + u;
++++++ nscd-netgroup-overlap.patch ++++++
015-12-20 Siddhesh Poyarekar
[BZ #16760]
* nscd/netgroupcache.c (addgetnetgrentX): Use memmove instead
of stpcpy.
Index: glibc-2.19/nscd/netgroupcache.c
===================================================================
--- glibc-2.19.orig/nscd/netgroupcache.c
+++ glibc-2.19/nscd/netgroupcache.c
@@ -211,6 +211,10 @@ addgetnetgrentX (struct database_dyn *db
const char *nuser = data.val.triple.user;
const char *ndomain = data.val.triple.domain;
+ size_t hostlen = strlen (nhost ?: "") + 1;
+ size_t userlen = strlen (nuser ?: "") + 1;
+ size_t domainlen = strlen (ndomain ?: "") + 1;
+
if (nhost == NULL || nuser == NULL || ndomain == NULL
|| nhost > nuser || nuser > ndomain)
{
@@ -228,9 +232,6 @@ addgetnetgrentX (struct database_dyn *db
: last + strlen (last) + 1 - buffer);
/* We have to make temporary copies. */
- size_t hostlen = strlen (nhost ?: "") + 1;
- size_t userlen = strlen (nuser ?: "") + 1;
- size_t domainlen = strlen (ndomain ?: "") + 1;
size_t needed = hostlen + userlen + domainlen;
if (buflen - req->key_len - bufused < needed)
@@ -264,9 +265,12 @@ addgetnetgrentX (struct database_dyn *db
}
char *wp = buffer + buffilled;
- wp = stpcpy (wp, nhost) + 1;
- wp = stpcpy (wp, nuser) + 1;
- wp = stpcpy (wp, ndomain) + 1;
+ wp = memmove (wp, nhost ?: "", hostlen);
+ wp += hostlen;
+ wp = memmove (wp, nuser ?: "", userlen);
+ wp += userlen;
+ wp = memmove (wp, ndomain ?: "", domainlen);
+ wp += domainlen;
buffilled = wp - buffer;
++nentries;
}
++++++ nscd-netgroup-query-buffer-len.patch ++++++
2014-03-12 Siddhesh Poyarekar
[BZ #16695]
* nscd/netgroupcache.c (addgetnetgrentX): Factor in space for
key in the buffer.
Index: glibc-2.19/nscd/netgroupcache.c
===================================================================
--- glibc-2.19.orig/nscd/netgroupcache.c
+++ glibc-2.19/nscd/netgroupcache.c
@@ -202,7 +202,7 @@ addgetnetgrentX (struct database_dyn *db
{
int e;
status = getfct.f (&data, buffer + buffilled,
- buflen - buffilled, &e);
+ buflen - buffilled - req->key_len, &e);
if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND)
/* This was either the last one for this group or the
++++++ nscd-netgroup-tryagain.patch ++++++
2014-05-26 Siddhesh Poyarekar
[BZ #16878]
* nscd/netgroupcache.c (addgetnetgrentX): Look for
NSS_STATUS_TRYAGAIN to indicate insufficient buffer space.
* nscd/nss_files/files-netgrp.c (_nss_netgroup_parseline): Use
NSS_STATUS_TRYAGAIN to indicate insufficient buffer space.
Index: glibc-2.19/nscd/netgroupcache.c
===================================================================
--- glibc-2.19.orig/nscd/netgroupcache.c
+++ glibc-2.19/nscd/netgroupcache.c
@@ -203,11 +203,6 @@ addgetnetgrentX (struct database_dyn *db
int e;
status = getfct.f (&data, buffer + buffilled,
buflen - buffilled - req->key_len, &e);
- if (status == NSS_STATUS_RETURN
- || status == NSS_STATUS_NOTFOUND)
- /* This was either the last one for this group or the
- group was empty. Look at next group if available. */
- break;
if (status == NSS_STATUS_SUCCESS)
{
if (data.type == triple_val)
@@ -322,11 +317,18 @@ addgetnetgrentX (struct database_dyn *db
}
}
}
- else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
+ else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{
buflen *= 2;
buffer = xrealloc (buffer, buflen);
}
+ else if (status == NSS_STATUS_RETURN
+ || status == NSS_STATUS_NOTFOUND
+ || status == NSS_STATUS_UNAVAIL)
+ /* This was either the last one for this group or the
+ group was empty or the NSS module had an internal
+ failure. Look at next group if available. */
+ break;
}
enum nss_status (*endfct) (struct __netgrent *);
Index: glibc-2.19/nss/nss_files/files-netgrp.c
===================================================================
--- glibc-2.19.orig/nss/nss_files/files-netgrp.c
+++ glibc-2.19/nss/nss_files/files-netgrp.c
@@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor,
if (cp - host > buflen)
{
*errnop = ERANGE;
- status = NSS_STATUS_UNAVAIL;
+ status = NSS_STATUS_TRYAGAIN;
}
else
{
++++++ nscd-netgroup-wildcards.patch ++++++
2015-12-20 Siddhesh Poyarekar
[BZ #16758]
* nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has
blank values.
[BZ #16759]
* inet/getnetgrent_r.c (get_nonempty_val): New function.
(nscd_getnetgrent): Use it.
Index: glibc-2.19/inet/getnetgrent_r.c
===================================================================
--- glibc-2.19.orig/inet/getnetgrent_r.c
+++ glibc-2.19/inet/getnetgrent_r.c
@@ -235,6 +235,14 @@ endnetgrent (void)
}
#ifdef USE_NSCD
+static const char *
+get_nonempty_val (const char *in)
+{
+ if (*in == '\0')
+ return NULL;
+ return in;
+}
+
static enum nss_status
nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen,
int *errnop)
@@ -243,11 +251,11 @@ nscd_getnetgrent (struct __netgrent *dat
return NSS_STATUS_UNAVAIL;
datap->type = triple_val;
- datap->val.triple.host = datap->cursor;
+ datap->val.triple.host = get_nonempty_val (datap->cursor);
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
- datap->val.triple.user = datap->cursor;
+ datap->val.triple.user = get_nonempty_val (datap->cursor);
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
- datap->val.triple.domain = datap->cursor;
+ datap->val.triple.domain = get_nonempty_val (datap->cursor);
datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1;
return NSS_STATUS_SUCCESS;
Index: glibc-2.19/nscd/netgroupcache.c
===================================================================
--- glibc-2.19.orig/nscd/netgroupcache.c
+++ glibc-2.19/nscd/netgroupcache.c
@@ -562,15 +562,19 @@ addinnetgrX (struct database_dyn *db, in
{
bool success = true;
- if (host != NULL)
+ /* For the host, user and domain in each triplet, we assume success
+ if the value is blank because that is how the wildcard entry to
+ match anything is stored in the netgroup cache. */
+ if (host != NULL && *triplets != '\0')
success = strcmp (host, triplets) == 0;
triplets = (const char *) rawmemchr (triplets, '\0') + 1;
- if (success && user != NULL)
+ if (success && user != NULL && *triplets != '\0')
success = strcmp (user, triplets) == 0;
triplets = (const char *) rawmemchr (triplets, '\0') + 1;
- if (success && (domain == NULL || strcmp (domain, triplets) == 0))
+ if (success && (domain == NULL || *triplets == '\0'
+ || strcmp (domain, triplets) == 0))
{
dataset->resp.result = 1;
break;
++++++ nscd-server-user.patch ++++++
Index: glibc-2.18/nscd/nscd.conf
===================================================================
--- glibc-2.18.orig/nscd/nscd.conf
+++ glibc-2.18/nscd/nscd.conf
@@ -33,7 +33,7 @@
# logfile /var/log/nscd.log
# threads 4
# max-threads 32
-# server-user nobody
+ server-user nscd
# stat-user somebody
debug-level 0
# reload-count 5
++++++ nscd-track-startup-failures.patch ++++++
From 532a60357ef4c5852cc1bf836cfd9d6f093ef204 Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar
Date: Mon, 3 Mar 2014 22:51:39 +0530
Subject: [PATCH] nscd: Improved support for tracking startup failure in nscd
service (BZ #16639)
From 867dbf6ba31c0a0f5c0366f9ed71b0afc3727a23 Mon Sep 17 00:00:00 2001
From: Andreas Schwab
Date: Mon, 11 Aug 2014 11:18:26 +0200
Subject: [PATCH] Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in
Currently, the nscd parent process parses commandline options and
configuration, forks on startup and immediately exits with a success.
If the child process encounters some error after this, it goes
undetected and any services started up after it may have to repeatedly
check to make sure that the nscd service did actually start up and is
serving requests.
To make this process more reliable, I have added a pipe between the
parent and child process, through which the child process sends a
notification to the parent informing it of its status. The parent
waits for this status and once it receives it, exits with the
corresponding exit code. So if the child service sends a success
status (0), the parent exits with a success status. Similarly for
error conditions, the child sends the non-zero status code, which the
parent passes on as the exit code.
This, along with setting the nscd service type to forking in its
systemd configuration file, allows systemd to be certain that the nscd
service is ready and is accepting connections.
2014-03-03 Siddhesh Poyarekar
[BZ #16639]
* nscd/connections.c (nscd_init): Call do_exit.
(start_threads): Call do_exit and notify_parent.
(begin_drop_privileges): Call do_exit.
(finish_drop_privileges): Likewise.
* nscd/selinux.c (preserve_capabilities): Likewise.
(install_real_capabilities): Likewise.
(nscd_selinux_enabled): Likewise.
(avc_create_thread): Likewise.
(avc_alloc_lock): Likewise.
(nscd_avc_init): Likewise.
* nscd/nscd.c (parent_fd): New static variable.
(main): Create a pipe between parent and child processes.
Skip closing parent_fd.
(monitor_child): New function.
(do_exit): Likewise.
(notify_parent): Likewise.
* nscd/nscd.h (notify_parent): Likewise.
(do_exit): Likewise.
Index: glibc-2.19/nscd/connections.c
===================================================================
--- glibc-2.19.orig/nscd/connections.c
+++ glibc-2.19/nscd/connections.c
@@ -649,8 +649,8 @@ cannot create read-only descriptor for \
close (fd);
}
else if (errno == EACCES)
- error (EXIT_FAILURE, 0, _("cannot access '%s'"),
- dbs[cnt].db_filename);
+ do_exit (EXIT_FAILURE, 0, _("cannot access '%s'"),
+ dbs[cnt].db_filename);
}
if (dbs[cnt].head == NULL)
@@ -699,8 +699,7 @@ cannot create read-only descriptor for \
{
dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"),
dbnames[cnt], dbs[cnt].db_filename);
- // XXX Correct way to terminate?
- exit (1);
+ do_exit (1, 0, NULL);
}
if (dbs[cnt].persistent)
@@ -867,7 +866,7 @@ cannot set socket to close on exec: %s;
if (sock < 0)
{
dbg_log (_("cannot open socket: %s"), strerror (errno));
- exit (errno == EACCES ? 4 : 1);
+ do_exit (errno == EACCES ? 4 : 1, 0, NULL);
}
/* Bind a name to the socket. */
struct sockaddr_un sock_addr;
@@ -876,7 +875,7 @@ cannot set socket to close on exec: %s;
if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
{
dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
- exit (errno == EACCES ? 4 : 1);
+ do_exit (errno == EACCES ? 4 : 1, 0, NULL);
}
#ifndef __ASSUME_SOCK_CLOEXEC
@@ -888,7 +887,7 @@ cannot set socket to close on exec: %s;
{
dbg_log (_("cannot change socket to nonblocking mode: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
/* The descriptor needs to be closed on exec. */
@@ -896,7 +895,7 @@ cannot set socket to close on exec: %s;
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
}
#endif
@@ -909,7 +908,7 @@ cannot set socket to close on exec: %s;
{
dbg_log (_("cannot enable socket to accept connections: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
#ifdef HAVE_NETLINK
@@ -953,7 +952,7 @@ cannot set socket to close on exec: %s;
dbg_log (_("\
cannot change socket to nonblocking mode: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
/* The descriptor needs to be closed on exec. */
@@ -962,7 +961,7 @@ cannot change socket to nonblocking mode
{
dbg_log (_("cannot set socket to close on exec: %s"),
strerror (errno));
- exit (1);
+ do_exit (1, 0, NULL);
}
}
# endif
@@ -2392,7 +2391,7 @@ start_threads (void)
if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0)
{
dbg_log (_("could not initialize conditional variable"));
- exit (1);
+ do_exit (1, 0, NULL);
}
pthread_t th;
@@ -2400,7 +2399,7 @@ start_threads (void)
&& pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0)
{
dbg_log (_("could not start clean-up thread; terminating"));
- exit (1);
+ do_exit (1, 0, NULL);
}
}
@@ -2414,13 +2413,17 @@ start_threads (void)
if (i == 0)
{
dbg_log (_("could not start any worker thread; terminating"));
- exit (1);
+ do_exit (1, 0, NULL);
}
break;
}
}
+ /* Now it is safe to let the parent know that we're doing fine and it can
+ exit. */
+ notify_parent (0);
+
/* Determine how much room for descriptors we should initially
allocate. This might need to change later if we cap the number
with MAXCONN. */
@@ -2465,8 +2468,8 @@ begin_drop_privileges (void)
if (pwd == NULL)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"),
- server_user);
+ do_exit (EXIT_FAILURE, 0,
+ _("Failed to run nscd as user '%s'"), server_user);
}
server_uid = pwd->pw_uid;
@@ -2483,7 +2486,8 @@ begin_drop_privileges (void)
{
/* This really must never happen. */
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, errno, _("initial getgrouplist failed"));
+ do_exit (EXIT_FAILURE, errno,
+ _("initial getgrouplist failed"));
}
server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t));
@@ -2492,7 +2496,7 @@ begin_drop_privileges (void)
== -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, errno, _("getgrouplist failed"));
+ do_exit (EXIT_FAILURE, errno, _("getgrouplist failed"));
}
}
@@ -2510,7 +2514,7 @@ finish_drop_privileges (void)
if (setgroups (server_ngroups, server_groups) == -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- error (EXIT_FAILURE, errno, _("setgroups failed"));
+ do_exit (EXIT_FAILURE, errno, _("setgroups failed"));
}
int res;
@@ -2521,8 +2525,7 @@ finish_drop_privileges (void)
if (res == -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- perror ("setgid");
- exit (4);
+ do_exit (4, errno, "setgid");
}
if (paranoia)
@@ -2532,8 +2535,7 @@ finish_drop_privileges (void)
if (res == -1)
{
dbg_log (_("Failed to run nscd as user '%s'"), server_user);
- perror ("setuid");
- exit (4);
+ do_exit (4, errno, "setuid");
}
#if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP
Index: glibc-2.19/nscd/nscd.c
===================================================================
--- glibc-2.19.orig/nscd/nscd.c
+++ glibc-2.19/nscd/nscd.c
@@ -39,6 +39,8 @@
#include
#include
#include
+#include
+#include
#include "dbg_log.h"
#include "nscd.h"
@@ -101,6 +103,7 @@ gid_t old_gid;
static int check_pid (const char *file);
static int write_pid (const char *file);
+static int monitor_child (int fd);
/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
@@ -142,6 +145,7 @@ static struct argp argp =
/* True if only statistics are requested. */
static bool get_stats;
+static int parent_fd = -1;
int
main (int argc, char **argv)
@@ -196,11 +200,27 @@ main (int argc, char **argv)
/* Behave like a daemon. */
if (run_mode == RUN_DAEMONIZE)
{
+ int fd[2];
+
+ if (pipe (fd) != 0)
+ error (EXIT_FAILURE, errno,
+ _("cannot create a pipe to talk to the child"));
+
pid = fork ();
if (pid == -1)
error (EXIT_FAILURE, errno, _("cannot fork"));
if (pid != 0)
- exit (0);
+ {
+ /* The parent only reads from the child. */
+ close (fd[1]);
+ exit (monitor_child (fd[0]));
+ }
+ else
+ {
+ /* The child only writes to the parent. */
+ close (fd[0]);
+ parent_fd = fd[1];
+ }
}
int nullfd = open (_PATH_DEVNULL, O_RDWR);
@@ -242,7 +262,8 @@ main (int argc, char **argv)
char *endp;
long int fdn = strtol (dirent->d_name, &endp, 10);
- if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd)
+ if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd
+ && fdn != parent_fd)
close ((int) fdn);
}
@@ -250,13 +271,14 @@ main (int argc, char **argv)
}
else
for (i = min_close_fd; i < getdtablesize (); i++)
- close (i);
+ if (i != parent_fd)
+ close (i);
setsid ();
if (chdir ("/") != 0)
- error (EXIT_FAILURE, errno,
- _("cannot change current working directory to \"/\""));
+ do_exit (EXIT_FAILURE, errno,
+ _("cannot change current working directory to \"/\""));
openlog ("nscd", LOG_CONS | LOG_ODELAY, LOG_DAEMON);
@@ -592,3 +614,79 @@ write_pid (const char *file)
return result;
}
+
+static int
+monitor_child (int fd)
+{
+ int child_ret = 0;
+ int ret = read (fd, &child_ret, sizeof (child_ret));
+
+ /* The child terminated with an error, either via exit or some other abnormal
+ method, like a segfault. */
+ if (ret <= 0 || child_ret != 0)
+ {
+ int err = wait (&child_ret);
+
+ if (err < 0)
+ {
+ fprintf (stderr, _("wait failed"));
+ return 1;
+ }
+
+ fprintf (stderr, _("child exited with status %d"),
+ WEXITSTATUS (child_ret));
+ if (WIFSIGNALED (child_ret))
+ fprintf (stderr, _(", terminated by signal %d.\n"),
+ WTERMSIG (child_ret));
+ else
+ fprintf (stderr, ".\n");
+ }
+
+ /* We have the child status, so exit with that code. */
+ close (fd);
+
+ return child_ret;
+}
+
+void
+do_exit (int child_ret, int errnum, const char *format, ...)
+{
+ if (parent_fd != -1)
+ {
+ int ret = write (parent_fd, &child_ret, sizeof (child_ret));
+ assert (ret == sizeof (child_ret));
+ close (parent_fd);
+ }
+
+ if (format != NULL)
+ {
+ /* Emulate error() since we don't have a va_list variant for it. */
+ va_list argp;
+
+ fflush (stdout);
+
+ fprintf (stderr, "%s: ", program_invocation_name);
+
+ va_start (argp, format);
+ vfprintf (stderr, format, argp);
+ va_end (argp);
+
+ fprintf (stderr, ": %s\n", strerror (errnum));
+ fflush (stderr);
+ }
+
+ /* Finally, exit. */
+ exit (child_ret);
+}
+
+void
+notify_parent (int child_ret)
+{
+ if (parent_fd == -1)
+ return;
+
+ int ret = write (parent_fd, &child_ret, sizeof (child_ret));
+ assert (ret == sizeof (child_ret));
+ close (parent_fd);
+ parent_fd = -1;
+}
Index: glibc-2.19/nscd/nscd.h
===================================================================
--- glibc-2.19.orig/nscd/nscd.h
+++ glibc-2.19/nscd/nscd.h
@@ -205,6 +205,8 @@ extern gid_t old_gid;
/* nscd.c */
extern void termination_handler (int signum) __attribute__ ((__noreturn__));
extern int nscd_open_socket (void);
+void notify_parent (int child_ret);
+void do_exit (int child_ret, int errnum, const char *format, ...);
/* connections.c */
extern void nscd_init (void);
Index: glibc-2.19/nscd/selinux.c
===================================================================
--- glibc-2.19.orig/nscd/selinux.c
+++ glibc-2.19/nscd/selinux.c
@@ -179,7 +179,7 @@ preserve_capabilities (void)
if (prctl (PR_SET_KEEPCAPS, 1) == -1)
{
dbg_log (_("Failed to set keep-capabilities"));
- error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
+ do_exit (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
/* NOTREACHED */
}
@@ -194,7 +194,7 @@ preserve_capabilities (void)
cap_free (tmp_caps);
dbg_log (_("Failed to initialize drop of capabilities"));
- error (EXIT_FAILURE, 0, _("cap_init failed"));
+ do_exit (EXIT_FAILURE, 0, _("cap_init failed"));
}
/* There is no reason why these should not work. */
@@ -216,7 +216,7 @@ preserve_capabilities (void)
{
cap_free (new_caps);
dbg_log (_("Failed to drop capabilities"));
- error (EXIT_FAILURE, 0, _("cap_set_proc failed"));
+ do_exit (EXIT_FAILURE, 0, _("cap_set_proc failed"));
}
return new_caps;
@@ -233,7 +233,7 @@ install_real_capabilities (cap_t new_cap
{
cap_free (new_caps);
dbg_log (_("Failed to drop capabilities"));
- error (EXIT_FAILURE, 0, _("cap_set_proc failed"));
+ do_exit (EXIT_FAILURE, 0, _("cap_set_proc failed"));
/* NOTREACHED */
}
@@ -242,7 +242,7 @@ install_real_capabilities (cap_t new_cap
if (prctl (PR_SET_KEEPCAPS, 0) == -1)
{
dbg_log (_("Failed to unset keep-capabilities"));
- error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
+ do_exit (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed"));
/* NOTREACHED */
}
}
@@ -258,7 +258,7 @@ nscd_selinux_enabled (int *selinux_enabl
if (*selinux_enabled < 0)
{
dbg_log (_("Failed to determine if kernel supports SELinux"));
- exit (EXIT_FAILURE);
+ do_exit (EXIT_FAILURE, 0, NULL);
}
}
@@ -272,7 +272,7 @@ avc_create_thread (void (*run) (void))
rc =
pthread_create (&avc_notify_thread, NULL, (void *(*) (void *)) run, NULL);
if (rc != 0)
- error (EXIT_FAILURE, rc, _("Failed to start AVC thread"));
+ do_exit (EXIT_FAILURE, rc, _("Failed to start AVC thread"));
return &avc_notify_thread;
}
@@ -294,7 +294,7 @@ avc_alloc_lock (void)
avc_mutex = malloc (sizeof (pthread_mutex_t));
if (avc_mutex == NULL)
- error (EXIT_FAILURE, errno, _("Failed to create AVC lock"));
+ do_exit (EXIT_FAILURE, errno, _("Failed to create AVC lock"));
pthread_mutex_init (avc_mutex, NULL);
return avc_mutex;
@@ -334,7 +334,7 @@ nscd_avc_init (void)
avc_entry_ref_init (&aeref);
if (avc_init ("avc", NULL, &log_cb, &thread_cb, &lock_cb) < 0)
- error (EXIT_FAILURE, errno, _("Failed to start AVC"));
+ do_exit (EXIT_FAILURE, errno, _("Failed to start AVC"));
else
dbg_log (_("Access Vector Cache (AVC) started"));
#ifdef HAVE_LIBAUDIT
++++++ nscd.conf ++++++
d /run/nscd 0755 root root
++++++ nscd.service ++++++
[Unit]
Description=Name Service Cache Daemon
After=sysinit.target
Wants=nss-lookup.target nss-user-lookup.target
Before=nss-lookup.target nss-user-lookup.target
[Service]
Type=forking
ExecStart=/usr/sbin/nscd
ExecStop=/usr/sbin/nscd --shutdown
ExecReload=/usr/sbin/nscd -i passwd
ExecReload=/usr/sbin/nscd -i group
ExecReload=/usr/sbin/nscd -i hosts
ExecReload=/usr/sbin/nscd -i services
ExecReload=/usr/sbin/nscd -i netgroup
Restart=always
PIDFile=/run/nscd/nscd.pid
[Install]
WantedBy=multi-user.target
++++++ nss-db-path.patch ++++++
Use /var/db for nss_db
Index: glibc-2.17.90/Makeconfig
===================================================================
--- glibc-2.17.90.orig/Makeconfig
+++ glibc-2.17.90/Makeconfig
@@ -259,7 +259,7 @@ inst_sysconfdir = $(install_root)$(sysco
# Directory for the database files and Makefile for nss_db.
ifndef vardbdir
-vardbdir = $(localstatedir)/db
+vardbdir = /var/lib/misc
endif
inst_vardbdir = $(install_root)$(vardbdir)
Index: glibc-2.17.90/nss/db-Makefile
===================================================================
--- glibc-2.17.90.orig/nss/db-Makefile
+++ glibc-2.17.90/nss/db-Makefile
@@ -22,7 +22,7 @@ DATABASES = $(wildcard /etc/passwd /etc/
/etc/rpc /etc/services /etc/shadow /etc/gshadow \
/etc/netgroup)
-VAR_DB = /var/db
+VAR_DB = /var/lib/misc
AWK = awk
MAKEDB = makedb --quiet
Index: glibc-2.17.90/sysdeps/unix/sysv/linux/paths.h
===================================================================
--- glibc-2.17.90.orig/sysdeps/unix/sysv/linux/paths.h
+++ glibc-2.17.90/sysdeps/unix/sysv/linux/paths.h
@@ -68,7 +68,7 @@
/* Provide trailing slash, since mostly used for building pathnames. */
#define _PATH_DEV "/dev/"
#define _PATH_TMP "/tmp/"
-#define _PATH_VARDB "/var/db/"
+#define _PATH_VARDB "/var/lib/misc/"
#define _PATH_VARRUN "/var/run/"
#define _PATH_VARTMP "/var/tmp/"
++++++ nss-dns-buffer-overflow.patch ++++++
2015-04-21 Arjun Shankar
[BZ #18287]
* resolv/nss_dns/dns-host.c (getanswer_r): Adjust buffer length
based on padding. (CVE-2015-1781)
Index: glibc-2.19/resolv/nss_dns/dns-host.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-host.c
+++ glibc-2.19/resolv/nss_dns/dns-host.c
@@ -618,7 +618,8 @@ getanswer_r (const querybuf *answer, int
int have_to_map = 0;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
buffer += pad;
- if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0))
+ buflen = buflen > pad ? buflen - pad : 0;
+ if (__builtin_expect (buflen < sizeof (struct host_data), 0))
{
/* The buffer is too small. */
too_small:
++++++ nss-dns-getnetbyname.patch ++++++
2016-03-29 Florian Weimer
[BZ #19879]
CVE-2016-3075
* resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r): Do not
copy name.
Index: glibc-2.19/resolv/nss_dns/dns-network.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-network.c
+++ glibc-2.19/resolv/nss_dns/dns-network.c
@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *nam
} 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)
{
++++++ nss-dns-infinite-loop.patch ++++++
2014-12-16 Florian Weimer
[BZ #17630]
* resolv/nss_dns/dns-network.c (getanswer_r): Iterate over alias
names.
Index: glibc-2.19/resolv/nss_dns/dns-network.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-network.c
+++ glibc-2.19/resolv/nss_dns/dns-network.c
@@ -398,8 +398,8 @@ getanswer_r (const querybuf *answer, int
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
++++++ nss-dns-memleak-2.patch ++++++
Index: glibc-2.19/resolv/nss_dns/dns-host.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-host.c
+++ glibc-2.19/resolv/nss_dns/dns-host.c
@@ -315,7 +315,11 @@ _nss_dns_gethostbyname4_r (const char *n
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
host_buffer.buf->buf, 2048, &host_buffer.ptr,
&ans2p, &nans2p, &resplen2, &ans2p_malloced);
- if (n < 0)
+ if (n >= 0)
+ status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
+ resplen2, name, pat, buffer, buflen,
+ errnop, herrnop, ttlp);
+ else
{
switch (errno)
{
@@ -342,17 +346,8 @@ _nss_dns_gethostbyname4_r (const char *n
*errnop = EAGAIN;
else
__set_errno (olderr);
-
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
-
- return status;
}
- status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
- resplen2, name, pat, buffer, buflen,
- errnop, herrnop, ttlp);
-
/* Check whether ans2p was separately allocated. */
if (ans2p_malloced)
free (ans2p);
++++++ nss-dns-memleak.patch ++++++
2014-02-18 Andreas Schwab
[BZ #16574]
* resolv/res_send.c (send_vc): Add parameter ansp2_malloced.
Store non-zero if the second buffer was newly allocated.
(send_dg): Likewise.
(__libc_res_nsend): Add parameter ansp2_malloced and pass it down
to send_vc and send_dg.
(res_nsend): Pass NULL for ansp2_malloced.
* resolv/res_query.c (__libc_res_nquery): Add parameter
answerp2_malloced and pass it down to __libc_res_nsend.
(res_nquery): Pass additional NULL to __libc_res_nquery.
(__libc_res_nsearch): Add parameter answerp2_malloced and pass it
down to __libc_res_nquery and __libc_res_nquerydomain. Deallocate
second answer buffer if answerp2_malloced was set.
(res_nsearch): Pass additional NULL to __libc_res_nsearch.
(__libc_res_nquerydomain): Add parameter
answerp2_malloced and pass it down to __libc_res_nquery.
(res_nquerydomain): Pass additional NULL to
__libc_res_nquerydomain.
* resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r): Pass
additional NULL to __libc_res_nsend and __libc_res_nquery.
* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname3_r): Pass
additional NULL to __libc_res_nsearch.
(_nss_dns_gethostbyname4_r): Revert last change. Use new
parameter of __libc_res_nsearch to check for separately allocated
second buffer.
(_nss_dns_gethostbyaddr2_r): Pass additional NULL to
__libc_res_nquery.
* resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Pass
additional NULL to __libc_res_nquery.
* resolv/gethnamaddr.c (gethostbyname2): Pass additional NULL to
__libc_res_nsearch.
(gethostbyaddr): Pass additional NULL to __libc_res_nquery.
* include/resolv.h: Update prototypes of __libc_res_nquery,
__libc_res_nsearch, __libc_res_nsend.
2014-02-13 Andreas Schwab
[BZ #16574]
* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname4_r): Free the
second answer buffer if it was separately allocated.
Index: glibc-2.19/include/resolv.h
===================================================================
--- glibc-2.19.orig/include/resolv.h
+++ glibc-2.19/include/resolv.h
@@ -48,11 +48,11 @@ libc_hidden_proto (__res_randomid)
libc_hidden_proto (__res_state)
int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
- u_char **, u_char **, int *, int *);
+ u_char **, u_char **, int *, int *, int *);
int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
- u_char **, u_char **, int *, int *);
+ u_char **, u_char **, int *, int *, int *);
int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
- u_char *, int, u_char **, u_char **, int *, int *)
+ u_char *, int, u_char **, u_char **, int *, int *, int *)
attribute_hidden;
libresolv_hidden_proto (_sethtent)
Index: glibc-2.19/resolv/gethnamaddr.c
===================================================================
--- glibc-2.19.orig/resolv/gethnamaddr.c
+++ glibc-2.19/resolv/gethnamaddr.c
@@ -621,7 +621,7 @@ gethostbyname2(name, af)
buf.buf = origbuf = (querybuf *) alloca (1024);
if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
- &buf.ptr, NULL, NULL, NULL)) < 0) {
+ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
if (buf.buf != origbuf)
free (buf.buf);
Dprintf("res_nsearch failed (%d)\n", n);
@@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af)
buf.buf = orig_buf = (querybuf *) alloca (1024);
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
- &buf.ptr, NULL, NULL, NULL);
+ &buf.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
strcpy(qp, "ip6.int");
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
buf.buf != orig_buf ? MAXPACKET : 1024,
- &buf.ptr, NULL, NULL, NULL);
+ &buf.ptr, NULL, NULL, NULL, NULL);
}
if (n < 0) {
if (buf.buf != orig_buf)
Index: glibc-2.19/resolv/nss_dns/dns-canon.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-canon.c
+++ glibc-2.19/resolv/nss_dns/dns-canon.c
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *nam
{
int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
buf, sizeof (buf), &ansp.ptr, NULL, NULL,
- NULL);
+ NULL, NULL);
if (r > 0)
{
/* We need to decode the response. Just one question record.
Index: glibc-2.19/resolv/nss_dns/dns-host.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-host.c
+++ glibc-2.19/resolv/nss_dns/dns-host.c
@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *n
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0)
{
switch (errno)
@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *n
n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n < 0)
{
@@ -308,12 +308,13 @@ _nss_dns_gethostbyname4_r (const char *n
u_char *ans2p = NULL;
int nans2p = 0;
int resplen2 = 0;
+ int ans2p_malloced = 0;
int olderr = errno;
enum nss_status status;
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
host_buffer.buf->buf, 2048, &host_buffer.ptr,
- &ans2p, &nans2p, &resplen2);
+ &ans2p, &nans2p, &resplen2, &ans2p_malloced);
if (n < 0)
{
switch (errno)
@@ -352,6 +353,10 @@ _nss_dns_gethostbyname4_r (const char *n
resplen2, name, pat, buffer, buflen,
errnop, herrnop, ttlp);
+ /* Check whether ans2p was separately allocated. */
+ if (ans2p_malloced)
+ free (ans2p);
+
if (host_buffer.buf != orig_host_buffer)
free (host_buffer.buf);
@@ -460,7 +465,7 @@ _nss_dns_gethostbyaddr2_r (const void *a
strcpy (qp, "].ip6.arpa");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
host_buffer.buf->buf, 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
if (n >= 0)
goto got_it_already;
}
@@ -481,14 +486,14 @@ _nss_dns_gethostbyaddr2_r (const void *a
}
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL);
+ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
{
strcpy (qp, "ip6.int");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
if (n < 0)
{
Index: glibc-2.19/resolv/nss_dns/dns-network.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-network.c
+++ glibc-2.19/resolv/nss_dns/dns-network.c
@@ -129,7 +129,7 @@ _nss_dns_getnetbyname_r (const char *nam
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
@@ -205,7 +205,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
- 1024, &net_buffer.ptr, NULL, NULL, NULL);
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
/* Nothing found. */
Index: glibc-2.19/resolv/res_query.c
===================================================================
--- glibc-2.19.orig/resolv/res_query.c
+++ glibc-2.19/resolv/res_query.c
@@ -98,7 +98,7 @@ static int
__libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
int class, int type, u_char *answer, int anslen,
u_char **answerp, u_char **answerp2, int *nanswerp2,
- int *resplen2);
+ int *resplen2, int *answerp2_malloced);
/*
* Formulate a normal query, send, and await answer.
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
u_char **answerp, /* if buffer needs to be enlarged */
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
HEADER *hp = (HEADER *) answer;
HEADER *hp2;
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
}
assert (answerp == NULL || (void *) *answerp == (void *) answer);
n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
- anslen, answerp, answerp2, nanswerp2, resplen2);
+ anslen, answerp, answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (use_malloc)
free (buf);
if (n < 0) {
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
int anslen) /* size of answer buffer */
{
return __libc_res_nquery(statp, name, class, type, answer, anslen,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nquery)
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
u_char **answerp,
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
const char *cp, * const *domain;
HEADER *hp = (HEADER *) answer;
@@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp,
if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
return (__libc_res_nquery(statp, cp, class, type, answer,
anslen, answerp, answerp2,
- nanswerp2, resplen2));
+ nanswerp2, resplen2, answerp2_malloced));
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -377,7 +380,8 @@ __libc_res_nsearch(res_state statp,
if (dots >= statp->ndots || trailing_dot) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
- answerp2, nanswerp2, resplen2);
+ answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (ret > 0 || trailing_dot)
return (ret);
saved_herrno = h_errno;
@@ -386,11 +390,11 @@ __libc_res_nsearch(res_state statp,
answer = *answerp;
anslen = MAXPACKET;
}
- if (answerp2
- && (*answerp2 < answer || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
}
@@ -417,7 +421,7 @@ __libc_res_nsearch(res_state statp,
class, type,
answer, anslen, answerp,
answerp2, nanswerp2,
- resplen2);
+ resplen2, answerp2_malloced);
if (ret > 0)
return (ret);
@@ -425,12 +429,11 @@ __libc_res_nsearch(res_state statp,
answer = *answerp;
anslen = MAXPACKET;
}
- if (answerp2
- && (*answerp2 < answer
- || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
/*
@@ -486,7 +489,8 @@ __libc_res_nsearch(res_state statp,
&& !(tried_as_is || root_on_list)) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp,
- answerp2, nanswerp2, resplen2);
+ answerp2, nanswerp2, resplen2,
+ answerp2_malloced);
if (ret > 0)
return (ret);
}
@@ -498,10 +502,11 @@ __libc_res_nsearch(res_state statp,
* else send back meaningless H_ERRNO, that being the one from
* the last DNSRCH we did.
*/
- if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
+ if (answerp2 && *answerp2_malloced)
{
free (*answerp2);
*answerp2 = NULL;
+ *answerp2_malloced = 0;
}
if (saved_herrno != -1)
RES_SET_H_ERRNO(statp, saved_herrno);
@@ -521,7 +526,7 @@ res_nsearch(res_state statp,
int anslen) /* size of answer */
{
return __libc_res_nsearch(statp, name, class, type, answer,
- anslen, NULL, NULL, NULL, NULL);
+ anslen, NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nsearch)
@@ -539,7 +544,8 @@ __libc_res_nquerydomain(res_state statp,
u_char **answerp,
u_char **answerp2,
int *nanswerp2,
- int *resplen2)
+ int *resplen2,
+ int *answerp2_malloced)
{
char nbuf[MAXDNAME];
const char *longname = nbuf;
@@ -581,7 +587,7 @@ __libc_res_nquerydomain(res_state statp,
}
return (__libc_res_nquery(statp, longname, class, type, answer,
anslen, answerp, answerp2, nanswerp2,
- resplen2));
+ resplen2, answerp2_malloced));
}
int
@@ -593,7 +599,8 @@ res_nquerydomain(res_state statp,
int anslen) /* size of answer */
{
return __libc_res_nquerydomain(statp, name, domain, class, type,
- answer, anslen, NULL, NULL, NULL, NULL);
+ answer, anslen, NULL, NULL, NULL, NULL,
+ NULL);
}
libresolv_hidden_def (res_nquerydomain)
Index: glibc-2.19/resolv/res_send.c
===================================================================
--- glibc-2.19.orig/resolv/res_send.c
+++ glibc-2.19/resolv/res_send.c
@@ -186,12 +186,12 @@ evNowTime(struct timespec *res) {
static int send_vc(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int, u_char **,
- u_char **, int *, int *);
+ u_char **, int *, int *, int *);
static int send_dg(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int,
int *, int *, u_char **,
- u_char **, int *, int *);
+ u_char **, int *, int *, int *);
#ifdef DEBUG
static void Aerror(const res_state, FILE *, const char *, int,
const struct sockaddr *);
@@ -343,7 +343,7 @@ int
__libc_res_nsend(res_state statp, const u_char *buf, int buflen,
const u_char *buf2, int buflen2,
u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
- int *nansp2, int *resplen2)
+ int *nansp2, int *resplen2, int *ansp2_malloced)
{
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
@@ -546,7 +546,8 @@ __libc_res_nsend(res_state statp, const
try = statp->retry;
n = send_vc(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno,
- ns, ansp, ansp2, nansp2, resplen2);
+ ns, ansp, ansp2, nansp2, resplen2,
+ ansp2_malloced);
if (n < 0)
return (-1);
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -556,7 +557,7 @@ __libc_res_nsend(res_state statp, const
n = send_dg(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno,
ns, &v_circuit, &gotsomewhere, ansp,
- ansp2, nansp2, resplen2);
+ ansp2, nansp2, resplen2, ansp2_malloced);
if (n < 0)
return (-1);
if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -646,7 +647,7 @@ res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz)
{
return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
}
libresolv_hidden_def (res_nsend)
@@ -657,7 +658,7 @@ send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
u_char **ansp, int *anssizp,
int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
- int *resplen2)
+ int *resplen2, int *ansp2_malloced)
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
@@ -823,6 +824,8 @@ send_vc(res_state statp,
}
*thisanssizp = MAXPACKET;
*thisansp = newp;
+ if (thisansp == ansp2)
+ *ansp2_malloced = 1;
anhp = (HEADER *) newp;
len = rlen;
} else {
@@ -992,7 +995,7 @@ send_dg(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
u_char **ansp, int *anssizp,
int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
- u_char **ansp2, int *anssizp2, int *resplen2)
+ u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
@@ -1238,6 +1241,8 @@ send_dg(res_state statp,
if (newp != NULL) {
*anssizp = MAXPACKET;
*thisansp = ans = newp;
+ if (thisansp == ansp2)
+ *ansp2_malloced = 1;
}
}
HEADER *anhp = (HEADER *) *thisansp;
++++++ nss-files-long-lines.patch ++++++
2014-06-23 Andreas Schwab
[BZ #17079]
* nss/nss_files/files-XXX.c (get_contents): Store overflow marker
before reading the next line.
Index: glibc-2.19/nss/nss_files/files-XXX.c
===================================================================
--- glibc-2.19.orig/nss/nss_files/files-XXX.c
+++ glibc-2.19/nss/nss_files/files-XXX.c
@@ -198,10 +198,12 @@ get_contents (char *linebuf, size_t len,
{
int curlen = ((remaining_len > (size_t) INT_MAX) ? INT_MAX
: remaining_len);
- char *p = fgets_unlocked (curbuf, curlen, stream);
+ /* Terminate the line so that we can test for overflow. */
((unsigned char *) curbuf)[curlen - 1] = 0xff;
+ char *p = fgets_unlocked (curbuf, curlen, stream);
+
/* EOF or read error. */
if (p == NULL)
return gcr_error;
++++++ nss-nis-stack-use.patch ++++++
2014-05-12 Andreas Schwab
[BZ #16932]
* nis/nss_nis/nis-hosts.c (internal_gethostbyname2_r)
(_nss_nis_gethostbyname4_r): Return error if item length is larger
than maximum RPC packet size.
* nis/nss_nis/nis-initgroups.c (initgroups_netid): Likewise.
* nis/nss_nis/nis-network.c (_nss_nis_getnetbyname_r): Likewise.
* nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r)
(_nss_nis_getservbyport_r): Likewise.
Index: glibc-2.19/nis/nss_nis/nis-hosts.c
===================================================================
--- glibc-2.19.orig/nis/nss_nis/nis-hosts.c
+++ glibc-2.19/nis/nss_nis/nis-hosts.c
@@ -270,6 +270,13 @@ internal_gethostbyname2_r (const char *n
/* Convert name to lowercase. */
size_t namlen = strlen (name);
+ /* Limit name length to the maximum size of an RPC packet. */
+ if (namlen > UDPMSGSIZE)
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_UNAVAIL;
+ }
+
char name2[namlen + 1];
size_t i;
@@ -461,6 +468,13 @@ _nss_nis_gethostbyname4_r (const char *n
/* Convert name to lowercase. */
size_t namlen = strlen (name);
+ /* Limit name length to the maximum size of an RPC packet. */
+ if (namlen > UDPMSGSIZE)
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_UNAVAIL;
+ }
+
char name2[namlen + 1];
size_t i;
Index: glibc-2.19/nis/nss_nis/nis-initgroups.c
===================================================================
--- glibc-2.19.orig/nis/nss_nis/nis-initgroups.c
+++ glibc-2.19/nis/nss_nis/nis-initgroups.c
@@ -150,6 +150,13 @@ initgroups_netid (uid_t uid, gid_t group
gid_t **groupsp, long int limit, int *errnop,
const char *domainname)
{
+ /* Limit domainname length to the maximum size of an RPC packet. */
+ if (strlen (domainname) > UDPMSGSIZE)
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_UNAVAIL;
+ }
+
/* Prepare the key. The form is "unix.UID@DOMAIN" with the UID and
DOMAIN field filled in appropriately. */
char key[sizeof ("unix.@") + sizeof (uid_t) * 3 + strlen (domainname)];
Index: glibc-2.19/nis/nss_nis/nis-network.c
===================================================================
--- glibc-2.19.orig/nis/nss_nis/nis-network.c
+++ glibc-2.19/nis/nss_nis/nis-network.c
@@ -179,6 +179,13 @@ _nss_nis_getnetbyname_r (const char *nam
/* Convert name to lowercase. */
size_t namlen = strlen (name);
+ /* Limit name length to the maximum size of an RPC packet. */
+ if (namlen > UDPMSGSIZE)
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_UNAVAIL;
+ }
+
char name2[namlen + 1];
size_t i;
Index: glibc-2.19/nis/nss_nis/nis-service.c
===================================================================
--- glibc-2.19.orig/nis/nss_nis/nis-service.c
+++ glibc-2.19/nis/nss_nis/nis-service.c
@@ -271,6 +271,13 @@ _nss_nis_getservbyname_r (const char *na
/* If the protocol is given, we could try if our NIS server knows
about services.byservicename map. If yes, we only need one query. */
size_t keylen = strlen (name) + (protocol ? 1 + strlen (protocol) : 0);
+ /* Limit key length to the maximum size of an RPC packet. */
+ if (keylen > UDPMSGSIZE)
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_UNAVAIL;
+ }
+
char key[keylen + 1];
/* key is: "name/proto" */
@@ -355,6 +362,13 @@ _nss_nis_getservbyport_r (int port, cons
Otherwise try first port/tcp, then port/udp and then fallback
to sequential scanning of services.byname. */
const char *proto = protocol != NULL ? protocol : "tcp";
+ /* Limit protocol name length to the maximum size of an RPC packet. */
+ if (strlen (proto) > UDPMSGSIZE)
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_UNAVAIL;
+ }
+
do
{
/* key is: "port/proto" */
++++++ nss-separate-state-getXXent.patch ++++++
++++ 715 lines (skipped)
++++++ nsswitch.conf ++++++
#
# /etc/nsswitch.conf
#
# An example Name Service Switch config file. This file should be
# sorted with the most-used services at the beginning.
#
# The entry '[NOTFOUND=return]' means that the search for an
# entry should stop if the search in the previous entry turned
# up nothing. Note that if the search failed due to some other reason
# (like no NIS server responding) then the search continues with the
# next entry.
#
# Legal entries are:
#
# compat Use compatibility setup
# nisplus Use NIS+ (NIS version 3)
# nis Use NIS (NIS version 2), also called YP
# dns Use DNS (Domain Name Service)
# files Use the local files
# [NOTFOUND=return] Stop searching if not found so far
#
# For more information, please read the nsswitch.conf.5 manual page.
#
# passwd: files nis
# shadow: files nis
# group: files nis
passwd: compat
group: compat
hosts: files dns
networks: files dns
services: files
protocols: files
rpc: files
ethers: files
netmasks: files
netgroup: files nis
publickey: files
bootparams: files
automount: files nis
aliases: files
++++++ open-o-tmpfile-mode.patch ++++++
2015-02-24 Eric Rannaud
[BZ #17523]
* io/fcntl.h (__OPEN_NEEDS_MODE): New macro.
* io/bits/fcntl2.h (open): Use it.
(openat): Likewise.
* io/open.c (__libc_open): Likewise.
* io/open64.c (__libc_open64): Likewise.
* io/open64_2.c (__open64_2): Likewise.
* io/open_2.c (__open_2): Likewise.
* io/openat.c (__openat): Likewise.
* io/openat64.c (__openat64): Likewise.
* io/openat64_2.c (__openat64_2): Likewise.
* io/openat_2.c (__openat_2): Likewise.
* sysdeps/mach/hurd/open.c (__libc_open): Likewise.
* sysdeps/mach/hurd/openat.c (__openat): Likewise.
* sysdeps/posix/open64.c (__libc_open64): Likewise.
* sysdeps/unix/sysv/linux/dl-openat64.c (openat64): Likewise.
* ports/sysdeps/unix/sysv/linux/generic/open.c (__libc_open): Likewise.
(__open_nocancel): Likewise.
* ports/sysdeps/unix/sysv/linux/generic/open64.c (__libc_open64):
Likewise.
* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise.
* sysdeps/unix/sysv/linux/openat.c (__OPENAT): Likewise.
Index: glibc-2.19/io/bits/fcntl2.h
===================================================================
--- glibc-2.19.orig/io/bits/fcntl2.h
+++ glibc-2.19/io/bits/fcntl2.h
@@ -20,7 +20,7 @@
# error "Never include directly; use instead."
#endif
-/* Check that calls to open and openat with O_CREAT set have an
+/* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an
appropriate third/fourth parameter. */
#ifndef __USE_FILE_OFFSET64
extern int __open_2 (const char *__path, int __oflag) __nonnull ((1));
@@ -35,7 +35,7 @@ extern int __REDIRECT (__open_alias, (co
__errordecl (__open_too_many_args,
"open can be called either with 2 or 3 arguments, not more");
__errordecl (__open_missing_mode,
- "open with O_CREAT in second argument needs 3 arguments");
+ "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
__fortify_function int
open (const char *__path, int __oflag, ...)
@@ -45,7 +45,7 @@ open (const char *__path, int __oflag, .
if (__builtin_constant_p (__oflag))
{
- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
{
__open_missing_mode ();
return __open_2 (__path, __oflag);
@@ -67,7 +67,7 @@ extern int __REDIRECT (__open64_alias, (
__errordecl (__open64_too_many_args,
"open64 can be called either with 2 or 3 arguments, not more");
__errordecl (__open64_missing_mode,
- "open64 with O_CREAT in second argument needs 3 arguments");
+ "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments");
__fortify_function int
open64 (const char *__path, int __oflag, ...)
@@ -77,7 +77,7 @@ open64 (const char *__path, int __oflag,
if (__builtin_constant_p (__oflag))
{
- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
{
__open64_missing_mode ();
return __open64_2 (__path, __oflag);
@@ -111,7 +111,7 @@ extern int __REDIRECT (__openat_alias, (
__errordecl (__openat_too_many_args,
"openat can be called either with 3 or 4 arguments, not more");
__errordecl (__openat_missing_mode,
- "openat with O_CREAT in third argument needs 4 arguments");
+ "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
__fortify_function int
openat (int __fd, const char *__path, int __oflag, ...)
@@ -121,7 +121,7 @@ openat (int __fd, const char *__path, in
if (__builtin_constant_p (__oflag))
{
- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
{
__openat_missing_mode ();
return __openat_2 (__fd, __path, __oflag);
@@ -145,7 +145,7 @@ extern int __REDIRECT (__openat64_alias,
__errordecl (__openat64_too_many_args,
"openat64 can be called either with 3 or 4 arguments, not more");
__errordecl (__openat64_missing_mode,
- "openat64 with O_CREAT in third argument needs 4 arguments");
+ "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments");
__fortify_function int
openat64 (int __fd, const char *__path, int __oflag, ...)
@@ -155,7 +155,7 @@ openat64 (int __fd, const char *__path,
if (__builtin_constant_p (__oflag))
{
- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1)
+ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1)
{
__openat64_missing_mode ();
return __openat64_2 (__fd, __path, __oflag);
Index: glibc-2.19/io/fcntl.h
===================================================================
--- glibc-2.19.orig/io/fcntl.h
+++ glibc-2.19/io/fcntl.h
@@ -34,6 +34,15 @@ __BEGIN_DECLS
numbers and flag bits for `open', `fcntl', et al. */
#include
+/* Detect if open needs mode as a third argument (or for openat as a fourth
+ argument). */
+#ifdef __O_TMPFILE
+# define __OPEN_NEEDS_MODE(oflag) \
+ (((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)
+#else
+# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)
+#endif
+
/* POSIX.1-2001 specifies that these types are defined by .
Earlier POSIX standards permitted any type ending in `_t' to be defined
by any POSIX header, so we don't conditionalize the definitions here. */
@@ -160,8 +169,9 @@ typedef __pid_t pid_t;
extern int fcntl (int __fd, int __cmd, ...);
/* Open FILE and return a new file descriptor for it, or -1 on error.
- OFLAG determines the type of access used. If O_CREAT is on OFLAG,
- the third argument is taken as a `mode_t', the mode of the created file.
+ OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set
+ in OFLAG, the third argument is taken as a `mode_t', the mode of the
+ created file.
This function is a cancellation point and therefore not marked with
__THROW. */
Index: glibc-2.19/io/open.c
===================================================================
--- glibc-2.19.orig/io/open.c
+++ glibc-2.19/io/open.c
@@ -23,7 +23,7 @@
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open (file, oflag)
@@ -38,7 +38,7 @@ __libc_open (file, oflag)
return -1;
}
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start(arg, oflag);
Index: glibc-2.19/io/open64.c
===================================================================
--- glibc-2.19.orig/io/open64.c
+++ glibc-2.19/io/open64.c
@@ -21,7 +21,7 @@
#include
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open64 (file, oflag)
@@ -36,7 +36,7 @@ __libc_open64 (file, oflag)
return -1;
}
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/io/open64_2.c
===================================================================
--- glibc-2.19.orig/io/open64_2.c
+++ glibc-2.19/io/open64_2.c
@@ -22,8 +22,8 @@
int
__open64_2 (const char *file, int oflag)
{
- if (oflag & O_CREAT)
- __fortify_fail ("invalid open64 call: O_CREAT without mode");
+ if (__OPEN_NEEDS_MODE (oflag))
+ __fortify_fail ("invalid open64 call: O_CREAT or O_TMPFILE without mode");
return __open64 (file, oflag);
}
Index: glibc-2.19/io/open_2.c
===================================================================
--- glibc-2.19.orig/io/open_2.c
+++ glibc-2.19/io/open_2.c
@@ -22,8 +22,8 @@
int
__open_2 (const char *file, int oflag)
{
- if (oflag & O_CREAT)
- __fortify_fail ("invalid open call: O_CREAT without mode");
+ if (__OPEN_NEEDS_MODE (oflag))
+ __fortify_fail ("invalid open call: O_CREAT or O_TMPFILE without mode");
return __open (file, oflag);
}
Index: glibc-2.19/io/openat.c
===================================================================
--- glibc-2.19.orig/io/openat.c
+++ glibc-2.19/io/openat.c
@@ -30,7 +30,7 @@ int __have_atfcts;
#endif
/* Open FILE with access OFLAG. Interpret relative paths relative to
- the directory associated with FD. If OFLAG includes O_CREAT, a
+ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a
third argument is the file protection. */
int
__openat (fd, file, oflag)
@@ -60,7 +60,7 @@ __openat (fd, file, oflag)
}
}
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/io/openat64.c
===================================================================
--- glibc-2.19.orig/io/openat64.c
+++ glibc-2.19/io/openat64.c
@@ -23,7 +23,7 @@
#include
/* Open FILE with access OFLAG. Interpret relative paths relative to
- the directory associated with FD. If OFLAG includes O_CREAT, a
+ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a
third argument is the file protection. */
int
__openat64 (fd, file, oflag)
@@ -53,7 +53,7 @@ __openat64 (fd, file, oflag)
}
}
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/io/openat64_2.c
===================================================================
--- glibc-2.19.orig/io/openat64_2.c
+++ glibc-2.19/io/openat64_2.c
@@ -22,8 +22,8 @@
int
__openat64_2 (int fd, const char *file, int oflag)
{
- if (oflag & O_CREAT)
- __fortify_fail ("invalid openat64 call: O_CREAT without mode");
+ if (__OPEN_NEEDS_MODE (oflag))
+ __fortify_fail ("invalid openat64 call: O_CREAT or O_TMPFILE without mode");
return __openat64 (fd, file, oflag);
}
Index: glibc-2.19/io/openat_2.c
===================================================================
--- glibc-2.19.orig/io/openat_2.c
+++ glibc-2.19/io/openat_2.c
@@ -22,8 +22,8 @@
int
__openat_2 (int fd, const char *file, int oflag)
{
- if (oflag & O_CREAT)
- __fortify_fail ("invalid openat call: O_CREAT without mode");
+ if (__OPEN_NEEDS_MODE (oflag))
+ __fortify_fail ("invalid openat call: O_CREAT or O_TMPFILE without mode");
return __openat (fd, file, oflag);
}
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/generic/open.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/generic/open.c
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/generic/open.c
@@ -22,14 +22,14 @@
#include
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open (const char *file, int oflag, ...)
{
int mode = 0;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
@@ -59,7 +59,7 @@ __open_nocancel (const char *file, int o
{
int mode = 0;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/generic/open64.c
===================================================================
--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/generic/open64.c
+++ glibc-2.19/ports/sysdeps/unix/sysv/linux/generic/open64.c
@@ -22,14 +22,14 @@
#include
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open64 (const char *file, int oflag, ...)
{
int mode = 0;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/sysdeps/mach/hurd/open.c
===================================================================
--- glibc-2.19.orig/sysdeps/mach/hurd/open.c
+++ glibc-2.19/sysdeps/mach/hurd/open.c
@@ -22,7 +22,7 @@
#include
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open (const char *file, int oflag, ...)
@@ -30,7 +30,7 @@ __libc_open (const char *file, int oflag
mode_t mode;
io_t port;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/sysdeps/mach/hurd/openat.c
===================================================================
--- glibc-2.19.orig/sysdeps/mach/hurd/openat.c
+++ glibc-2.19/sysdeps/mach/hurd/openat.c
@@ -26,7 +26,7 @@
#include
/* Open FILE with access OFLAG. Interpret relative paths relative to
- the directory associated with FD. If OFLAG includes O_CREAT, a
+ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a
third argument is the file protection. */
int
__openat (fd, file, oflag)
@@ -37,7 +37,7 @@ __openat (fd, file, oflag)
mode_t mode;
io_t port;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/sysdeps/posix/open64.c
===================================================================
--- glibc-2.19.orig/sysdeps/posix/open64.c
+++ glibc-2.19/sysdeps/posix/open64.c
@@ -19,14 +19,14 @@
#include
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open64 (const char *file, int oflag, ...)
{
int mode = 0;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/sysdeps/unix/sysv/linux/dl-openat64.c
===================================================================
--- glibc-2.19.orig/sysdeps/unix/sysv/linux/dl-openat64.c
+++ glibc-2.19/sysdeps/unix/sysv/linux/dl-openat64.c
@@ -28,7 +28,7 @@ openat64 (dfd, file, oflag)
const char *file;
int oflag;
{
- assert ((oflag & O_CREAT) == 0);
+ assert (!__OPEN_NEEDS_MODE (oflag));
#ifdef __NR_openat
return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE);
Index: glibc-2.19/sysdeps/unix/sysv/linux/open64.c
===================================================================
--- glibc-2.19.orig/sysdeps/unix/sysv/linux/open64.c
+++ glibc-2.19/sysdeps/unix/sysv/linux/open64.c
@@ -21,14 +21,14 @@
#include
#include
-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT,
+/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG,
a third argument is the file protection. */
int
__libc_open64 (const char *file, int oflag, ...)
{
int mode = 0;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
Index: glibc-2.19/sysdeps/unix/sysv/linux/openat.c
===================================================================
--- glibc-2.19.orig/sysdeps/unix/sysv/linux/openat.c
+++ glibc-2.19/sysdeps/unix/sysv/linux/openat.c
@@ -148,8 +148,8 @@ OPENAT_NOT_CANCEL (fd, file, oflag, mode
/* Open FILE with access OFLAG. Interpret relative paths relative to
- the directory associated with FD. If OFLAG includes O_CREAT, a
- third argument is the file protection. */
+ the directory associated with FD. If OFLAG includes O_CREAT or
+ O_TMPFILE, a fourth argument is the file protection. */
int
__OPENAT (fd, file, oflag)
int fd;
@@ -157,7 +157,7 @@ __OPENAT (fd, file, oflag)
int oflag;
{
mode_t mode = 0;
- if (oflag & O_CREAT)
+ if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
++++++ pldd-wait-ptrace-stop.patch ++++++
2014-02-24 Andreas Schwab
[BZ #15804]
* elf/pldd.c (wait_for_ptrace_stop): New function.
(main): Call it after attaching.
Index: glibc-2.19/elf/pldd.c
===================================================================
--- glibc-2.19.orig/elf/pldd.c
+++ glibc-2.19/elf/pldd.c
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#include
@@ -82,6 +83,7 @@ static char *exe;
/* Local functions. */
static int get_process_info (int dfd, long int pid);
+static void wait_for_ptrace_stop (long int pid);
int
@@ -170,6 +172,8 @@ main (int argc, char *argv[])
tid);
}
+ wait_for_ptrace_stop (tid);
+
struct thread_list *newp = alloca (sizeof (*newp));
newp->tid = tid;
newp->next = thread_list;
@@ -194,6 +198,27 @@ main (int argc, char *argv[])
}
+/* Wait for PID to enter ptrace-stop state after being attached. */
+static void
+wait_for_ptrace_stop (long int pid)
+{
+ int status;
+
+ /* While waiting for SIGSTOP being delivered to the tracee we have to
+ reinject any other pending signal. Ignore all other errors. */
+ while (waitpid (pid, &status, __WALL) == pid && WIFSTOPPED (status))
+ {
+ /* The STOP signal should not be delivered to the tracee. */
+ if (WSTOPSIG (status) == SIGSTOP)
+ return;
+ if (ptrace (PTRACE_CONT, pid, NULL,
+ (void *) (uintptr_t) WSTOPSIG (status)))
+ /* The only possible error is that the process died. */
+ return;
+ }
+}
+
+
/* Handle program arguments. */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
++++++ powerpc-opt-power8.patch ++++++
++++ 2696 lines (skipped)
++++++ ppc64-copysign.patch ++++++
2014-04-01 Alan Modra
[BZ #16786]
* sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Don't trash stack.
Index: glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
===================================================================
--- glibc-2.19.orig/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
+++ glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
@@ -27,11 +27,11 @@ ENTRY(__copysign)
/* double [f1] copysign (double [f1] x, double [f2] y);
copysign(x,y) returns a value with the magnitude of x and
with the sign bit of y. */
- stfd fp2,56(r1)
+ stfd fp2,-8(r1)
nop
nop
nop
- ld r3,56(r1)
+ ld r3,-8(r1)
cmpdi r3,0
blt L(0)
fabs fp1,fp1
++++++ ppc64le-profiling.patch ++++++
2013-07-29 Adhemerval Zanella
[BZ #17213]
* sysdeps/powerpc/powerpc64/entry.h: Fix TEXT_START definition for
powerpc64le.
Index: glibc-2.19/sysdeps/powerpc/powerpc64/entry.h
===================================================================
--- glibc-2.19.orig/sysdeps/powerpc/powerpc64/entry.h
+++ glibc-2.19/sysdeps/powerpc/powerpc64/entry.h
@@ -23,6 +23,7 @@ extern void _start (void);
#define ENTRY_POINT _start
+#if _CALL_ELF != 2
/* We have to provide a special declaration. */
#define ENTRY_POINT_DECL(class) class void _start (void);
@@ -33,3 +34,4 @@ extern void _start (void);
#define TEXT_START \
({ extern unsigned long int _start_as_data[] asm ("_start"); \
_start_as_data[0]; })
+#endif
++++++ pre_checkin.sh ++++++
#!/bin/bash
# This script is called automatically during autobuild checkin.
sed -e 's/^Name:.*glibc/&-testsuite/' glibc.spec > glibc-testsuite.spec
cp glibc.changes glibc-testsuite.changes
awk '/^Name:/{ $0 = $0 "-utils" }
/UTILS-SUMMARY-BEGIN/ {
ignore = 1
print "\
Summary: Development utilities from GNU C library\n\
License: LGPL-2.1+\n\
Group: Development/Languages/C and C++"
}
/UTILS-SUMMARY-END/ { ignore = 0 }
/^%description$/ {
ignore = 1
print "\
%description\n\
The glibc-utils package contains mtrace, a memory leak tracer and\n\
xtrace, a function call tracer which can be helpful during program\n\
debugging.\n\
\n\
If you are unsure if you need this, don'\''t install this package.\n"
}
/^%package/ { ignore = 0}
!ignore { print }' glibc.spec > glibc-utils.spec
cp glibc.changes glibc-utils.changes
osc service localrun format_spec_file
++++++ psfaa.patch ++++++
2014-06-11 Florian Weimer
[BZ #17048]
* posix/spawn_int.h (struct __spawn_action): Make the path string
non-const to support deallocation.
* posix/spawn_faction_addopen.c
(posix_spawn_file_actions_addopen): Make a copy of the pathname.
* posix/spawn_faction_destroy.c
(posix_spawn_file_actions_destroy): Adjust comment. Deallocate
path in all spawn_do_open actions.
* posix/tst-spawn.c (do_test): Exercise the copy operation in
posix_spawn_file_actions_addopen.
Index: glibc-2.19/posix/spawn_faction_addopen.c
===================================================================
--- glibc-2.19.orig/posix/spawn_faction_addopen.c
+++ glibc-2.19/posix/spawn_faction_addopen.c
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include "spawn_int.h"
@@ -35,17 +36,24 @@ posix_spawn_file_actions_addopen (posix_
if (fd < 0 || fd >= maxfd)
return EBADF;
+ char *path_copy = strdup (path);
+ if (path_copy == NULL)
+ return ENOMEM;
+
/* Allocate more memory if needed. */
if (file_actions->__used == file_actions->__allocated
&& __posix_spawn_file_actions_realloc (file_actions) != 0)
- /* This can only mean we ran out of memory. */
- return ENOMEM;
+ {
+ /* This can only mean we ran out of memory. */
+ free (path_copy);
+ return ENOMEM;
+ }
/* Add the new value. */
rec = &file_actions->__actions[file_actions->__used];
rec->tag = spawn_do_open;
rec->action.open_action.fd = fd;
- rec->action.open_action.path = path;
+ rec->action.open_action.path = path_copy;
rec->action.open_action.oflag = oflag;
rec->action.open_action.mode = mode;
Index: glibc-2.19/posix/spawn_faction_destroy.c
===================================================================
--- glibc-2.19.orig/posix/spawn_faction_destroy.c
+++ glibc-2.19/posix/spawn_faction_destroy.c
@@ -18,11 +18,29 @@
#include
#include
-/* Initialize data structure for file attribute for `spawn' call. */
+#include "spawn_int.h"
+
+/* Deallocate the file actions. */
int
posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
{
- /* Free the memory allocated. */
+ /* Free the paths in the open actions. */
+ for (int i = 0; i < file_actions->__used; ++i)
+ {
+ struct __spawn_action *sa = &file_actions->__actions[i];
+ switch (sa->tag)
+ {
+ case spawn_do_open:
+ free (sa->action.open_action.path);
+ break;
+ case spawn_do_close:
+ case spawn_do_dup2:
+ /* No cleanup required. */
+ break;
+ }
+ }
+
+ /* Free the array of actions. */
free (file_actions->__actions);
return 0;
}
Index: glibc-2.19/posix/spawn_int.h
===================================================================
--- glibc-2.19.orig/posix/spawn_int.h
+++ glibc-2.19/posix/spawn_int.h
@@ -22,7 +22,7 @@ struct __spawn_action
struct
{
int fd;
- const char *path;
+ char *path;
int oflag;
mode_t mode;
} open_action;
Index: glibc-2.19/posix/tst-spawn.c
===================================================================
--- glibc-2.19.orig/posix/tst-spawn.c
+++ glibc-2.19/posix/tst-spawn.c
@@ -168,6 +168,7 @@ do_test (int argc, char *argv[])
char fd2name[18];
char fd3name[18];
char fd4name[18];
+ char *name3_copy;
char *spargv[12];
int i;
@@ -222,9 +223,15 @@ do_test (int argc, char *argv[])
if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
/* We want to open the third file. */
- if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
+ name3_copy = strdup (name3);
+ if (name3_copy == NULL)
+ error (EXIT_FAILURE, errno, "strdup");
+ if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy,
O_RDONLY, 0666) != 0)
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
+ /* Overwrite the name to check that a copy has been made. */
+ memset (name3_copy, 'X', strlen (name3_copy));
+
/* We dup the second descriptor. */
fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
@@ -253,6 +260,7 @@ do_test (int argc, char *argv[])
/* Cleanup. */
if (posix_spawn_file_actions_destroy (&actions) != 0)
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
+ free (name3_copy);
/* Wait for the child. */
if (waitpid (pid, &status, 0) != pid)
++++++ pthread-mutex-trylock-elision.patch ++++++
[PATCH] Properly handle forced elision in pthread_mutex_trylock
BZ #16657
* pthread_mutex_trylock.c (__pthread_mutex_trylock): Use
FORCE_ELISION instead of DO_ELISION.
* sysdeps/unix/sysv/linux/x86/force-elision.h (DO_ELISION):
Remove.
---
nptl/pthread_mutex_trylock.c | 7 +++----
nptl/sysdeps/unix/sysv/linux/x86/force-elision.h | 5 -----
2 files changed, 3 insertions(+), 9 deletions(-)
Index: glibc-2.19/nptl/pthread_mutex_trylock.c
===================================================================
--- glibc-2.19.orig/nptl/pthread_mutex_trylock.c
+++ glibc-2.19/nptl/pthread_mutex_trylock.c
@@ -26,8 +26,8 @@
#define lll_trylock_elision(a,t) lll_trylock(a)
#endif
-#ifndef DO_ELISION
-#define DO_ELISION(m) 0
+#ifndef FORCE_ELISION
+#define FORCE_ELISION(m, s)
#endif
/* We don't force elision in trylock, because this can lead to inconsistent
@@ -77,8 +77,7 @@ __pthread_mutex_trylock (mutex)
return 0;
case PTHREAD_MUTEX_TIMED_NP:
- if (DO_ELISION (mutex))
- goto elision;
+ FORCE_ELISION (mutex, goto elision);
/*FALL THROUGH*/
case PTHREAD_MUTEX_ADAPTIVE_NP:
case PTHREAD_MUTEX_ERRORCHECK_NP:
Index: glibc-2.19/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
===================================================================
--- glibc-2.19.orig/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
+++ glibc-2.19/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h
@@ -16,11 +16,6 @@
License along with the GNU C Library; if not, see
http://www.gnu.org/licenses/. */
-/* Check for elision on this lock without upgrading. */
-#define DO_ELISION(m) \
- (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0) \
-
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
if (__pthread_force_elision \
++++++ pthread-mutexattr-gettype-kind.patch ++++++
pthread_mutexattr_gettype (BZ #15790)
[BZ #15790]
* nptl/pthread_mutexattr_gettype.c (pthread_mutexattr_gettype):
Filter out PTHREAD_MUTEX_NO_ELISION_NP from value returned in
kind.
* nptl/Makefile (tests): Add tst-pthread-mutexattr.
* nptl/tst-pthread-mutexattr.c: New file.
---
nptl/Makefile | 2 +-
nptl/pthread_mutexattr_gettype.c | 3 +-
nptl/tst-pthread-mutexattr.c | 60 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 2 deletions(-)
create mode 100644 nptl/tst-pthread-mutexattr.c
Index: glibc-2.19/nptl/Makefile
===================================================================
--- glibc-2.19.orig/nptl/Makefile
+++ glibc-2.19/nptl/Makefile
@@ -253,7 +253,7 @@ tests = tst-typesizes \
tst-exit1 tst-exit2 tst-exit3 \
tst-stdio1 tst-stdio2 \
tst-stack1 tst-stack2 tst-stack3 tst-pthread-getattr \
- tst-pthread-attr-affinity \
+ tst-pthread-attr-affinity tst-pthread-mutexattr \
tst-unload \
tst-dlsym1 \
tst-sysconf \
Index: glibc-2.19/nptl/pthread_mutexattr_gettype.c
===================================================================
--- glibc-2.19.orig/nptl/pthread_mutexattr_gettype.c
+++ glibc-2.19/nptl/pthread_mutexattr_gettype.c
@@ -28,7 +28,8 @@ pthread_mutexattr_gettype (attr, kind)
iattr = (const struct pthread_mutexattr *) attr;
- *kind = iattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
+ *kind = (iattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS
+ & ~PTHREAD_MUTEX_NO_ELISION_NP);
return 0;
}
Index: glibc-2.19/nptl/tst-pthread-mutexattr.c
===================================================================
--- /dev/null
+++ glibc-2.19/nptl/tst-pthread-mutexattr.c
@@ -0,0 +1,60 @@
+/* Make sure that pthread_mutexattr_gettype returns a valid kind.
+
+ Copyright (C) 2014 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
+#include
+#include
+
+static int
+do_test (void)
+{
+ pthread_mutexattr_t attr;
+ int kind;
+ int error;
+
+ error = pthread_mutexattr_init (&attr);
+ if (error)
+ {
+ printf ("pthread_mutexattr_init: %s\n", strerror (error));
+ return 1;
+ }
+ error = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_DEFAULT);
+ if (error)
+ {
+ printf ("pthread_mutexattr_settype (1): %s\n", strerror (error));
+ return 1;
+ }
+ error = pthread_mutexattr_gettype (&attr, &kind);
+ if (error)
+ {
+ printf ("pthread_mutexattr_gettype: %s\n", strerror (error));
+ return 1;
+ }
+ error = pthread_mutexattr_settype (&attr, kind);
+ if (error)
+ {
+ printf ("pthread_mutexattr_settype (2): %s\n", strerror (error));
+ return 1;
+ }
+ return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
++++++ refactor-nan-parsing.patch ++++++
++++ 896 lines (skipped)
++++++ regcomp-memory-leak.patch ++++++
2014-06-20 Andreas Schwab
[BZ #17069]
* posix/regcomp.c (parse_reg_exp): Deallocate partially
constructed tree before returning error.
* posix/bug-regexp36.c: Expand test case.
2014-06-19 Andreas Schwab
[BZ #17069]
* posix/regcomp.c (parse_expression): Deallocate partially
constructed tree before returning error.
* posix/Makefile.c (tests): Add bug-regex36.
(generated): Add bug-regex36.mtrace.
(tests-special): Add $(objpfx)bug-regex36-mem.out
(bug-regex36-ENV): New variable.
($(objpfx)bug-regex36-mem.out): New rule.
* posix/bug-regex36.c: New file.
Index: glibc-2.19/posix/Makefile
===================================================================
--- glibc-2.19.orig/posix/Makefile
+++ glibc-2.19/posix/Makefile
@@ -86,7 +86,7 @@ tests := tstgetopt testfnm runtests run
tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
- tst-pathconf tst-getaddrinfo4 \
+ tst-pathconf tst-getaddrinfo4 bug-regex36 \
tst-fnmatch3
xtests := bug-ga2
ifeq (yes,$(build-shared))
@@ -111,7 +111,7 @@ generated := $(addprefix wordexp-test-re
tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace \
bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem \
tst-vfork3-mem tst-vfork3.mtrace getconf.speclist \
- tst-fnmatch-mem tst-fnmatch.mtrace
+ tst-fnmatch-mem tst-fnmatch.mtrace bug-regex36.mtrace
include ../Rules
@@ -261,6 +261,12 @@ bug-regex31-ENV = MALLOC_TRACE=$(objpfx)
$(objpfx)bug-regex31-mem: $(objpfx)bug-regex31.out
$(common-objpfx)malloc/mtrace $(objpfx)bug-regex31.mtrace > $@
+bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace
+
+$(objpfx)bug-regex36-mem.out: $(objpfx)bug-regex36.out
+ $(common-objpfx)malloc/mtrace $(objpfx)bug-regex36.mtrace > $@; \
+ $(evaluate-test)
+
tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace
$(objpfx)tst-vfork3-mem: $(objpfx)tst-vfork3.out
Index: glibc-2.19/posix/bug-regex36.c
===================================================================
--- /dev/null
+++ glibc-2.19/posix/bug-regex36.c
@@ -0,0 +1,29 @@
+/* Test regcomp not leaking memory on parse errors
+ Copyright (C) 2014 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
+#include
+
+int
+main (int argc, char **argv)
+{
+ regex_t r;
+ mtrace ();
+ regcomp (&r, "[a]\\|[a]\\{-2,}", 0);
+ regfree (&r);
+}
Index: glibc-2.19/posix/regcomp.c
===================================================================
--- glibc-2.19.orig/posix/regcomp.c
+++ glibc-2.19/posix/regcomp.c
@@ -2154,7 +2154,11 @@ parse_reg_exp (re_string_t *regexp, rege
{
branch = parse_branch (regexp, preg, token, syntax, nest, err);
if (BE (*err != REG_NOERROR && branch == NULL, 0))
- return NULL;
+ {
+ if (tree != NULL)
+ postorder (tree, free_tree, NULL);
+ return NULL;
+ }
}
else
branch = NULL;
@@ -2415,14 +2419,21 @@ parse_expression (re_string_t *regexp, r
while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
|| token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
{
- tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
- if (BE (*err != REG_NOERROR && tree == NULL, 0))
- return NULL;
+ bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+ if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+ {
+ if (tree != NULL)
+ postorder (tree, free_tree, NULL);
+ return NULL;
+ }
+ tree = dup_tree;
/* In BRE consecutive duplications are not allowed. */
if ((syntax & RE_CONTEXT_INVALID_DUP)
&& (token->type == OP_DUP_ASTERISK
|| token->type == OP_OPEN_DUP_NUM))
{
+ if (tree != NULL)
+ postorder (tree, free_tree, NULL);
*err = REG_BADRPT;
return NULL;
}
++++++ reinitialize-dl_load_write_lock.patch ++++++
Index: glibc-2.19/nptl/sysdeps/unix/sysv/linux/fork.c
===================================================================
--- glibc-2.19.orig/nptl/sysdeps/unix/sysv/linux/fork.c
+++ glibc-2.19/nptl/sysdeps/unix/sysv/linux/fork.c
@@ -179,8 +179,9 @@ __libc_fork (void)
/* Reset locks in the I/O code. */
_IO_list_resetlock ();
- /* Reset the lock the dynamic loader uses to protect its data. */
+ /* Reset the locks the dynamic loader uses to protect its data. */
__rtld_lock_initialize (GL(dl_load_lock));
+ __rtld_lock_initialize (GL(dl_load_write_lock));
/* Run the handlers registered for the child. */
while (allp != NULL)
++++++ res-send-fd-reuse.patch ++++++
2014-06-03 Andreas Schwab
[BZ #15946]
* resolv/res_send.c (send_dg): Reload file descriptor after
calling reopen.
Index: glibc-2.19/resolv/res_send.c
===================================================================
--- glibc-2.19.orig/resolv/res_send.c
+++ glibc-2.19/resolv/res_send.c
@@ -1410,6 +1410,7 @@ send_dg(res_state statp,
retval = reopen (statp, terrno, ns);
if (retval <= 0)
return retval;
+ pfd[0].fd = EXT(statp).nssocks[ns];
}
}
goto wait;
++++++ resolv-assertion-failure.patch ++++++
2016-03-25 Florian Weimer
[BZ #19791]
* resolv/res_send.c (close_and_return_error): New function.
(send_dg): Initialize *resplen2 after reopen failure. Call
close_and_return_error for error returns. On error paths without
__res_iclose, initialze *resplen2 explicitly. Update comment for
successful return.
Index: glibc-2.19/resolv/res_send.c
===================================================================
--- glibc-2.19.orig/resolv/res_send.c
+++ glibc-2.19/resolv/res_send.c
@@ -653,6 +653,18 @@ libresolv_hidden_def (res_nsend)
/* Private */
+/* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
+ is not NULL, and return zero. */
+static int
+__attribute__ ((warn_unused_result))
+close_and_return_error (res_state statp, int *resplen2)
+{
+ __res_iclose(statp, false);
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return 0;
+}
+
static int
send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -1025,7 +1037,11 @@ send_dg(res_state statp,
retry_reopen:
retval = reopen (statp, terrno, ns);
if (retval <= 0)
- return retval;
+ {
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return retval;
+ }
retry:
evNowTime(&now);
evConsTime(&timeout, seconds, 0);
@@ -1036,8 +1052,6 @@ send_dg(res_state statp,
int recvresp2 = buf2 == NULL;
pfd[0].fd = EXT(statp).nssocks[ns];
pfd[0].events = POLLOUT;
- if (resplen2 != NULL)
- *resplen2 = 0;
wait:
if (need_recompute) {
recompute_resend:
@@ -1045,9 +1059,7 @@ send_dg(res_state statp,
if (evCmpTime(finish, now) <= 0) {
poll_err_out:
Perror(statp, stderr, "poll", errno);
- err_out:
- __res_iclose(statp, false);
- return (0);
+ return close_and_return_error (statp, resplen2);
}
evSubTime(&timeout, &finish, &now);
need_recompute = 0;
@@ -1094,7 +1106,9 @@ send_dg(res_state statp,
}
*gotsomewhere = 1;
- return (0);
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return 0;
}
if (n < 0) {
if (errno == EINTR)
@@ -1162,7 +1176,7 @@ send_dg(res_state statp,
fail_sendmmsg:
Perror(statp, stderr, "sendmmsg", errno);
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
}
else
@@ -1180,7 +1194,7 @@ send_dg(res_state statp,
if (errno == EINTR || errno == EAGAIN)
goto recompute_resend;
Perror(statp, stderr, "send", errno);
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
just_one:
if (nwritten != 0 || buf2 == NULL || single_request)
@@ -1257,7 +1271,7 @@ send_dg(res_state statp,
goto wait;
}
Perror(statp, stderr, "recvfrom", errno);
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
*gotsomewhere = 1;
if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) {
@@ -1268,7 +1282,7 @@ send_dg(res_state statp,
(stdout, ";; undersized: %d\n",
*thisresplenp));
*terrno = EMSGSIZE;
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
if ((recvresp1 || hp->id != anhp->id)
&& (recvresp2 || hp2->id != anhp->id)) {
@@ -1317,7 +1331,7 @@ send_dg(res_state statp,
? *thisanssizp : *thisresplenp);
/* record the error */
statp->_flags |= RES_F_EDNS0ERR;
- goto err_out;
+ return close_and_return_error (statp, resplen2);
}
#endif
if (!(statp->options & RES_INSECURE2)
@@ -1369,10 +1383,10 @@ send_dg(res_state statp,
}
next_ns:
- __res_iclose(statp, false);
/* don't retry if called from dig */
if (!statp->pfcode)
- return (0);
+ return close_and_return_error (statp, resplen2);
+ __res_iclose(statp, false);
}
if (anhp->rcode == NOERROR && anhp->ancount == 0
&& anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
@@ -1394,6 +1408,8 @@ send_dg(res_state statp,
__res_iclose(statp, false);
// XXX if we have received one reply we could
// XXX use it and not repeat it over TCP...
+ if (resplen2 != NULL)
+ *resplen2 = 0;
return (1);
}
/* Mark which reply we received. */
@@ -1409,21 +1425,22 @@ send_dg(res_state statp,
__res_iclose (statp, false);
retval = reopen (statp, terrno, ns);
if (retval <= 0)
- return retval;
+ {
+ if (resplen2 != NULL)
+ *resplen2 = 0;
+ return retval;
+ }
pfd[0].fd = EXT(statp).nssocks[ns];
}
}
goto wait;
}
- /*
- * All is well, or the error is fatal. Signal that the
- * next nameserver ought not be tried.
- */
+ /* All is well. We have received both responses (if
+ two responses were requested). */
return (resplen);
- } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- /* Something went wrong. We can stop trying. */
- goto err_out;
- }
+ } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
+ /* Something went wrong. We can stop trying. */
+ return close_and_return_error (statp, resplen2);
else {
/* poll should not have returned > 0 in this case. */
abort ();
++++++ resolv-dont-ignore-second-answer.patch ++++++
Don't ignore second answer from nameserver if the first one was empty (BZ #13651)
Index: glibc-2.19/resolv/res_query.c
===================================================================
--- glibc-2.19.orig/resolv/res_query.c
+++ glibc-2.19/resolv/res_query.c
@@ -382,7 +382,7 @@ __libc_res_nsearch(res_state statp,
answer, anslen, answerp,
answerp2, nanswerp2, resplen2,
answerp2_malloced);
- if (ret > 0 || trailing_dot)
+ if (ret > 0 || (ret == 0 && *resplen2 > 0) || trailing_dot)
return (ret);
saved_herrno = h_errno;
tried_as_is++;
@@ -422,7 +422,7 @@ __libc_res_nsearch(res_state statp,
answer, anslen, answerp,
answerp2, nanswerp2,
resplen2, answerp2_malloced);
- if (ret > 0)
+ if (ret > 0 || (ret == 0 && *resplen2 > 0))
return (ret);
if (answerp && *answerp != answer) {
@@ -491,7 +491,7 @@ __libc_res_nsearch(res_state statp,
answer, anslen, answerp,
answerp2, nanswerp2, resplen2,
answerp2_malloced);
- if (ret > 0)
+ if (ret > 0 || (ret == 0 && *resplen2 > 0))
return (ret);
}
++++++ resolv-mem-leak.patch ++++++
Fix resource leak in resolver (bug 19257)
* resolv/res_init.c (__res_iclose): Use statp->nscount instead of
statp->_u._ext.nscount as loop count.
---
resolv/res_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: glibc-2.22/resolv/res_init.c
===================================================================
--- glibc-2.22.orig/resolv/res_init.c
+++ glibc-2.22/resolv/res_init.c
@@ -593,7 +593,7 @@ __res_iclose(res_state statp, bool free_
statp->_vcsock = -1;
statp->_flags &= ~(RES_F_VC | RES_F_CONN);
}
- for (ns = 0; ns < statp->_u._ext.nscount; ns++)
+ for (ns = 0; ns < statp->nscount; ns++)
if (statp->_u._ext.nsaddrs[ns]) {
if (statp->_u._ext.nssocks[ns] != -1) {
close_not_cancel_no_status(statp->_u._ext.nssocks[ns]);
++++++ resolv-nameserver-handling.patch ++++++
From 6c07233f12e00b9cf66fb5d4a9b7ddb897590912 Mon Sep 17 00:00:00 2001
From: Andreas Schwab
Date: Thu, 19 Feb 2015 15:52:08 +0100
Subject: [PATCH] Simplify handling of nameserver configuration in resolver
[BZ #13028]
[BZ #17053]
* resolv/res_init.c (__res_vinit): Remove use of ext.nsmap.
* resolv/res_send.c (__libc_res_nsend): Likewise.
(get_nsaddr): New function.
(res_ourserver_p, send_vc, reopen): Use it instead of accessing
statp directly.
---
resolv/res_init.c | 47 +++++-----------
resolv/res_send.c | 164 +++++++++++++++++++++++-------------------------------
2 files changed, 84 insertions(+), 127 deletions(-)
Index: glibc-2.19/resolv/res_init.c
===================================================================
--- glibc-2.19.orig/resolv/res_init.c
+++ glibc-2.19/resolv/res_init.c
@@ -153,10 +153,8 @@ __res_vinit(res_state statp, int preinit
char *cp, **pp;
int n;
char buf[BUFSIZ];
- int nserv = 0; /* number of nameserver records read from file */
-#ifdef _LIBC
- int nservall = 0; /* number of NS records read, nserv IPv4 only */
-#endif
+ int nserv = 0; /* number of nameservers read from file */
+ int have_serv6 = 0;
int haveenv = 0;
int havesearch = 0;
#ifdef RESOLVSORT
@@ -184,15 +182,9 @@ __res_vinit(res_state statp, int preinit
statp->_flags = 0;
statp->qhook = NULL;
statp->rhook = NULL;
- statp->_u._ext.nsinit = 0;
statp->_u._ext.nscount = 0;
-#ifdef _LIBC
- statp->_u._ext.nscount6 = 0;
- for (n = 0; n < MAXNS; n++) {
- statp->_u._ext.nsaddrs[n] = NULL;
- statp->_u._ext.nsmap[n] = MAXNS;
- }
-#endif
+ for (n = 0; n < MAXNS; n++)
+ statp->_u._ext.nsaddrs[n] = NULL;
/* Allow user to override the local domain definition */
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
@@ -296,11 +288,7 @@ __res_vinit(res_state statp, int preinit
continue;
}
/* read nameservers to query */
-#ifdef _LIBC
- if (MATCH(buf, "nameserver") && nservall < MAXNS) {
-#else
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
-#endif
struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
@@ -308,13 +296,12 @@ __res_vinit(res_state statp, int preinit
cp++;
if ((*cp != '\0') && (*cp != '\n')
&& __inet_aton(cp, &a)) {
- statp->nsaddr_list[nservall].sin_addr = a;
- statp->nsaddr_list[nservall].sin_family = AF_INET;
- statp->nsaddr_list[nservall].sin_port =
+ statp->nsaddr_list[nserv].sin_addr = a;
+ statp->nsaddr_list[nserv].sin_family = AF_INET;
+ statp->nsaddr_list[nserv].sin_port =
htons(NAMESERVER_PORT);
nserv++;
#ifdef _LIBC
- nservall++;
} else {
struct in6_addr a6;
char *el;
@@ -356,10 +343,11 @@ __res_vinit(res_state statp, int preinit
}
}
- statp->_u._ext.nsaddrs[nservall] = sa6;
- statp->_u._ext.nssocks[nservall] = -1;
- statp->_u._ext.nsmap[nservall] = MAXNS + 1;
- nservall++;
+ statp->nsaddr_list[nserv].sin_family = 0;
+ statp->_u._ext.nsaddrs[nserv] = sa6;
+ statp->_u._ext.nssocks[nserv] = -1;
+ have_serv6 = 1;
+ nserv++;
}
}
#endif
@@ -414,10 +402,9 @@ __res_vinit(res_state statp, int preinit
continue;
}
}
- statp->nscount = nservall;
+ statp->nscount = nserv;
#ifdef _LIBC
- if (nservall - nserv > 0) {
- statp->_u._ext.nscount6 = nservall - nserv;
+ if (have_serv6) {
/* We try IPv6 servers again. */
statp->ipv6_unavail = false;
}
@@ -606,11 +593,7 @@ __res_iclose(res_state statp, bool free_
statp->_vcsock = -1;
statp->_flags &= ~(RES_F_VC | RES_F_CONN);
}
-#ifdef _LIBC
- for (ns = 0; ns < MAXNS; ns++)
-#else
for (ns = 0; ns < statp->_u._ext.nscount; ns++)
-#endif
if (statp->_u._ext.nsaddrs[ns]) {
if (statp->_u._ext.nssocks[ns] != -1) {
close_not_cancel_no_status(statp->_u._ext.nssocks[ns]);
@@ -621,7 +604,6 @@ __res_iclose(res_state statp, bool free_
statp->_u._ext.nsaddrs[ns] = NULL;
}
}
- statp->_u._ext.nsinit = 0;
}
libc_hidden_def (__res_iclose)
Index: glibc-2.19/resolv/res_send.c
===================================================================
--- glibc-2.19.orig/resolv/res_send.c
+++ glibc-2.19/resolv/res_send.c
@@ -183,6 +183,7 @@ evNowTime(struct timespec *res) {
/* Forward. */
+static struct sockaddr *get_nsaddr (res_state, int);
static int send_vc(res_state, const u_char *, int,
const u_char *, int,
u_char **, int *, int *, int, u_char **,
@@ -220,20 +221,21 @@ res_ourserver_p(const res_state statp, c
in_port_t port = in4p->sin_port;
in_addr_t addr = in4p->sin_addr.s_addr;
- for (ns = 0; ns < MAXNS; ns++) {
+ for (ns = 0; ns < statp->nscount; ns++) {
const struct sockaddr_in *srv =
- (struct sockaddr_in *)EXT(statp).nsaddrs[ns];
+ (struct sockaddr_in *) get_nsaddr (statp, ns);
- if ((srv != NULL) && (srv->sin_family == AF_INET) &&
+ if ((srv->sin_family == AF_INET) &&
(srv->sin_port == port) &&
(srv->sin_addr.s_addr == INADDR_ANY ||
srv->sin_addr.s_addr == addr))
return (1);
}
} else if (inp->sin6_family == AF_INET6) {
- for (ns = 0; ns < MAXNS; ns++) {
- const struct sockaddr_in6 *srv = EXT(statp).nsaddrs[ns];
- if ((srv != NULL) && (srv->sin6_family == AF_INET6) &&
+ for (ns = 0; ns < statp->nscount; ns++) {
+ const struct sockaddr_in6 *srv
+ = (struct sockaddr_in6 *) get_nsaddr (statp, ns);
+ if ((srv->sin6_family == AF_INET6) &&
(srv->sin6_port == inp->sin6_port) &&
!(memcmp(&srv->sin6_addr, &in6addr_any,
sizeof (struct in6_addr)) &&
@@ -383,74 +385,48 @@ __libc_res_nsend(res_state statp, const
* If the ns_addr_list in the resolver context has changed, then
* invalidate our cached copy and the associated timing data.
*/
- if (EXT(statp).nsinit) {
+ if (EXT(statp).nscount != 0) {
int needclose = 0;
if (EXT(statp).nscount != statp->nscount)
needclose++;
else
- for (ns = 0; ns < MAXNS; ns++) {
- unsigned int map = EXT(statp).nsmap[ns];
- if (map < MAXNS
+ for (ns = 0; ns < statp->nscount; ns++) {
+ if (statp->nsaddr_list[ns].sin_family != 0
&& !sock_eq((struct sockaddr_in6 *)
- &statp->nsaddr_list[map],
+ &statp->nsaddr_list[ns],
EXT(statp).nsaddrs[ns]))
{
needclose++;
break;
}
}
- if (needclose)
+ if (needclose) {
__res_iclose(statp, false);
+ EXT(statp).nscount = 0;
+ }
}
/*
* Maybe initialize our private copy of the ns_addr_list.
*/
- if (EXT(statp).nsinit == 0) {
- unsigned char map[MAXNS];
-
- memset (map, MAXNS, sizeof (map));
- for (n = 0; n < MAXNS; n++) {
- ns = EXT(statp).nsmap[n];
- if (ns < statp->nscount)
- map[ns] = n;
- else if (ns < MAXNS) {
- free(EXT(statp).nsaddrs[n]);
- EXT(statp).nsaddrs[n] = NULL;
- EXT(statp).nsmap[n] = MAXNS;
- }
- }
- n = statp->nscount;
- if (statp->nscount > EXT(statp).nscount)
- for (n = EXT(statp).nscount, ns = 0;
- n < statp->nscount; n++) {
- while (ns < MAXNS
- && EXT(statp).nsmap[ns] != MAXNS)
- ns++;
- if (ns == MAXNS)
- break;
- EXT(statp).nsmap[ns] = n;
- map[n] = ns++;
- }
- EXT(statp).nscount = n;
- for (ns = 0; ns < EXT(statp).nscount; ns++) {
- n = map[ns];
- if (EXT(statp).nsaddrs[n] == NULL)
- EXT(statp).nsaddrs[n] =
+ if (EXT(statp).nscount == 0) {
+ for (ns = 0; ns < statp->nscount; ns++) {
+ EXT(statp).nssocks[ns] = -1;
+ if (statp->nsaddr_list[ns].sin_family == 0)
+ continue;
+ if (EXT(statp).nsaddrs[ns] == NULL)
+ EXT(statp).nsaddrs[ns] =
malloc(sizeof (struct sockaddr_in6));
- if (EXT(statp).nsaddrs[n] != NULL) {
- memset (mempcpy(EXT(statp).nsaddrs[n],
+ if (EXT(statp).nsaddrs[ns] != NULL)
+ memset (mempcpy(EXT(statp).nsaddrs[ns],
&statp->nsaddr_list[ns],
sizeof (struct sockaddr_in)),
'\0',
sizeof (struct sockaddr_in6)
- sizeof (struct sockaddr_in));
- EXT(statp).nssocks[n] = -1;
- n++;
- }
}
- EXT(statp).nsinit = 1;
+ EXT(statp).nscount = statp->nscount;
}
/*
@@ -459,44 +435,37 @@ __libc_res_nsend(res_state statp, const
*/
if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) &&
(statp->options & RES_BLAST) == 0) {
- struct sockaddr_in6 *ina;
- unsigned int map;
-
- n = 0;
- while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS)
- n++;
- if (n < MAXNS) {
- ina = EXT(statp).nsaddrs[n];
- map = EXT(statp).nsmap[n];
- for (;;) {
- ns = n + 1;
- while (ns < MAXNS
- && EXT(statp).nsmap[ns] == MAXNS)
- ns++;
- if (ns == MAXNS)
- break;
- EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns];
- EXT(statp).nsmap[n] = EXT(statp).nsmap[ns];
- n = ns;
- }
- EXT(statp).nsaddrs[n] = ina;
- EXT(statp).nsmap[n] = map;
- }
+ struct sockaddr_in ina;
+ struct sockaddr_in6 *inp;
+ int lastns = statp->nscount - 1;
+ int fd;
+
+ inp = EXT(statp).nsaddrs[0];
+ ina = statp->nsaddr_list[0];
+ fd = EXT(statp).nssocks[0];
+ for (ns = 0; ns < lastns; ns++) {
+ EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
+ statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
+ EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
+ }
+ EXT(statp).nsaddrs[lastns] = inp;
+ statp->nsaddr_list[lastns] = ina;
+ EXT(statp).nssocks[lastns] = fd;
}
/*
* Send request, RETRY times, or until successful.
*/
for (try = 0; try < statp->retry; try++) {
- for (ns = 0; ns < MAXNS; ns++)
+ for (ns = 0; ns < statp->nscount; ns++)
{
#ifdef DEBUG
char tmpbuf[40];
#endif
- struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
+#if defined USE_HOOKS || defined DEBUG
+ struct sockaddr *nsap = get_nsaddr (statp, ns);
+#endif
- if (nsap == NULL)
- goto next_ns;
same_ns:
#ifdef USE_HOOKS
if (__builtin_expect (statp->qhook != NULL, 0)) {
@@ -535,9 +504,9 @@ __libc_res_nsend(res_state statp, const
Dprint(statp->options & RES_DEBUG,
(stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, inet_ntop(nsap->sin6_family,
- (nsap->sin6_family == AF_INET6
- ? &nsap->sin6_addr
+ ns + 1, inet_ntop(nsap->sa_family,
+ (nsap->sa_family == AF_INET6
+ ? &((struct sockaddr_in6 *) nsap)->sin6_addr
: &((struct sockaddr_in *) nsap)->sin_addr),
tmpbuf, sizeof (tmpbuf))));
@@ -653,6 +622,21 @@ libresolv_hidden_def (res_nsend)
return 0;
}
+static struct sockaddr *
+get_nsaddr (res_state statp, int n)
+{
+
+ if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
+ /* EXT(statp).nsaddrs[n] holds an address that is larger than
+ struct sockaddr, and user code did not update
+ statp->nsaddr_list[n]. */
+ return (struct sockaddr *) EXT(statp).nsaddrs[n];
+ else
+ /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
+ has the same content as EXT(statp).nsaddrs[n]. */
+ return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
+}
+
static int
send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -667,7 +651,7 @@ send_vc(res_state statp,
// XXX REMOVE
// int anssiz = *anssizp;
HEADER *anhp = (HEADER *) ans;
- struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
+ struct sockaddr *nsap = get_nsaddr (statp, ns);
int truncating, connreset, resplen, n;
struct iovec iov[4];
u_short len;
@@ -687,8 +671,8 @@ send_vc(res_state statp,
if (getpeername(statp->_vcsock,
(struct sockaddr *)&peer, &size) < 0 ||
- !sock_eq(&peer, nsap)) {
- __res_iclose(statp, false);
+ !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
+ __res_iclose(statp, false);
statp->_flags &= ~RES_F_VC;
}
}
@@ -697,20 +681,19 @@ send_vc(res_state statp,
if (statp->_vcsock >= 0)
__res_iclose(statp, false);
- statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0);
+ statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
if (statp->_vcsock < 0) {
*terrno = errno;
Perror(statp, stderr, "socket(vc)", errno);
return (-1);
}
__set_errno (0);
- if (connect(statp->_vcsock, (struct sockaddr *)nsap,
- nsap->sin6_family == AF_INET
+ if (connect(statp->_vcsock, nsap,
+ nsap->sa_family == AF_INET
? sizeof (struct sockaddr_in)
: sizeof (struct sockaddr_in6)) < 0) {
*terrno = errno;
- Aerror(statp, stderr, "connect/vc", errno,
- (struct sockaddr *) nsap);
+ Aerror(statp, stderr, "connect/vc", errno, nsap);
__res_iclose(statp, false);
return (0);
}
@@ -914,8 +897,7 @@ static int
reopen (res_state statp, int *terrno, int ns)
{
if (EXT(statp).nssocks[ns] == -1) {
- struct sockaddr *nsap
- = (struct sockaddr *) EXT(statp).nsaddrs[ns];
+ struct sockaddr *nsap = get_nsaddr (statp, ns);
socklen_t slen;
/* only try IPv6 if IPv6 NS and if not failed before */
++++++ s390-revert-abi-change.patch ++++++
++++ 2292 lines (skipped)
++++++ send-dg-buffer-overflow.patch ++++++
Index: glibc-2.19/resolv/nss_dns/dns-host.c
===================================================================
--- glibc-2.19.orig/resolv/nss_dns/dns-host.c
+++ glibc-2.19/resolv/nss_dns/dns-host.c
@@ -1061,7 +1061,10 @@ gaih_getanswer_slice (const querybuf *an
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)
{
@@ -1238,7 +1241,14 @@ gaih_getanswer_slice (const querybuf *an
/* 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;
}
@@ -1252,11 +1262,101 @@ gaih_getanswer (const querybuf *answer1,
enum nss_status status = NSS_STATUS_NOTFOUND;
+ /* Combining the NSS status of two distinct queries requires some
+ compromise and attention to symmetry (A or AAAA queries can be
+ returned in any order). What follows is a breakdown of how this
+ code is expected to work and why. We discuss only SUCCESS,
+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
+ that apply (though RETURN and MERGE exist). We make a distinction
+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
+ A recoverable TRYAGAIN is almost always due to buffer size issues
+ and returns ERANGE in errno and the caller is expected to retry
+ with a larger buffer.
+
+ Lastly, you may be tempted to make significant changes to the
+ conditions in this code to bring about symmetry between responses.
+ Please don't change anything without due consideration for
+ expected application behaviour. Some of the synthesized responses
+ aren't very well thought out and sometimes appear to imply that
+ IPv4 responses are always answer 1, and IPv6 responses are always
+ answer 2, but that's not true (see the implemetnation of send_dg
+ and send_vc to see response can arrive in any order, particlarly
+ for UDP). However, we expect it holds roughly enough of the time
+ that this code works, but certainly needs to be fixed to make this
+ a more robust implementation.
+
+ ----------------------------------------------
+ | Answer 1 Status / | Synthesized | Reason |
+ | Answer 2 Status | Status | |
+ |--------------------------------------------|
+ | SUCCESS/SUCCESS | SUCCESS | [1] |
+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] |
+ | SUCCESS/NOTFOUND | SUCCESS | [1] |
+ | SUCCESS/UNAVAIL | SUCCESS | [1] |
+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] |
+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
+ | NOTFOUND/SUCCESS | SUCCESS | [3] |
+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] |
+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] |
+ | UNAVAIL/SUCCESS | UNAVAIL | [4] |
+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] |
+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] |
+ ----------------------------------------------
+
+ [1] If the first response is a success we return success.
+ This ignores the state of the second answer and in fact
+ incorrectly sets errno and h_errno to that of the second
+ answer. However because the response is a success we ignore
+ *errnop and *h_errnop (though that means you touched errno on
+ success). We are being conservative here and returning the
+ likely IPv4 response in the first answer as a success.
+
+ [2] If the first response is a recoverable TRYAGAIN we return
+ that instead of looking at the second response. The
+ expectation here is that we have failed to get an IPv4 response
+ and should retry both queries.
+
+ [3] If the first response was not a SUCCESS and the second
+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
+ result from the second response, otherwise the first responses
+ status is used. Again we have some odd side-effects when the
+ second response is NOTFOUND because we overwrite *errnop and
+ *h_errnop that means that a first answer of NOTFOUND might see
+ its *errnop and *h_errnop values altered. Whether it matters
+ in practice that a first response NOTFOUND has the wrong
+ *errnop and *h_errnop is undecided.
+
+ [4] If the first response is UNAVAIL we return that instead of
+ looking at the second response. The expectation here is that
+ it will have failed similarly e.g. configuration failure.
+
+ [5] Testing this code is complicated by the fact that truncated
+ second response buffers might be returned as SUCCESS if the
+ first answer is a SUCCESS. To fix this we add symmetry to
+ TRYAGAIN with the second response. If the second response
+ is a recoverable error we now return TRYAGIN even if the first
+ response was SUCCESS. */
+
if (anslen1 > 0)
status = gaih_getanswer_slice(answer1, anslen1, qname,
&pat, &buffer, &buflen,
errnop, h_errnop, ttlp,
&first);
+
if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|| (status == NSS_STATUS_TRYAGAIN
/* We want to look at the second answer in case of an
@@ -1272,8 +1372,15 @@ gaih_getanswer (const querybuf *answer1,
&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;
Index: glibc-2.19/resolv/res_query.c
===================================================================
--- glibc-2.19.orig/resolv/res_query.c
+++ glibc-2.19/resolv/res_query.c
@@ -394,6 +394,7 @@ __libc_res_nsearch(res_state statp,
{
free (*answerp2);
*answerp2 = NULL;
+ *nanswerp2 = 0;
*answerp2_malloced = 0;
}
}
@@ -433,6 +434,7 @@ __libc_res_nsearch(res_state statp,
{
free (*answerp2);
*answerp2 = NULL;
+ *nanswerp2 = 0;
*answerp2_malloced = 0;
}
@@ -506,6 +508,7 @@ __libc_res_nsearch(res_state statp,
{
free (*answerp2);
*answerp2 = NULL;
+ *nanswerp2 = 0;
*answerp2_malloced = 0;
}
if (saved_herrno != -1)
Index: glibc-2.19/resolv/res_send.c
===================================================================
--- glibc-2.19.orig/resolv/res_send.c
+++ glibc-2.19/resolv/res_send.c
@@ -1,3 +1,20 @@
+/* Copyright (C) 2016 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/. */
+
/*
* Copyright (c) 1985, 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -362,6 +379,8 @@ __libc_res_nsend(res_state statp, const
#ifdef USE_HOOKS
if (__builtin_expect (statp->qhook || statp->rhook, 0)) {
if (anssiz < MAXPACKET && ansp) {
+ /* Always allocate MAXPACKET, callers expect
+ this specific size. */
u_char *buf = malloc (MAXPACKET);
if (buf == NULL)
return (-1);
@@ -637,6 +656,77 @@ get_nsaddr (res_state statp, int n)
return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
}
+/* The send_vc function is responsible for sending a DNS query over TCP
+ to the nameserver numbered NS from the res_state STATP i.e.
+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
+ IPv6 queries at the same serially on the same socket.
+
+ Please note that for TCP there is no way to disable sending both
+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
+ and sends the queries serially and waits for the result after each
+ sent query. This implemetnation should be corrected to honour these
+ options.
+
+ Please also note that for TCP we send both queries over the same
+ socket one after another. This technically violates best practice
+ since the server is allowed to read the first query, respond, and
+ then close the socket (to service another client). If the server
+ does this, then the remaining second query in the socket data buffer
+ will cause the server to send the client an RST which will arrive
+ asynchronously and the client's OS will likely tear down the socket
+ receive buffer resulting in a potentially short read and lost
+ response data. This will force the client to retry the query again,
+ and this process may repeat until all servers and connection resets
+ are exhausted and then the query will fail. It's not known if this
+ happens with any frequency in real DNS server implementations. This
+ implementation should be corrected to use two sockets by default for
+ parallel queries.
+
+ The query stored in BUF of BUFLEN length is sent first followed by
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
+ serially on the same socket.
+
+ Answers to the query are stored firstly in *ANSP up to a max of
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
+ then malloc is used to allocate a new response buffer and ANSCP and
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
+ are needed but ANSCP is NULL, then as much of the response as
+ possible is read into the buffer, but the results will be truncated.
+ When truncation happens because of a small answer buffer the DNS
+ packets header feild TC will bet set to 1, indicating a truncated
+ message and the rest of the socket data will be read and discarded.
+
+ Answers to the query are stored secondly in *ANSP2 up to a max of
+ *ANSSIZP2 bytes, with the actual response length stored in
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
+ is non-NULL (required for a second query) then malloc is used to
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
+ size and *ANSP2_MALLOCED is set to 1.
+
+ The ANSP2_MALLOCED argument will eventually be removed as the
+ change in buffer pointer can be used to detect the buffer has
+ changed and that the caller should use free on the new buffer.
+
+ Note that the answers may arrive in any order from the server and
+ therefore the first and second answer buffers may not correspond to
+ the first and second queries.
+
+ It is not supported to call this function with a non-NULL ANSP2
+ but a NULL ANSCP. Put another way, you can call send_vc with a
+ single unmodifiable buffer or two modifiable buffers, but no other
+ combination is supported.
+
+ It is the caller's responsibility to free the malloc allocated
+ buffers by detecting that the pointers have changed from their
+ original values i.e. *ANSCP or *ANSP2 has changed.
+
+ If errors are encountered then *TERRNO is set to an appropriate
+ errno value and a zero result is returned for a recoverable error,
+ and a less-than zero result is returned for a non-recoverable error.
+
+ If no errors are encountered then *TERRNO is left unmodified and
+ a the length of the first response in bytes is returned. */
static int
send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -646,11 +736,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, resplen, n;
struct iovec iov[4];
@@ -725,6 +811,8 @@ send_vc(res_state statp,
* Receive length & response
*/
int recvresp1 = 0;
+ /* Skip the second response if there is no second query.
+ To do that we mark the second response as received. */
int recvresp2 = buf2 == NULL;
uint16_t rlen16;
read_len:
@@ -761,33 +849,14 @@ send_vc(res_state statp,
u_char **thisansp;
int *thisresplenp;
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
+ /* We have not received any responses
+ yet or we only have one response to
+ receive. */
thisanssizp = anssizp;
thisansp = anscp ?: ansp;
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. */
-#ifdef _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;
@@ -795,10 +864,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 (__builtin_expect (anscp != NULL, 1)) {
+ /* Is the answer buffer too small? */
+ if (*thisanssizp < rlen) {
+ /* If the current buffer is non-NULL and it's not
+ pointing at 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;
@@ -810,6 +883,9 @@ send_vc(res_state statp,
if (thisansp == ansp2)
*ansp2_malloced = 1;
anhp = (HEADER *) newp;
+ /* A uint16_t can't be larger than MAXPACKET
+ thus it's safe to allocate MAXPACKET but
+ read RLEN bytes instead. */
len = rlen;
} else {
Dprint(statp->options & RES_DEBUG,
@@ -972,6 +1048,66 @@ reopen (res_state statp, int *terrno, in
return 1;
}
+/* The send_dg function is responsible for sending a DNS query over UDP
+ to the nameserver numbered NS from the res_state STATP i.e.
+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
+ along with the ability to send the query in parallel for both stacks
+ (default) or serially (RES_SINGLKUP). It also supports serial lookup
+ with a close and reopen of the socket used to talk to the server
+ (RES_SNGLKUPREOP) to work around broken name servers.
+
+ The query stored in BUF of BUFLEN length is sent first followed by
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
+
+ Answers to the query are stored firstly in *ANSP up to a max of
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
+ then malloc is used to allocate a new response buffer and ANSCP and
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
+ are needed but ANSCP is NULL, then as much of the response as
+ possible is read into the buffer, but the results will be truncated.
+ When truncation happens because of a small answer buffer the DNS
+ packets header feild TC will bet set to 1, indicating a truncated
+ message, while the rest of the UDP packet is discarded.
+
+ Answers to the query are stored secondly in *ANSP2 up to a max of
+ *ANSSIZP2 bytes, with the actual response length stored in
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
+ is non-NULL (required for a second query) then malloc is used to
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
+ size and *ANSP2_MALLOCED is set to 1.
+
+ The ANSP2_MALLOCED argument will eventually be removed as the
+ change in buffer pointer can be used to detect the buffer has
+ changed and that the caller should use free on the new buffer.
+
+ Note that the answers may arrive in any order from the server and
+ therefore the first and second answer buffers may not correspond to
+ the first and second queries.
+
+ It is not supported to call this function with a non-NULL ANSP2
+ but a NULL ANSCP. Put another way, you can call send_vc with a
+ single unmodifiable buffer or two modifiable buffers, but no other
+ combination is supported.
+
+ It is the caller's responsibility to free the malloc allocated
+ buffers by detecting that the pointers have changed from their
+ original values i.e. *ANSCP or *ANSP2 has changed.
+
+ If an answer is truncated because of UDP datagram DNS limits then
+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
+ if any progress was made reading a response from the nameserver and
+ is used by the caller to distinguish between ECONNREFUSED and
+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
+
+ If errors are encountered then *TERRNO is set to an appropriate
+ errno value and a zero result is returned for a recoverable error,
+ and a less-than zero result is returned for a non-recoverable error.
+
+ If no errors are encountered then *TERRNO is left unmodified and
+ a the length of the first response in bytes is returned. */
static int
send_dg(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -981,8 +1117,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;
@@ -1015,6 +1149,8 @@ send_dg(res_state statp,
int need_recompute = 0;
int nwritten = 0;
int recvresp1 = 0;
+ /* Skip the second response if there is no second query.
+ To do that we mark the second response as received. */
int recvresp2 = buf2 == NULL;
pfd[0].fd = EXT(statp).nssocks[ns];
pfd[0].events = POLLOUT;
@@ -1178,55 +1314,56 @@ send_dg(res_state statp,
int *thisresplenp;
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
+ /* We have not received any responses
+ yet or we only have one response to
+ receive. */
thisanssizp = anssizp;
thisansp = anscp ?: ansp;
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. */
-#ifdef _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 non-NULL and it's not
+ pointing at 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 (__builtin_expect (*thisanssizp < *thisresplenp, 0)) {
+ 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);
++++++ setlocale-directory-traversal.patch ++++++
++++ 648 lines (skipped)
++++++ sin-sign.patch ++++++
Index: glibc-2.19/sysdeps/ieee754/dbl-64/s_sin.c
===================================================================
--- glibc-2.19.orig/sysdeps/ieee754/dbl-64/s_sin.c
+++ glibc-2.19/sysdeps/ieee754/dbl-64/s_sin.c
@@ -447,19 +447,21 @@ __sin (double x)
}
else
{
+ double t;
if (a > 0)
{
m = 1;
+ t = a;
db = da;
}
else
{
m = 0;
- a = -a;
+ t = -a;
db = -da;
}
- u.x = big + a;
- y = a - (u.x - big);
+ u.x = big + t;
+ y = t - (u.x - big);
res = do_sin (u, y, db, &cor);
cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
retval = ((res == res + cor) ? ((m) ? res : -res)
@@ -671,19 +673,21 @@ __cos (double x)
}
else
{
+ double t;
if (a > 0)
{
m = 1;
+ t = a;
db = da;
}
else
{
m = 0;
- a = -a;
+ t = -a;
db = -da;
}
- u.x = big + a;
- y = a - (u.x - big);
+ u.x = big + t;
+ y = t - (u.x - big);
res = do_sin (u, y, db, &cor);
cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
retval = ((res == res + cor) ? ((m) ? res : -res)
++++++ strftime-range-check.patch ++++++
2015-09-26 Paul Pluzhnikov
[BZ #18985]
* time/strftime_l.c (a_wkday, f_wkday, a_month, f_month): Range check.
(__strftime_internal): Likewise.
* time/tst-strftime.c (do_bz18985): New test.
(do_test): Call it.
Index: glibc-2.19/time/strftime_l.c
===================================================================
--- glibc-2.19.orig/time/strftime_l.c
+++ glibc-2.19/time/strftime_l.c
@@ -509,13 +509,17 @@ __strftime_internal (s, maxsize, format,
only a few elements. Dereference the pointers only if the format
requires this. Then it is ok to fail if the pointers are invalid. */
# define a_wkday \
- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
+ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
+ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
# define f_wkday \
- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
+ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
+ ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
# define a_month \
- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
+ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
+ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
# define f_month \
- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
+ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
+ ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
# define ampm \
((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
? NLW(PM_STR) : NLW(AM_STR)))
@@ -525,8 +529,10 @@ __strftime_internal (s, maxsize, format,
# define ap_len STRLEN (ampm)
#else
# if !HAVE_STRFTIME
-# define f_wkday (weekday_name[tp->tm_wday])
-# define f_month (month_name[tp->tm_mon])
+# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \
+ ? "?" : weekday_name[tp->tm_wday])
+# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \
+ ? "?" : month_name[tp->tm_mon])
# define a_wkday f_wkday
# define a_month f_month
# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
@@ -1320,7 +1326,7 @@ __strftime_internal (s, maxsize, format,
*tzset_called = true;
}
# endif
- zone = tzname[tp->tm_isdst];
+ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
}
#endif
if (! zone)
Index: glibc-2.19/time/tst-strftime.c
===================================================================
--- glibc-2.19.orig/time/tst-strftime.c
+++ glibc-2.19/time/tst-strftime.c
@@ -4,6 +4,56 @@
#include
+static int
+do_bz18985 (void)
+{
+ char buf[1000];
+ struct tm ttm;
+ int rc, ret = 0;
+
+ memset (&ttm, 1, sizeof (ttm));
+ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */
+ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm);
+
+ if (rc == 66)
+ {
+ const char expected[]
+ = "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?";
+ if (0 != strcmp (buf, expected))
+ {
+ printf ("expected:\n %s\ngot:\n %s\n", expected, buf);
+ ret += 1;
+ }
+ }
+ else
+ {
+ printf ("expected 66, got %d\n", rc);
+ ret += 1;
+ }
+
+ /* Check negative values as well. */
+ memset (&ttm, 0xFF, sizeof (ttm));
+ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */
+ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm);
+
+ if (rc == 30)
+ {
+ const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 ";
+ if (0 != strcmp (buf, expected))
+ {
+ printf ("expected:\n %s\ngot:\n %s\n", expected, buf);
+ ret += 1;
+ }
+ }
+ else
+ {
+ printf ("expected 30, got %d\n", rc);
+ ret += 1;
+ }
+
+ return ret;
+}
+
static struct
{
const char *fmt;
@@ -104,7 +154,7 @@ do_test (void)
}
}
- return result;
+ return result + do_bz18985 ();
}
#define TEST_FUNCTION do_test ()
++++++ strxfrm-l-memory-handling.patch ++++++
++++ 676 lines (skipped)
++++++ tls-dtor-list-pointer-mangling.patch ++++++
2016-07-11 Florian Weimer
[BZ #19018]
* stdlib/cxa_thread_atexit_impl.c (__cxa_thread_atexit_impl):
Mangle function pointer before storing it.
(__call_tls_dtors): Demangle function pointer before calling it.
Index: glibc-2.19/stdlib/cxa_thread_atexit_impl.c
===================================================================
--- glibc-2.19.orig/stdlib/cxa_thread_atexit_impl.c
+++ glibc-2.19/stdlib/cxa_thread_atexit_impl.c
@@ -42,6 +42,10 @@ static __thread struct link_map *lm_cach
int
__cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
{
+#ifdef PTR_MANGLE
+ PTR_MANGLE (func);
+#endif
+
/* Prepend. */
struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
new->func = func;
@@ -83,9 +87,13 @@ __call_tls_dtors (void)
while (tls_dtor_list)
{
struct dtor_list *cur = tls_dtor_list;
- tls_dtor_list = tls_dtor_list->next;
+ dtor_func func = cur->func;
+#ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (func);
+#endif
- cur->func (cur->obj);
+ tls_dtor_list = tls_dtor_list->next;
+ func (cur->obj);
__rtld_lock_lock_recursive (GL(dl_load_lock));
++++++ wordexp-wrde-nocmd.patch ++++++
2014-11-19 Carlos O'Donell
Florian Weimer
Joseph Myers
Adam Conrad
Andreas Schwab
Brooks
[BZ #17625]
* 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 (exec_comm): Return WRDE_CMDSUB if WRDE_NOCMD flag
is set.
(parse_dollars): Remove check for WRDE_NOCMD.
(parse_dquote): Likewise.
Index: glibc-2.19/posix/wordexp-test.c
===================================================================
--- glibc-2.19.orig/posix/wordexp-test.c
+++ glibc-2.19/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;
Index: glibc-2.19/posix/wordexp.c
===================================================================
--- glibc-2.19.orig/posix/wordexp.c
+++ glibc-2.19/posix/wordexp.c
@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size
pid_t pid;
int noexec = 0;
+ /* Do nothing if command substitution should not succeed. */
+ if (flags & WRDE_NOCMD)
+ return WRDE_CMDSUB;
+
/* Don't fork() unless necessary */
if (!comm || !*comm)
return 0;
@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word
}
}
- if (flags & WRDE_NOCMD)
- return WRDE_CMDSUB;
-
(*offset) += 2;
return parse_comm (word, word_length, max_length, words, offset, flags,
quoted? NULL : pwordexp, ifs, ifs_white);
@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_
break;
case '`':
- if (flags & WRDE_NOCMD)
- return WRDE_CMDSUB;
-
++(*offset);
error = parse_backtick (word, word_length, max_length, words,
offset, flags, NULL, NULL, NULL);
@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *p
break;
case '`':
- if (flags & WRDE_NOCMD)
- {
- error = WRDE_CMDSUB;
- goto do_error;
- }
-
++words_offset;
error = parse_backtick (&word, &word_length, &max_length, words,
&words_offset, flags, pwordexp, ifs,
++++++ wscanf-buffer-overflow.patch ++++++
2015-02-05 Paul Pluzhnikov
[BZ #16618]
* stdio-common/tst-sscanf.c (main): Test for buffer overflow.
* stdio-common/vfscanf.c (_IO_vfscanf_internal): Compute needed
size in bytes. Store needed elements in wpmax. Use needed size
in bytes for extend_alloca.
Index: glibc-2.19/stdio-common/tst-sscanf.c
===================================================================
--- glibc-2.19.orig/stdio-common/tst-sscanf.c
+++ glibc-2.19/stdio-common/tst-sscanf.c
@@ -232,5 +232,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;
}
Index: glibc-2.19/stdio-common/vfscanf.c
===================================================================
--- glibc-2.19.orig/stdio-common/vfscanf.c
+++ glibc-2.19/stdio-common/vfscanf.c
@@ -272,9 +272,10 @@ _IO_vfscanf_internal (_IO_FILE *s, const
if (__builtin_expect (wpsize == wpmax, 0)) \
{ \
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 = __builtin_expect (wpmax <= SIZE_MAX / sizeof (CHAR_T) / 2, 1); \
+ 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
} \
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); \