Compare commits

...
Author SHA1 Message Date
Marcin Kościelnicki b039fd85db rtld: Check __libc_enable_secure before honoring LD_PREFER_MAP_32BIT_EXEC (CVE-2019-19126) [BZ #25204]
The problem was introduced in glibc 2.23, in commit
b9eb92ab05
("Add Prefer_MAP_32BIT_EXEC to map executable pages with MAP_32BIT").

(cherry picked from commit d5dfad4326)
2019-11-22 14:09:58 +01:00
H.J. Lu 8337b12d0b x86-64: Properly align La_x86_64_retval to VEC_SIZE [BZ #22715]
_dl_runtime_profile calls _dl_call_pltexit, passing a pointer to
La_x86_64_retval which is allocated on stack.  The lrv_vector0
field in La_x86_64_retval must be aligned to size of vector register.
When allocating stack space for La_x86_64_retval, we need to make sure
that the address of La_x86_64_retval + RV_VECTOR0_OFFSET is aligned to
VEC_SIZE.  This patch checks the alignment of the lrv_vector0 field
and pads the stack space if needed.

Tested with x32 and x86-64 on SSE4, AVX and AVX512 machines.  It fixed

FAIL: elf/tst-audit10
FAIL: elf/tst-audit4
FAIL: elf/tst-audit5
FAIL: elf/tst-audit6
FAIL: elf/tst-audit7

on x32 AVX512 machine.

(cherry picked from commit 207a72e298)

	[BZ #22715]
	* sysdeps/x86_64/dl-trampoline.h (_dl_runtime_profile): Properly
	align La_x86_64_retval to VEC_SIZE.
2018-01-19 09:54:03 -08:00
Florian Weimer fbd72f1490 x86: Fix mis-merge of XSAVE ld.so trampoline selection [BZ #22641]
The change is best viewed with “diff -w”:

@@ -226,6 +226,7 @@ init_cpu_features (struct cpu_features *cpu_features)
 	  /* Determine if FMA4 is usable.  */
 	  if (HAS_CPU_FEATURE (FMA4))
 	    cpu_features->feature[index_FMA4_Usable] |= bit_FMA4_Usable;
+	}

       /* For _dl_runtime_resolve, set xsave_state_size to xsave area
 	 size + integer register save size and align it to 64 bytes.  */
@@ -292,7 +293,6 @@ init_cpu_features (struct cpu_features *cpu_features)
 	    }
 	}
     }
-    }

 #if !HAS_CPUID
 no_cpuid:

Without this change, XSAVE support will never be selected unless the CPU
also supports AVX, which is not what we want.  For example, if AVX is
disabled, but MPX is supported, the BND registers are not preserved if
we use FXSAVE instead of XSAVE.

This fixes commit 26d289bb92 (x86-64:
Use fxsave/xsave/xsavec in _dl_runtime_resolve).
2018-01-11 16:54:40 +01:00
H.J. Lu 26d289bb92 x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve [BZ #21265]
In _dl_runtime_resolve, use fxsave/xsave/xsavec to preserve all vector,
mask and bound registers.  It simplifies _dl_runtime_resolve and supports
different calling conventions.  ld.so code size is reduced by more than
1 KB.  However, use fxsave/xsave/xsavec takes a little bit more cycles
than saving and restoring vector and bound registers individually.

Latency for _dl_runtime_resolve to lookup the function, foo, from one
shared library plus libc.so:

                             Before    After     Change

Westmere (SSE)/fxsave         345      866       151%
IvyBridge (AVX)/xsave         420      643       53%
Haswell (AVX)/xsave           713      1252      75%
Skylake (AVX+MPX)/xsavec      559      719       28%
Skylake (AVX512+MPX)/xsavec   145      272       87%
Ryzen (AVX)/xsavec            280      553       97%

This is the worst case where portion of time spent for saving and
restoring registers is bigger than majority of cases.  With smaller
_dl_runtime_resolve code size, overall performance impact is negligible.

On IvyBridge, differences in build and test time of binutils with lazy
binding GCC and binutils are noises.  On Westmere, differences in
bootstrap and "makc check" time of GCC 7 with lazy binding GCC and
binutils are also noises.

	[BZ #21265]
	* sysdeps/x86/cpu-features-offsets.sym (XSAVE_STATE_SIZE_OFFSET):
	New.
	* sysdeps/x86/cpu-features.c: Include <libc-internal.h>.
	(init_cpu_features): Set xsave_state_size and bit_XSAVEC_Usable
	if needed.
	* sysdeps/x86/cpu-features.h (bit_XSAVEC_Usable): New.
	(STATE_SAVE_OFFSET): Likewise.
	(STATE_SAVE_MASK): Likewise.
	[__ASSEMBLER__]: Include <cpu-features-offsets.h>.
	(cpu_features): Add xsave_state_size.
	(index_XSAVEC_Usable): New.
	* sysdeps/x86_64/dl-machine.h (elf_machine_runtime_setup):
	Replace _dl_runtime_resolve_sse, _dl_runtime_resolve_avx and
	_dl_runtime_resolve_avx512 with _dl_runtime_resolve_fxsave,
	_dl_runtime_resolve_xsave and _dl_runtime_resolve_xsavec.
	* sysdeps/x86_64/dl-trampoline.S: Include <cpu-features.h>.
	(DL_RUNTIME_UNALIGNED_VEC_SIZE): Removed.
	(DL_RUNTIME_RESOLVE_REALIGN_STACK): Check STATE_SAVE_ALIGNMENT
	instead of VEC_SIZE.
	(REGISTER_SAVE_BND0): Removed.
	(REGISTER_SAVE_BND1): Likewise.
	(REGISTER_SAVE_BND3): Likewise.
	(REGISTER_SAVE_RAX): Always defined to 0.
	(VMOV): Removed.
	(_dl_runtime_resolve_avx512): Likewise.
	(_dl_runtime_resolve_avx): Likewise.
	(_dl_runtime_resolve_sse): Likewise.
	(USE_FXSAVE): New.
	(_dl_runtime_resolve_fxsave): Likewise.
	(USE_XSAVE): Likewise.
	(_dl_runtime_resolve_xsave): Likewise.
	(USE_XSAVEC): Likewise.
	(_dl_runtime_resolve_xsavec): Likewise.
	* sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve_avx512):
	Removed.
	(_dl_runtime_resolve_avx): Likewise.
	(_dl_runtime_resolve_sse): Likewise.
	(_dl_runtime_resolve_fxsave): New.
	(_dl_runtime_resolve_xsave): Likewise.
	(_dl_runtime_resolve_xsavec): Likewise.
	(_dl_runtime_profile): Defined only if _dl_runtime_profile is
	defined.

(cherry picked from commit b52b0d793d)
2017-10-22 08:47:20 -07:00
H.J. Lu 9d521f59de Update NEWS for [BZ #21666] fix 2017-10-20 18:00:11 -07:00
H.J. Lu 93710f5174 x86-64: Verify that _dl_runtime_resolve preserves vector registers
On x86-64, _dl_runtime_resolve must preserve the first 8 vector
registers.  Add 3 _dl_runtime_resolve tests to verify that SSE,
AVX and AVX512 registers are preserved.

	* sysdeps/x86_64/Makefile (tests): Add tst-sse, tst-avx and
	tst-avx512.
	(test-extras): Add tst-avx-aux and tst-avx512-aux.
	(extra-test-objs): Add tst-avx-aux.o and tst-avx512-aux.o.
	(modules-names): Add tst-ssemod, tst-avxmod and tst-avx512mod.
	($(objpfx)tst-sse): New rule.
	($(objpfx)tst-avx): Likewise.
	($(objpfx)tst-avx512): Likewise.
	(CFLAGS-tst-avx-aux.c): New.
	(CFLAGS-tst-avxmod.c): Likewise.
	(CFLAGS-tst-avx512-aux.c): Likewise.
	(CFLAGS-tst-avx512mod.c): Likewise.
	* sysdeps/x86_64/tst-avx-aux.c: New file.
	* sysdeps/x86_64/tst-avx.c: Likewise.
	* sysdeps/x86_64/tst-avx512-aux.c: Likewise.
	* sysdeps/x86_64/tst-avx512.c: Likewise.
	* sysdeps/x86_64/tst-avx512mod.c: Likewise.
	* sysdeps/x86_64/tst-avxmod.c: Likewise.
	* sysdeps/x86_64/tst-sse.c: Likewise.
	* sysdeps/x86_64/tst-ssemod.c: Likewise.

(cherry picked from commit 3403a17fea)
2017-10-19 08:56:14 -07:00
H.J. Lu bc566388d6 Avoid .symver on common symbols [BZ #21666]
The .symver directive on common symbol just creates a new common symbol,
not an alias and the newer assembler with the bug fix for

https://sourceware.org/bugzilla/show_bug.cgi?id=21661

will issue an error.  Before the fix, we got

$ readelf -sW libc.so | grep "loc[12s]"
  5109: 00000000003a0608     8 OBJECT  LOCAL  DEFAULT   36 loc1
  5188: 00000000003a0610     8 OBJECT  LOCAL  DEFAULT   36 loc2
  5455: 00000000003a0618     8 OBJECT  LOCAL  DEFAULT   36 locs
  6575: 00000000003a05f0     8 OBJECT  GLOBAL DEFAULT   36 locs@GLIBC_2.2.5
  7156: 00000000003a05f8     8 OBJECT  GLOBAL DEFAULT   36 loc1@GLIBC_2.2.5
  7312: 00000000003a0600     8 OBJECT  GLOBAL DEFAULT   36 loc2@GLIBC_2.2.5

in libc.so.  The versioned loc1, loc2 and locs have the wrong addresses.
After the fix, we got

$ readelf -sW libc.so | grep "loc[12s]"
  6570: 000000000039e3b8     8 OBJECT  GLOBAL DEFAULT   34 locs@GLIBC_2.2.5
  7151: 000000000039e3c8     8 OBJECT  GLOBAL DEFAULT   34 loc1@GLIBC_2.2.5
  7307: 000000000039e3c0     8 OBJECT  GLOBAL DEFAULT   34 loc2@GLIBC_2.2.5

	[BZ #21666]
	* misc/regexp.c (loc1): Add __attribute__ ((nocommon));
	(loc2): Likewise.
	(locs): Likewise.

(cherry picked from commit 388b4f1a02)
2017-10-19 08:43:16 -07:00
H.J. Lu 4401ec26af X86-64: Correct CFA in _dl_runtime_resolve
When stack is re-aligned in _dl_runtime_resolve, there is no need to
adjust CFA when allocating register save area on stack.

	* sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve): Don't
	adjust CFA when allocating register save area on re-aligned
	stack.

(cherry picked from commit 0ac8ee53e8)
2017-10-19 08:40:49 -07:00
Florian Weimer d990d79610 i686: Add missing IS_IN (libc) guards to vectorized strcspn
Since commit d957c4d3fa (i386: Compile
rtld-*.os with -mno-sse -mno-mmx -mfpmath=387), vector intrinsics can
no longer be used in ld.so, even if the compiled code never makes it
into the final ld.so link.  This commit adds the missing IS_IN (libc)
guard to the SSE 4.2 strcspn implementation, so that it can be used from
ld.so in the future.

(cherry picked from commit 69052a3a95)
2017-06-20 06:28:29 +02:00
Siddhesh Poyarekar 901d3d5aaa Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug #21209)
The LD_HWCAP_MASK environment variable may alter the selection of
function variants for some architectures.  For AT_SECURE process it
means that if an outdated routine has a bug that would otherwise not
affect newer platforms by default, LD_HWCAP_MASK will allow that bug
to be exploited.

To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid
binaries.

	[BZ #21209]
	* elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for
	AT_SECURE processes.
	* sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK.

(cherry picked from commit 1c1243b6fc)
2017-06-20 06:07:34 +02:00
Florian Weimer 03b0b2b471 ld.so: Reject overly long LD_AUDIT path elements
Also only process the last LD_AUDIT entry.

(cherry picked from commit 81b82fb966)
2017-06-19 22:48:21 +02:00
Florian Weimer 8cc357efd3 ld.so: Reject overly long LD_PRELOAD path elements
(cherry picked from commit 6d0ba62289)
2017-06-19 22:48:20 +02:00
Florian Weimer efa26d9c13 CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1 programs [BZ #21624]
LD_LIBRARY_PATH can only be used to reorder system search paths, which
is not useful functionality.

This makes an exploitable unbounded alloca in _dl_init_paths unreachable
for AT_SECURE=1 programs.

(cherry picked from commit f6110a8fee)
2017-06-19 18:34:53 +02:00
Santhosh Thottingal 9f172a30ac Correct collation rules for Malayalam.
[BZ #19922]
	* locales/iso14651_t1_common: Add collation rules for U+07DA to U+07DF.

	[BZ #19919]
	* locales/iso14651_t1_common: Correct collation of U+0D36 and U+0D37.
2017-06-11 10:29:58 -04:00
Slava Barinov 0be74c5c7c fts: Fix symbol redirect for fts_set [BZ #21289]
In a 32-bit environment with _FILE_OFFSET_BITS=64, the __REDIRECT macro
combined with __THROW generates an invalid C++ declaration.

(cherry picked from commit ce39613205)
2017-03-31 10:26:07 +02:00
Siddhesh Poyarekar 800f9aa06b Drop GLIBC_TUNABLES in setxid processes
Drop the GLIBC_TUNABLES environment variable from the environment of
setxid processes to avoid passing it on to non-setxid children.  This
prevents potentially insecure tunables in the GLIBC_TUNABLES envvar
from crossing over into a child that may use a libc that has tunables
support.

	* sysdeps/generic/unsecvars.h: Add GLIBC_TUNABLES.
2017-02-02 16:18:15 +05:30
Tulio Magno Quites Machado Filho da9f68f2b9 powerpc: Fix write-after-destroy in lock elision [BZ #20822]
The update of *adapt_count after the release of the lock causes a race
condition when thread A unlocks, thread B continues and destroys the
mutex, and thread A writes to *adapt_count.

(cherry picked from commit e9a96ea1ac)
(with changes from commit eb1321f291)
2017-01-23 14:40:10 -02:00
Mike Frysinger e9d53ff4d4 localedata: bs_BA: fix yesexpr/noexpr [BZ #20974]
Both regexes end with a "*." which means the previous match can be
omitted, and then the . allows them to match any input at all.

This means tools like coreutils' `rm -i` will always delete things
when prompted because the yesexpr regex matches all inputs (even
the negative ones).

(cherry picked from commit a035eb6928)
2016-12-30 01:52:17 -05:00
Aurelien Jarno 3a5aa2ee4f alpha: fix trunc for big input values
The alpha specific version of trunc and truncf always add and subtract
0x1.0p23 or 0x1.0p52 even for big values. This causes this kind of
errors in the testsuite:

  Failure: Test: trunc_towardzero (0x1p107)
  Result:
   is:          1.6225927682921334e+32   0x1.fffffffffffffp+106
   should be:   1.6225927682921336e+32   0x1.0000000000000p+107
   difference:  1.8014398509481984e+16   0x1.0000000000000p+54
   ulp       :  0.5000
   max.ulp   :  0.0000

Change this by returning the input value when its absolute value is
greater than 0x1.0p23 or 0x1.0p52. NaN have to go through the add and
subtract operations to get possibly silenced.

Finally remove the code to handle inexact exception, trunc should never
generate such an exception.

Changelog:
	* sysdeps/alpha/fpu/s_trunc.c (__trunc): Return the input value
	when its absolute value is greater than 0x1.0p52.
	[_IEEE_FP_INEXACT] Remove.
	* sysdeps/alpha/fpu/s_truncf.c (__truncf): Return the input value
	when its absolute value is greater than 0x1.0p23.
	[_IEEE_FP_INEXACT] Remove.

(cherry picked from commit b74d259fe7)
2016-12-08 00:36:18 -05:00
Aurelien Jarno 51a313c504 alpha: fix rint on sNaN input
The alpha version of rint wrongly return sNaN for sNaN input. Fix that
by checking for NaN and by returning the input value added with itself
in that case.

Changelog:
	* sysdeps/alpha/fpu/s_rint.c (__rint): Add argument with itself
	when it is a NaN.
	* sysdeps/alpha/fpu/s_rintf.c (__rintf): Likewise.

(cherry picked from commit cb7f9d63b9)
2016-12-08 00:36:15 -05:00
Aurelien Jarno 12bf4f130d alpha: fix floor on sNaN input
The alpha version of floor wrongly return sNaN for sNaN input. Fix that
by checking for NaN and by returning the input value added with itself
in that case.

Finally remove the code to handle inexact exception, floor should never
generate such an exception.

Changelog:
	* sysdeps/alpha/fpu/s_floor.c (__floor): Add argument with itself
	when it is a NaN.
	[_IEEE_FP_INEXACT] Remove.
	* sysdeps/alpha/fpu/s_floorf.c (__floorf): Likewise.

(cherry picked from commit 65cc568cf5)
2016-12-08 00:36:12 -05:00
Aurelien Jarno 85186de4f4 alpha: fix ceil on sNaN input
The alpha version of ceil wrongly return sNaN for sNaN input. Fix that
by checking for NaN and by returning the input value added with itself
in that case.

Finally remove the code to handle inexact exception, ceil should never
generate such an exception.

Changelog:
	* sysdeps/alpha/fpu/s_ceil.c (__ceil): Add argument with itself
	when it is a NaN.
	[_IEEE_FP_INEXACT] Remove.
	* sysdeps/alpha/fpu/s_ceilf.c (__ceilf): Likewise.

(cherry picked from commit 062e53c195)
2016-12-08 00:36:05 -05:00
Maciej W. Rozycki 8ee1ecb99c MIPS: Add `.insn' to ensure a text label is defined as code not data
Avoid a build error with microMIPS compilation and recent versions of
GAS which complain if a branch targets a label which is marked as data
rather than microMIPS code:

../sysdeps/mips/mips32/crti.S: Assembler messages:
../sysdeps/mips/mips32/crti.S:72: Error: branch to a symbol in another ISA mode
make[2]: *** [.../csu/crti.o] Error 1

as commit 9d862524f6ae ("MIPS: Verify the ISA mode and alignment of
branch and jump targets") closed a hole in branch processing, making
relocation calculation respect the ISA mode of the symbol referred.
This allowed diagnosing the situation where an attempt is made to pass
control from code assembled for one ISA mode to code assembled for a
different ISA mode and either relaxing the branch to a cross-mode jump
or if that is not possible, then reporting this as an error rather than
letting such code build and then fail unpredictably at the run time.

This however requires the correct annotation of branch targets as code,
because the ISA mode is not relevant for data symbols and is therefore
not recorded for them.  The `.insn' pseudo-op is used for this purpose
and has been supported by GAS since:

Wed Feb 12 14:36:29 1997  Ian Lance Taylor  <ian@cygnus.com>

	* config/tc-mips.c (mips_pseudo_table): Add "insn".
	(s_insn): New static function.
	* doc/c-mips.texi: Document .insn.

so there has been no reason to avoid it where required.  More recently
this pseudo-op has been documented, by the microMIPS architecture
specification[1][2], as required for the correct interpretation of any
code label which is not followed by an actual instruction in an assembly
source.

Use it in our crti.S files then, to mark that the trailing label there
with no instructions following is indeed not a code bug and the branch
is legitimate.

References:

[1] "MIPS Architecture for Programmers, Volume II-B: The microMIPS32
    Instruction Set", MIPS Technologies, Inc., Document Number: MD00582,
    Revision 5.04, January 15, 2014, Section 7.1 "Assembly-Level
    Compatibility", p. 533

[2] "MIPS Architecture for Programmers, Volume II-B: The microMIPS64
    Instruction Set", MIPS Technologies, Inc., Document Number: MD00594,
    Revision 5.04, January 15, 2014, Section 8.1 "Assembly-Level
    Compatibility", p. 623

2016-11-23  Matthew Fortune  <Matthew.Fortune@imgtec.com>
            Maciej W. Rozycki  <macro@imgtec.com>

	* sysdeps/mips/mips32/crti.S (_init): Add `.insn' pseudo-op at
	`.Lno_weak_fn' label.
	* sysdeps/mips/mips64/n32/crti.S (_init): Likewise.
	* sysdeps/mips/mips64/n64/crti.S (_init): Likewise.

(cherry picked from commit cfaf1949ff)
2016-11-23 12:58:50 +00:00
Denis Kaganovich a6a59e99d1 configure: accept __stack_chk_fail_local for ssp support too [BZ #20662]
When glibc is compiled with gcc 6.2 that has been configured with
--enable-default-pie and --enable-default-ssp, the configure script
fails to detect that the compiler has ssp turned on by default when
being built for i686-linux-gnu.

This is because gcc is emitting __stack_chk_fail_local but the
script is only looking for __stack_chk_fail.  Support both.

Example output:
checking whether x86_64-pc-linux-gnu-gcc -m32 -Wl,-O1 -Wl,--as-needed
implicitly enables -fstack-protector... no

(cherry picked from commit c7409aded4)
2016-11-15 14:31:53 -05:00
Siddhesh Poyarekar 422facff9f Fix cos computation for multiple precision fallback (bz #20357)
During the sincos consolidation I made two mistakes, one was a logical
error due to which cos(0x1.8475e5afd4481p+0) returned
sin(0x1.8475e5afd4481p+0) instead.

The second issue was an error in negating inputs for the correct
quadrants for sine.  I could not find a suitable test case for this
despite running a program to search for such an input for a couple of
hours.

Following patch fixes both issues.  Tested on x86_64.  Thanks to Matt
Clay for identifying the issue.

	[BZ #20357]
	* sysdeps/ieee754/dbl-64/s_sin.c (sloww): Fix up condition
	to call __mpsin/__mpcos and to negate values.
	* math/auto-libm-test-in: Add test.
	* math/auto-libm-test-out: Regenerate.

(cherry picked from commit cbf88869ed)
2016-11-02 09:10:28 +01:00
Andrew Senkevich 6ab1e91474 Don't compile do_test with -mavx/-mavx2/-mavx512.
Don't compile do_test (in sincos ABI tests) with -mavx, -mavx2
nor -mavx512 since they won't run on non-AVX machines.

(cherry-picked from commit fe0cf86148)
2016-10-17 19:01:32 +03:00
Andrew Senkevich 0350824fab Fixed x86_64 vector sincos/sincosf ABI.
Fixed wrong vector sincos/sincosf ABI to have it compatible with
current vector function declaration "#pragma omp declare simd notinbranch",
according to which vector sincos should have vector of pointers for second and
third parameters. It is fixed with implementation as wrapper to version
having second and third parameters as pointers.

(cherry-picked from commit ee2196bb67)
2016-10-17 17:55:28 +03:00
Tulio Magno Quites Machado Filho 79312adef2 powerpc: Fix POWER9 implies
Fix multiarch build for POWER9 by correcting the order of the
directories listed at sysnames configure variable.

(cherry picked from commit 1850ce5a2e)
2016-09-19 12:13:10 -03:00
Florian Weimer 2eda04ec6f nptl/tst-once5: Reduce time to expected failure
(cherry picked from commit 1f645571d2)
2016-08-18 13:06:01 +02:00
Florian Weimer a86b1fac28 argp: Do not override GCC keywords with macros [BZ #16907]
glibc provides fallback definitions already.  It is not necessary to
suppress warnings for unknown attributes because GCC does this
automatically for system headers.

This commit does not sync with gnulib because gnulib has started to use
_GL_* macros in the header file, which are arguably in the gnulib
implementation space and not suitable for an installed glibc header
file.

(cherry picked from commit 2c820533c6)
2016-08-18 13:04:16 +02:00
Florian Weimer 9e9fcd095a fopencookie: Mangle function pointers stored on the heap [BZ #20222]
(cherry picked from commit 983fd5c41a)
2016-08-18 13:04:13 +02:00
Florian Weimer 79ad3fa2b1 nss_db: Fix initialization of iteration position [BZ #20237]
When get*ent is called without a preceding set*ent, we need
to set the initial iteration position in get*ent.

Reproducer: Add “services: db files” to /etc/nsswitch.conf, then run
“perl -e getservent”.  It will segfault before this change, and exit
silently after it.

(cherry picked from commit 31d0a4fa64)
2016-08-18 13:02:45 +02:00
Andreas Schwab 395b1b9cbf Return proper status from _nss_nis_initgroups_dyn (bug 20262)
(cherry picked from commit 73fb56a4d5)
2016-08-18 13:02:21 +02:00
Florian Weimer a69d26143b malloc: Avoid premature fallback to mmap [BZ #20284]
Before this change, the while loop in reused_arena which avoids
returning a corrupt arena would never execute its body if the selected
arena were not corrupt.  As a result, result == begin after the loop,
and the function returns NULL, triggering fallback to mmap.

(cherry picked from commit a3b473373e)
2016-08-18 13:01:41 +02:00
Andreas Schwab 23446cad92 arm: mark __startcontext as .cantunwind (bug 20435)
__startcontext marks the bottom of the call stack of the contexts created
by makecontext.

(cherry picked from commit 9e2ff6c9cc)

Also includes the NEWS update, cherry-picked from commits
056dd72af8 and
4d047efdbc.
2016-08-18 13:00:06 +02:00
Florian Weimer 3a97372dbe Do not override objects in libc.a in other static libraries [BZ #20452]
With this change, we no longer add sysdep.o and similar objects which
are present in libc.a to other static libraries.

(cherry picked from commit d9067fca40)
2016-08-18 12:57:39 +02:00
Florian Weimer 0266710379 malloc: Preserve arena free list/thread count invariant [BZ #20370]
It is necessary to preserve the invariant that if an arena is
on the free list, it has thread attach count zero.  Otherwise,
when arena_thread_freeres sees the zero attach count, it will
add it, and without the invariant, an arena could get pushed
to the list twice, resulting in a cycle.

One possible execution trace looks like this:

Thread 1 examines free list and observes it as empty.
Thread 2 exits and adds its arena to the free list,
  with attached_threads == 0).
Thread 1 selects this arena in reused_arena (not from the free list).
Thread 1 increments attached_threads and attaches itself.
  (The arena remains on the free list.)
Thread 1 exits, decrements attached_threads,
  and adds the arena to the free list.

The final step creates a cycle in the usual way (by overwriting the
next_free member with the former list head, while there is another
list item pointing to the arena structure).

tst-malloc-thread-exit exhibits this issue, but it was only visible
with a debugger because the incorrect fix in bug 19243 removed
the assert from get_free_list.

(cherry picked from commit f88aab5d50)
2016-08-04 11:56:22 +02:00
Florian Weimer e3e0bedf69 x86: Use sysdep.o from libc.a in static libraries
Static libraries can use the sysdep.o copy in libc.a without
a performance penalty.  This results in a visible difference
if libpthread.a is relinked into a single object file (which
is needed to support libraries which check for the presence
of certain symbols to enable threading support, which generally
fails with static linking unless libpthread.a is relinked).

(cherry picked from commit e67330ab57)
2016-08-04 11:52:46 +02:00
Aurelien Jarno bbe472f4e0 SPARC64: update localplt.data
Commits d81f90cc and 89faa0340 replaced called to __isnan and __isinf
by the corresponding GCC builtins. In turns GCC emits calls to _Qp_cmp.
We should therefore add _Qp_cmp to localplt.data as otherwise the
elf/check-localplt test fails with:

   Extra PLT reference: libc.so: _Qp_cmp

A similar change has already been done for SPARC32 in commit 6ef1cb95.

Changelog:
	* sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data: Add _Qp_cmp.

(cherry picked from commit fd1cf1dc3b)
2016-07-01 14:47:20 +02:00
John David Anglin 0903610fdc hppa: fix loading of global pointer in _start [BZ #20277]
The patched change fixes a regression for executables compiled with the
-p option and linked with gcrt1.o.  The executables crash on startup.

This regression was introduced in 2.22 and was noticed in the gcc testsuite.

(cherry picked from commit 9765ffa710)
2016-07-01 14:40:09 +02:00
Aurelien Jarno 3d21617c43 i686/multiarch: Regenerate ulps
This comes from running “make regen-ulps” on AMD Opteron 6272 CPUs.

Changelog:
	* sysdeps/i386/i686/fpu/multiarch/libm-test-ulps: Regenerated.

(cherry picked from commit 6a40d8df0c)
2016-06-30 00:53:16 +02:00
Stefan Liebler 6bf10d196d Fix tst-cancel17/tst-cancelx17, which sometimes segfaults while exiting.
The testcase tst-cancel[x]17 ends sometimes with a segmentation fault.
This happens in one of 10000 cases. Then the real testcase has already
exited with success and returned from do_test(). The segmentation fault
occurs after returning from main in _dl_fini().

In those cases, the aio_read(&a) was not canceled because the read
request was already in progress. In the meanwhile aio_write(ap) wrote
something to the pipe and the read request is able to read the
requested byte.
The read request hasn't finished before returning from do_test().
After it finishes, it writes the return value and error code from the
read syscall to the struct aiocb a, which lies on the stack of do_test.
The stack of the subsequent function call of _dl_fini or _dl_sort_fini,
which is inlined in _dl_fini is corrupted.

In case of S390, it reads a zero and decrements it by 1:
unsigned int k = nmaps - 1;
struct link_map **runp = maps[k]->l_initfini;
The load from unmapped memory leads to the segmentation fault.
The stack corruption also happens on other architectures.
I saw them e.g. on x86 and ppc, too.

This patch adds an aio_suspend call to ensure, that the read request
is finished before returning from do_test().

ChangeLog:

	* nptl/tst-cancel17.c (do_test): Wait for finishing aio_read(&a).

(cherry picked from commit b3a810d0d3)
2016-06-28 12:28:21 +02:00
Aurelien Jarno cacad9315e MIPS: run tst-mode-switch-{1,2,3}.c using test-skeleton.c
For some reasons I have not investigated yet, tst-mode-switch-1 hangs on
a MIPS UTM-8 machine running an o32 userland and a 3.6.1 kernel.

This patch changes the test so that it runs under the test-skeleton
framework, causing the test to fail after a timeout instead of hanging
the whole testsuite. At the same time, also change the tst-mode-switch-2
and tst-mode-switch-3 tests.

Changelog:
	* sysdeps/mips/tst-mode-switch-1.c (main): Converted to ...
	(do_test): ... this.
	(TEST_FUNCTION): New macro.
	 Include test-skeleton.c.
	* sysdeps/mips/tst-mode-switch-2.c (main): Likewise.
	* sysdeps/mips/tst-mode-switch-3.c (main): Likewise.

(cherry picked from commit 0cdaef4dac)
2016-06-27 23:59:43 +02:00
Aurelien Jarno d16e36e575 MIPS, SPARC: more fixes to the vfork aliases in libpthread.so
Commit 43c29487 tried to fix the vfork aliases in libpthread.so on MIPS
and SPARC, but failed to do it correctly, introducing an ABI change.

This patch does the remaining changes needed to align the MIPS and SPARC
vfork implementations with the other architectures. That way the the
alpha version of pt-vfork.S works correctly for MIPS and SPARC. The
changes for alpha were done in 82aab97c.

Changelog:
	* sysdeps/unix/sysv/linux/mips/vfork.S (__vfork): Rename into
	__libc_vfork.
	(__vfork) [IS_IN (libc)]: Remove alias.
	(__libc_vfork) [IS_IN (libc)]: Define as an alias.
	* sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.

(cherry picked from commit b87c1ec3fa)
2016-06-27 10:02:14 +02:00
Aurelien Jarno 80bf719031 MIPS, SPARC: fix wrong vfork aliases in libpthread.so
With recent binutils versions the GNU libc fails to build on at least
MISP and SPARC, with this kind of error:

  /home/aurel32/glibc/glibc-build/nptl/libpthread.so:(*IND*+0x0): multiple definition of `vfork@GLIBC_2.0'
  /home/aurel32/glibc/glibc-build/nptl/libpthread.so::(.text+0xee50): first defined here

It appears that on these architectures pt-vfork.S includes vfork.S
(through the alpha version of pt-vfork.S) and that the __vfork aliases
are not conditionalized on IS_IN (libc) like on other architectures.
Therefore the aliases are also wrongly included in libpthread.so.

Fix this by properly conditionalizing the aliases like on other
architectures.

Changelog:
	* sysdeps/unix/sysv/linux/mips/vfork.S (__vfork): Conditionalize
	hidden_def, weak_alias and strong_alias on [IS_IN (libc)].
	* sysdeps/unix/sysv/linux/sparc/sparc32/vfork.S: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/vfork.S: Likewise.

(cherry picked from commit 43c2948756)
2016-06-19 15:48:38 +02:00
Adhemerval Zanella 321e1cef26 libio: Fix fmemopen append mode failure (BZ# 20012)
The fmemopen implementation does not account the file position correctly in
append mode. The following example shows the failure:

===
int main ()
{
  char buf[10] = "test";
  FILE *fp = fmemopen (buf, 10, "a+");
  fseek (fp, 0, SEEK_SET);

  int gr;
  if ((gr = getc (fp)) != 't' ||
      (gr = getc (fp)) != 'e' ||
      (gr = getc (fp)) != 's' ||
      (gr = getc (fp)) != 't' ||
      (gr = getc (fp)) != EOF)
    {
      printf ("%s: getc failed returned %i\n", __FUNCTION__, gr);
      return 1;
    }

  return 0;
}
===

This is due both how read and write operation update the buffer position,
taking in consideration buffer lenght instead of maximum position defined
by the open mode.  This patch fixes it and also fixes fseek not returning
EINVAL for invalid whence modes.

Tested on x86_64 and i686.

This is a backport of b65b205fbc.

	[BZ #20012]
	* libio/fmemopen.c (fmemopen_read): Use buffer maximum position, not
	length to calculate the buffer to read.
	(fmemopen_write): Set the buffer position based on bytes written.
	(fmemopen_seek): Return EINVAL for invalid whence modes.
2016-06-03 15:07:21 -03:00
Adhemerval Zanella c2fba3b047 libio: Update internal fmemopen position after write (BZ #20005)
Current GLIBC fmemopen fails with a simple testcase:

  char buffer[500] = "x";
  FILE *stream;
  stream = fmemopen(buffer, 500, "r+");
  fwrite("fish",sizeof(char),5,stream);
  printf("pos-1:%ld\n",ftell(stream));
  fflush(stream);
  printf("pos-2:%ld\n",ftell(stream));

It returns:

  pos-1:5
  pos-2:0

Where it should return:

  pos-1:5
  pos-2:5

This is due the internal write function does not correctly update the internal
object position state and then the seek operation returns a wrong value.  This
patch fixes it.

It fixes both BZ #20005 and BZ #19230 (marked as duplicated). A new test is
added to check for such case.

Tested on x86_64 and i686.

This is a backport of f9123b5003.

	* libio/fmemopen.c (fmemopen_write): Update internal position after
	write.
	* stdio-common/Makefile (tests): Add tst-fmemopen4.c.
	* stdio-common/tst-fmemopen4.c: New file..
2016-06-03 15:07:19 -03:00
Florian Weimer 1915d6d182 fork in libpthread cannot use IFUNC resolver [BZ #19861]
This commit only addresses the fork case, the vfork case has to be a
tail call, which is why the generic code needs an IFUNC resolver
there.

(cherry picked from commit f06f3f05b4)
2016-06-02 11:39:58 +02:00
Florian Weimer e6eea05ee7 test-skeleton.c: Do not set RLIMIT_DATA [BZ #19648]
With older kernels, it is mostly ineffective because it causes malloc
to switch from sbrk to mmap (potentially invalidating malloc testing
compared to what real appliations do).  With newer kernels which
have switched to enforcing RLIMIT_DATA for mmap as well, some test
cases will fail in an unintended fashion because the limit which was
set previously does not include room for all mmap mappings.

(cherry picked from commit 900056024b)
2016-05-30 12:48:09 +02:00
Florian Weimer f222547511 Make padding in struct sockaddr_storage explicit [BZ #20111]
This avoids aliasing issues with GCC 6 in -fno-strict-aliasing
mode.  (With implicit padding, not all data is copied.)

This change makes it explicit that struct sockaddr_storage is
only 126 bytes large on m68k (unlike elsewhere, where we end up
with the requested 128 bytes).  The new test case makes sure that
this does not happen on other architectures.

(cherry picked from commit 3375cfafa7)
2016-05-24 11:21:54 +02:00
Florian Weimer bdce95930e CVE-2016-4429: sunrpc: Do not use alloca in clntudp_call [BZ #20112]
The call is technically in a loop, and under certain circumstances
(which are quite difficult to reproduce in a test case), alloca
can be invoked repeatedly during a single call to clntudp_call.
As a result, the available stack space can be exhausted (even
though individual alloca sizes are bounded implicitly by what
can fit into a UDP packet, as a side effect of the earlier
successful send operation).

(cherry picked from commit bc779a1a5b)
2016-05-24 11:16:07 +02:00
Florian Weimer 25a34b0ac1 tst-mallocfork2: Fix race condition, use fewer resources
The first SIGUSR1 signal could arrive when sigusr1_sender_pid
was still 0.  As a result, kill would send SIGSTOP to the
entire process group.  This would cause the test to hang before
printing any output.

This commit also adds a sched_yield to the signal source, so that
it does not flood the parent process with signals it has never a
chance to handle.

Even with these changes, tst-mallocfork2 still fails reliably
after the fix in commit commit 56290d6e76
(Increase fork signal safety for single-threaded processes) is
backed out.

(cherry picked from commit e2cd73a2cc)

The backport increases the timeout to 20 seconds, in line with
the default on master.  (The branch default of 2 seconds is too
tight.)
2016-05-24 10:59:55 +02:00
Florian Weimer 2143af6a47 Increase fork signal safety for single-threaded processes [BZ #19703]
This provides a band-aid and addresses the scenario where fork is
called from a signal handler while the process is in the malloc
subsystem (or has acquired the libio list lock).  It does not
address the general issue of async-signal-safety of fork;
multi-threaded processes are not covered, and some glibc
subsystems have fork handlers which are not async-signal-safe.

(cherry picked from commit 56290d6e76)
2016-05-12 15:44:52 +02:00
Stefan Liebler a37d61a662 Fix strfmon_l: Use specified locale for number formatting [BZ #19633]
The commit 985fc132f2
"strfmon_l: Use specified locale for number formatting [BZ #19633]"
introduced an elf/check-abi-libc testfailure due to __printf_fp_l
on architectures which use sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h.

This patch uses libc_hidden_def instead of ldbl_hidden_def.
The ldbl_strong_alias is removed due to the rename of ___printf_fp_l
to __printf_fp_l.

ChangeLog:

	* stdio-common/printf_fp.c (__printf_fp_l):
	Rename ___printf_fp_l to __printf_fp_l and
	remove strong alias. Use libc_hidden_def instead
	of ldbl_hidden_def macro.

(cherry picked from commit b1b8f5d89d)
2016-05-11 13:33:01 +02:00
Florian Weimer 1a8a7c1295 CVE-2016-3706: getaddrinfo: stack overflow in hostent conversion [BZ #20010]
When converting a struct hostent response to struct gaih_addrtuple, the
gethosts macro (which is called from gaih_inet) used alloca, without
malloc fallback for large responses.  This commit changes this code to
use calloc unconditionally.

This commit also consolidated a second hostent-to-gaih_addrtuple
conversion loop (in gaih_inet) to use the new conversion function.

(cherry picked from commit 4ab2ab03d4)
2016-05-11 11:55:19 +02:00
Florian Weimer 24e2b1cede Revert "Report dlsym, dlvsym lookup errors using dlerror [BZ #19509]"
This reverts commits 80f87443ee
and a824d60958.

See bug 20069.  We can revisit this change once there has been a GCC
release with a fix for Address Sanitizer.
2016-05-11 11:42:34 +02:00
Florian Weimer bbea74b299 Remove trailing newline from date_fmt in Serbian locales [BZ #19581]
(cherry picked from commit ff889b1965)
2016-05-09 13:15:25 +02:00
Adhemerval Zanella a824d60958 Fix tst-dlsym-error build
This patch fixes the new test tst-dlsym-error build on aarch64
(and possible other architectures as well) due missing strchrnul
definition.

	* elf/tst-dlsym-error.c: Include <string.h> for strchrnul.

(cherry picked from commit e91bd74658)
2016-05-09 12:46:36 +02:00
Florian Weimer 80f87443ee Report dlsym, dlvsym lookup errors using dlerror [BZ #19509]
* elf/dl-lookup.c (_dl_lookup_symbol_x): Report error even if
	skip_map != NULL.
	* elf/tst-dlsym-error.c: New file.
	* elf/Makefile (tests): Add tst-dlsym-error.
	(tst-dlsym-error): Link against libdl.

(cherry picked from commit 7d45c163d0)
2016-05-09 12:46:35 +02:00
Florian Weimer c4294bd862 ldconfig: Do not remove stale symbolic links with -X [BZ #19610]
(cherry picked from commit 920b35c92e)
2016-05-09 12:18:32 +02:00
Florian Weimer c87db3fcbd CVE-2016-1234: glob: Do not copy d_name field of struct dirent [BZ #19779]
Instead, we store the data we need from the return value of
readdir in an object of the new type struct readdir_result.
This type is independent of the layout of struct dirent.

(cherry picked from commit 5171f3079f)
2016-05-09 12:13:37 +02:00
Florian Weimer 68302147ee glob: Simplify the interface for the GLOB_ALTDIRFUNC callback gl_readdir
Previously, application code had to set up the d_namlen member if
the target supported it, involving conditional compilation.  After
this change, glob will use the length of the string in d_name instead
of d_namlen to determine the file name length.  All glibc targets
provide the d_type and d_ino members, and setting them as needed for
gl_readdir is straightforward.

Changing the behavior with regards to d_ino is left to a future
cleanup.

(cherry picked from commit 137fe72eca)
2016-05-09 12:13:36 +02:00
Florian Weimer 90c0f166e9 strfmon_l: Use specified locale for number formatting [BZ #19633]
(cherry picked from commit 985fc132f2)
2016-05-09 12:01:52 +02:00
Florian Weimer 4cf055a2a3 tst-audit10: Fix compilation on compilers without bit_AVX512F [BZ #19860]
[BZ# 19860]
	* sysdeps/x86_64/tst-audit10.c (avx512_enabled): Always return
	zero if the compiler does not provide the AVX512F bit.

(cherry picked from commit f327f5b47b)
2016-05-09 11:56:20 +02:00
Roland McGrath d603d94994 Fix tst-audit10 build when -mavx512f is not supported.
(cherry picked from commit 3bd80c0de2)
2016-05-09 11:56:05 +02:00
Florian Weimer 7fa9775594 tst-audit4, tst-audit10: Compile AVX/AVX-512 code separately [BZ #19269]
This ensures that GCC will not use unsupported instructions before
the run-time check to ensure support.

(cherry picked from commit 3c0f7407ee)
2016-05-09 11:55:37 +02:00
Florian Weimer 075b2665b1 resolv: Always set *resplen2 out parameter in send_vc [BZ #19825]
In various error scenarios (for example, if the server closes the
TCP connection before sending the full response), send_vc can return
without resetting the *resplen2 value.  This can pass uninitialized
or unexpected data to the caller.

(cherry picked from commit b9bdfa7c8f)
2016-05-09 11:37:38 +02:00
Florian Weimer 1e5ac8a1da nss_dns: Skip over non-PTR records in the netent code [BZ #19868]
This requires additional checks for the RDATA length and the
availability of record metadata.

(cherry picked from commit a12f9431b3)
2016-05-09 11:35:16 +02:00
Florian Weimer 730244f49a nss_dns: Check address length before creating addrinfo result [BZ #19831]
Previously, we allocated room in the result space before the check,
leaving uninitialized data there in case the check failed.

This also consolidates the behavior between single (A or AAAA) and
dual (A and AAAA in parallel) queries.  Single queries checked
the record length against the QTYPE, not the RRTYPE.

(cherry picked from commit 5e0c421cc0)
2016-05-09 11:35:01 +02:00
Florian Weimer 1e51b4d367 resolv, nss_dns: Remove remaining syslog logging [BZ #19862]
The fix for bug 14841 only removed part of the logging.

(cherry picked from commit b9b026c9c0)
2016-05-09 11:34:54 +02:00
Florian Weimer f233c608d1 nss_dns: Validate RDATA length against packet length [BZ #19830]
In _nss_dns_getcanonname_r, a check for the availability of RR metadata
was missing as well.

(cherry picked from commit f749498fa5)
2016-05-09 11:34:48 +02:00
Florian Weimer 49203a513f nss_dns: Fix assertion failure in _nss_dns_getcanonname_r [BZ #19865]
(cherry picked from commit d29fb41f44)
2016-05-09 11:29:20 +02:00
Florian Weimer 888d9a0146 malloc: Add missing internal_function attributes on function definitions
Fixes build on i386 after commit 29d794863c.

(cherry picked from commit 186fe877f3)
2016-05-09 11:22:01 +02:00
Florian Weimer 927170dd59 malloc: Remove malloc hooks from fork handler
The fork handler now runs so late that there is no risk anymore that
other fork handlers in the same thread use malloc, so it is no
longer necessary to install malloc hooks which made a subset
of malloc functionality available to the thread that called fork.

(cherry picked from commit 8a727af925)
2016-05-09 11:22:01 +02:00
Florian Weimer 2a71cf4096 malloc: Run fork handler as late as possible [BZ #19431]
Previously, a thread M invoking fork would acquire locks in this order:

  (M1) malloc arena locks (in the registered fork handler)
  (M2) libio list lock

A thread F invoking flush (NULL) would acquire locks in this order:

  (F1) libio list lock
  (F2) individual _IO_FILE locks

A thread G running getdelim would use this order:

  (G1) _IO_FILE lock
  (G2) malloc arena lock

After executing (M1), (F1), (G1), none of the threads can make progress.

This commit changes the fork lock order to:

  (M'1) libio list lock
  (M'2) malloc arena locks

It explicitly encodes the lock order in the implementations of fork,
and does not rely on the registration order, thus avoiding the deadlock.

(cherry picked from commit 29d794863c)
2016-05-09 11:22:00 +02:00
Samuel Thibault a5c2f42566 Fix malloc threaded tests link on non-Linux
* malloc/Makefile ($(objpfx)tst-malloc-backtrace,
	$(objpfx)tst-malloc-thread-exit, $(objpfx)tst-malloc-thread-fail): Use
	$(shared-thread-library) instead of hardcoding the path to libpthread.

(cherry picked from commit b87e41378b)
2016-05-09 11:22:00 +02:00
Florian Weimer f69ae17e84 malloc: Remove NO_THREADS
No functional change.  It was not possible to build without
threading support before.

(cherry picked from commit 59eda029a8)
2016-05-09 11:21:02 +02:00
Florian Weimer 4c4b3cbb46 hesiod: Avoid heap overflow in get_txt_records [BZ #20031]
(cherry picked from commit 8a03ccbb77)
2016-05-09 11:18:58 +02:00
Florian Weimer 2d1f679018 hesiod: Always use thread-local resolver state [BZ #19573]
The Hesiod implementation imported into glibc was enhanced
to support caller-supplied resolver states.  But its only
consumer is nss_hesiod, and it supplies the thread-local
resolver state.  Therefore, this commit changes the Hesiod
implementation to use the thread-local resolver state (_res)
directly.  This fixes bug 19573 because the Hesiod
implementation no longer has to initialize and free any
resolver state.

To avoid any risk of interposition of ABI-incompatible Hesiod
function implementations, this commit marks the Hesiod functions
as hidden.  (They were already hidden using a linker version
script.)

(cherry picked from commit 5018f16c62)
2016-05-09 11:15:05 +02:00
Florian Weimer 8a756c076e hesiod: Remove RCS keywords
(cherry picked from commit dbdc657dc0)
2016-05-09 11:15:05 +02:00
Florian Weimer f8020794ae getnameinfo: Return EAI_OVERFLOW in more cases [BZ #19787]
The AF_LOCAL and AF_INET/AF_INET6 non-numerci service conversion
did not return EAI_OVERFLOW if the supplied buffer was too small,
silently returning truncated data.  In the AF_INET/AF_INET6
numeric cases, the snprintf return value checking was incorrect.

(cherry picked from commit 066746783d)
2016-05-09 11:08:02 +02:00
Florian Weimer 05d2606fa1 getnameinfo: Avoid calling strnlen on uninitialized buffer
In the numeric AF_INET/AF_INET6 case, if inet_ntop fails
as the result of a short host buffer, we used to call strnlen
on the uninitialized host buffer.

(cherry picked from commit 1c3490d4b2)
2016-05-09 11:08:02 +02:00
Florian Weimer c5aae1035c getnameinfo: Reduce line length and add missing comments
(cherry picked from commit c9b0e6a432)
2016-05-09 11:08:01 +02:00
Florian Weimer e5bcbfc23b getnameinfo: Refactor and fix memory leak [BZ #19642]
Split getnameinfo into separate functions for host and service
lookups, and for different address families.

(cherry picked from commit 2dce81a319)
2016-05-09 11:04:33 +02:00
Florian Weimer 42a496388d getnameinfo: Do not preserve errno
POSIX does not require it, the companion getaddrinfo implementation
does not do it, and this behavior is not documented in the manual
page, either.

(cherry picked from commit 2b54cbce2c)
2016-05-09 11:04:33 +02:00
Florian Weimer 28a87e0274 nss_db: Propagate ERANGE error if parse_line fails [BZ #19837]
Reproducer (needs to run as root):

perl -e \
  'print "large:x:999:" . join(",", map {"user$_"} (1 .. 135))."\n"' \
  >> /etc/group
cd /var/db
make
getent -s db group

After the fix, the last command should list the "large" group.

The magic number 135 has been chosen so that the line is shorter than
1024 bytes, but the pointers required to encode the member array will
cross the threshold, triggering the bug.

(cherry picked from commit a6033052d0)
2016-05-09 10:56:22 +02:00
Yvan Roux 5769d5d17c Suppress GCC 6 warning about ambiguous 'else' with -Wparentheses
(cherry picked from commit df1cf48777)
2016-04-20 10:43:40 +01:00
Mike Frysinger f1e182acaa configure: fix test == usage
POSIX defines the = operator, but not ==.  Fix the few places where we
incorrectly used ==.

(cherry picked from commit b2d4456b33)
2016-04-09 20:06:24 -04:00
Florian Weimer 146b58d11f CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879]
The defensive copy is not needed because the name may not alias the
output buffer.

(cherry picked from commit 317b199b4a)
(cherry picked from commit 883dceebc8)
2016-04-04 15:31:21 -04:00
Stefan Liebler 0eb234232e S390: Extend structs La_s390_regs / La_s390_retval with vector-registers.
Starting with z13, vector registers can also occur as argument registers.
Thus the passed input/output register structs for
la_s390_[32|64]_gnu_plt[enter|exit] functions should reflect those new
registers. This patch extends these structs La_s390_regs and La_s390_retval
and adjusts _dl_runtime_profile() to handle those fields in case of
running on a z13 machine.

(picked from upstream commit 5cdd1989d1)

ChangeLog:

	* sysdeps/s390/bits/link.h: (La_s390_vr) New typedef.
	(La_s390_32_regs): Append vector register lr_v24-lr_v31.
	(La_s390_64_regs): Likewise.
	(La_s390_32_retval): Append vector register lrv_v24.
	(La_s390_64_retval): Likeweise.
	* sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_profile):
	Handle extended structs La_s390_32_regs and La_s390_32_retval.
	* sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_profile):
	Handle extended structs La_s390_64_regs and La_s390_64_retval.
2016-04-01 14:12:05 +02:00
Stefan Liebler d93f04543c S390: Save and restore fprs/vrs while resolving symbols.
On s390, no fpr/vrs were saved while resolving a symbol
via _dl_runtime_resolve/_dl_runtime_profile.

According to the abi, the fpr-arguments are defined as call clobbered.
In leaf-functions, gcc 4.9 and newer can use fprs for saving/restoring gprs
instead of saving them to the stack.
If gcc do this in one of the resolver-functions, then the floating point
arguments of a library-function are invalid for the first library-function-call.
Thus, this patch saves/restores the fprs around the resolving code.

The same could occur for vector registers. Furthermore an ifunc-resolver
could also clobber the vector/floating point argument registers.
Thus this patch provides the further variants _dl_runtime_resolve_vx/
_dl_runtime_profile_vx, which are used if the kernel claims, that
we run on a machine with vector registers.

Furthermore, if _dl_runtime_profile calls _dl_call_pltexit,
the pointers to inregs-/outregs-structs were setup invalid.
Now they point to the correct location in the stack-frame.
Before branching back to the caller, the return values are now
restored instead of containing the return values of the
_dl_call_pltexit() call.
On s390-32, an endless loop occurs if _dl_call_pltexit() should be called.
Now, this code-path branches to this function instead of just after the
preceding basr-instruction.

(Picked from upstream commits 4603c51ef7
and d8a012c5c9)

ChangeLog:

	* sysdeps/s390/s390-32/dl-trampoline.S: Include dl-trampoline.h twice
	to create a non-vector/vector version for _dl_runtime_resolve and
	_dl_runtime_profile. Move implementation to ...
	* sysdeps/s390/s390-32/dl-trampoline.h: ... here.
	(_dl_runtime_resolve) Save and restore fpr/vrs.
	(_dl_runtime_profile) Save and restore vrs and fix some issues
	if _dl_call_pltexit is called.
	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_runtime_setup):
	Choose the correct resolver function if running on a machine with vx.
	* sysdeps/s390/s390-64/dl-trampoline.S: Include dl-trampoline.h twice
	to create a non-vector/vector version for _dl_runtime_resolve and
	_dl_runtime_profile. Move implementation to ...
	* sysdeps/s390/s390-64/dl-trampoline.h: ... here.
	(_dl_runtime_resolve) Save and restore fpr/vrs.
	(_dl_runtime_profile) Save and restore vrs and fix some issues
	* sysdeps/s390/s390-64/dl-machine.h: (elf_machine_runtime_setup):
	Choose the correct resolver function if running on a machine with vx.
2016-04-01 14:11:10 +02:00
Florian Weimer 3a188eb4e6 resolv: Always set *resplen2 out parameter in send_dg [BZ #19791]
Since commit 44d20bca52 (Implement
second fallback mode for DNS requests), there is a code path which
returns early, before *resplen2 is initialized.  This happens if the
name server address is immediately recognized as invalid (because of
lack of protocol support, or if it is a broadcast address such
255.255.255.255, or another invalid address).

If this happens and *resplen2 was non-zero (which is the case if a
previous query resulted in a failure), __libc_res_nquery would reuse
an existing second answer buffer.  This answer has been previously
identified as unusable (for example, it could be an NXDOMAIN
response).  Due to the presence of a second answer, no name server
switching will occur.  The result is a name resolution failure,
although a successful resolution would have been possible if name
servers have been switched and queries had proceeded along the search
path.

The above paragraph still simplifies the situation.  Before glibc
2.23, if the second answer needed malloc, the stub resolver would
still attempt to reuse the second answer, but this is not possible
because __libc_res_nsearch has freed it, after the unsuccessful call
to __libc_res_nquerydomain, and set the buffer pointer to NULL.  This
eventually leads to an assertion failure in __libc_res_nquery:

	/* Make sure both hp and hp2 are defined */
	assert((hp != NULL) && (hp2 != NULL));

If assertions are disabled, the consequence is a NULL pointer
dereference on the next line.

Starting with glibc 2.23, as a result of commit
e9db92d3ac (CVE-2015-7547: getaddrinfo()
stack-based buffer overflow (Bug 18665)), the second answer is always
allocated with malloc.  This means that the assertion failure happens
with small responses as well because there is no buffer to reuse, as
soon as there is a name resolution failure which triggers a search for
an answer along the search path.

This commit addresses the issue by ensuring that *resplen2 is
initialized before the send_dg function returns.

This commit also addresses a bug where an invalid second reply is
incorrectly returned as a valid to the caller.

(cherry picked from commit b66d837bb5)
2016-03-28 22:24:16 +02:00
Dylan Alex Simon 73f158cef5 math: don't clobber old libm.so on install [BZ #19822]
When installing glibc (w/mathvec enabled) in-place on a system with
a glibc w/out mathvec enabled, the install will clobber the existing
libm.so (e.g., /lib64/libm-2.21.so) with a linker script.  This is
because libm.so is a symlink to libm.so.6 which is a symlink to the
final libm-2.21.so file.  When the makefile writes the linker script
directly to libm.so, it gets clobbered.

The simple patch below to math/Makefile fixes this.  It is based on
the nptl Makefile, which does exactly the same thing in a safer way.

(cherry picked from commit f9378ac377)
2016-03-21 02:21:12 -04:00
Andreas Schwab 317da342ba Fix resource leak in resolver (bug 19257)
The number of currently defined nameservers is stored in ->nscount,
whereas ->_u._ext.nscount is set by __libc_res_nsend only after local
initializations.

(cherry picked from commit 5e7fdabd7d)
2016-03-20 12:23:26 +01:00
H.J. Lu 33ab2ad58e Or bit_Prefer_MAP_32BIT_EXEC in EXTRA_LD_ENVVARS
We should turn on bit_Prefer_MAP_32BIT_EXEC in EXTRA_LD_ENVVARS without
overriding other bits.

	[BZ #19758]
	* sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
	(EXTRA_LD_ENVVARS): Or bit_Prefer_MAP_32BIT_EXEC.
2016-03-11 08:21:20 -08:00
H.J. Lu b4456470a6 Define _HAVE_STRING_ARCH_mempcpy to 1 for x86
Since x86 has an optimized mempcpy and GCC can inline mempcpy on x86,
define _HAVE_STRING_ARCH_mempcpy to 1 for x86.

	[BZ #19759]
	* sysdeps/x86/bits/string.h (_HAVE_STRING_ARCH_mempcpy): New.

(cherry picked from commit 2b35e48c0c)
2016-03-11 07:47:11 -08:00
H.J. Lu 3ac64b00b5 Mention BZ #19762 in NEWS 2016-03-10 17:08:23 -08:00
H.J. Lu 0594fd0546 Use HAS_ARCH_FEATURE with Fast_Rep_String
HAS_ARCH_FEATURE, not HAS_CPU_FEATURE, should be used with
Fast_Rep_String.

	[BZ #19762]
	* sysdeps/i386/i686/multiarch/bcopy.S (bcopy): Use
	HAS_ARCH_FEATURE with Fast_Rep_String.
	* sysdeps/i386/i686/multiarch/bzero.S (__bzero): Likewise.
	* sysdeps/i386/i686/multiarch/memcpy.S (memcpy): Likewise.
	* sysdeps/i386/i686/multiarch/memcpy_chk.S (__memcpy_chk):
	Likewise.
	* sysdeps/i386/i686/multiarch/memmove_chk.S (__memmove_chk):
	Likewise.
	* sysdeps/i386/i686/multiarch/mempcpy.S (__mempcpy): Likewise.
	* sysdeps/i386/i686/multiarch/mempcpy_chk.S (__mempcpy_chk):
	Likewise.
	* sysdeps/i386/i686/multiarch/memset.S (memset): Likewise.
	* sysdeps/i386/i686/multiarch/memset_chk.S (__memset_chk):
	Likewise.

(cherry picked from commit 4e940b2f4b)
2016-03-10 05:32:48 -08:00
Aurelien Jarno 63ed4db4b4 mips: terminate the FDE before the return trampoline in makecontext
In makecontext the FDE needs to be terminated before the return
trampoline otherwise backtrace called within a context created by
makecontext yields infinite backtrace.

This bug has been present for a long time, stdlib/tst-makecontext did
not fail until recent commit e535ce25. Tested on mips-linux-gnu and
mips64el-linux-gnuabi64 and mips-linux-gnu, no regression.

This fixes stdlib/tst-makecontext on MIPS.

Changelog:
	[BZ #19792]
	* sysdeps/unix/sysv/linux/mips/makecontext.S (__makecontext):
	Terminate FDE before return label.

(cherry picked from commit f8e9c4d30c)
2016-03-09 18:51:50 +01:00
Aurelien Jarno 9d1399e89d Add sys/auxv.h wrapper to include/sys/
The GNU libc testsuite fails to build on powerpc/ppc64/ppc64le with the
following error:

    ../sysdeps/powerpc/test-get_hwcap.c:26:22: fatal error: sys/auxv.h: No such file or director

This is because test-get_hwcap.c includes <sys/auxv.h>, but we don't
provide a wrapper in include/sys. This patch adds one.

Changelog:
	* include/sys/auxv.h: New file.

(cherry picked from commit 0b8dedd38f)
2016-03-08 21:22:21 +01:00
Hongjiu Zhang f23d7d2a84 sln: use stat64
When using sln on some filesystems which return 64-bit inodes,
the stat call might fail during install like so:
	.../elf/sln .../elf/symlink.list
	/lib32/libc.so.6: invalid destination: Value too large for defined data type
	/lib32/ld-linux.so.2: invalid destination: Value too large for defined data type
	Makefile:104: recipe for target 'install-symbolic-link' failed

Switch to using stat64 all the time to avoid this.

URL: https://bugs.gentoo.org/576396
(cherry picked from commit f5e753c8c3)
2016-03-07 11:39:06 -05:00
Carlos O'Donell 0a321a461c Update NEWS. 2016-02-26 02:10:07 -05:00
Carlos O'Donell d27dabc996 NEWS (2.23): Fix typo in bug 19048 text. 2016-02-25 17:26:36 -03:00
Andreas Schwab 591b7e37e6 Don't use long double math functions if NO_LONG_DOUBLE 2016-02-25 10:04:18 -03:00
Roland McGrath f0029f1bb3 Add fts64_* to sysdeps/arm/nacl/libc.abilist
(cherry picked from commit b2e722855b)
2016-02-22 15:20:10 -08:00
H.J. Lu 6094fc2cf7 [x86_64] Set DL_RUNTIME_UNALIGNED_VEC_SIZE to 8
Due to GCC bug:

   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066

__tls_get_addr may be called with 8-byte stack alignment.  Although
this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume
that stack will be always aligned at 16 bytes.  Since SSE optimized
memory/string functions with aligned SSE register load and store are
used in the dynamic linker, we must set DL_RUNTIME_UNALIGNED_VEC_SIZE
to 8 so that _dl_runtime_resolve_sse will align the stack before
calling _dl_fixup:

Dump of assembler code for function _dl_runtime_resolve_sse:
   0x00007ffff7deea90 <+0>:	push   %rbx
   0x00007ffff7deea91 <+1>:	mov    %rsp,%rbx
   0x00007ffff7deea94 <+4>:	and    $0xfffffffffffffff0,%rsp
                                ^^^^^^^^^^^ Align stack to 16 bytes
   0x00007ffff7deea98 <+8>:	sub    $0x100,%rsp
   0x00007ffff7deea9f <+15>:	mov    %rax,0xc0(%rsp)
   0x00007ffff7deeaa7 <+23>:	mov    %rcx,0xc8(%rsp)
   0x00007ffff7deeaaf <+31>:	mov    %rdx,0xd0(%rsp)
   0x00007ffff7deeab7 <+39>:	mov    %rsi,0xd8(%rsp)
   0x00007ffff7deeabf <+47>:	mov    %rdi,0xe0(%rsp)
   0x00007ffff7deeac7 <+55>:	mov    %r8,0xe8(%rsp)
   0x00007ffff7deeacf <+63>:	mov    %r9,0xf0(%rsp)
   0x00007ffff7deead7 <+71>:	movaps %xmm0,(%rsp)
   0x00007ffff7deeadb <+75>:	movaps %xmm1,0x10(%rsp)
   0x00007ffff7deeae0 <+80>:	movaps %xmm2,0x20(%rsp)
   0x00007ffff7deeae5 <+85>:	movaps %xmm3,0x30(%rsp)
   0x00007ffff7deeaea <+90>:	movaps %xmm4,0x40(%rsp)
   0x00007ffff7deeaef <+95>:	movaps %xmm5,0x50(%rsp)
   0x00007ffff7deeaf4 <+100>:	movaps %xmm6,0x60(%rsp)
   0x00007ffff7deeaf9 <+105>:	movaps %xmm7,0x70(%rsp)

	[BZ #19679]
	* sysdeps/x86_64/dl-trampoline.S (DL_RUNIME_UNALIGNED_VEC_SIZE):
	Renamed to ...
	(DL_RUNTIME_UNALIGNED_VEC_SIZE): This.  Set to 8.
	(DL_RUNIME_RESOLVE_REALIGN_STACK): Renamed to ...
	(DL_RUNTIME_RESOLVE_REALIGN_STACK): This.  Updated.
	(DL_RUNIME_RESOLVE_REALIGN_STACK): Renamed to ...
	(DL_RUNTIME_RESOLVE_REALIGN_STACK): This.
	* sysdeps/x86_64/dl-trampoline.h
	(DL_RUNIME_RESOLVE_REALIGN_STACK): Renamed to ...
	(DL_RUNTIME_RESOLVE_REALIGN_STACK): This.
2016-02-22 09:33:13 -08:00
Adhemerval Zanella e742928c15 Regenerated configure scripts. 2016-02-18 18:39:25 -02:00
Adhemerval Zanella d3a793f7ee Regenerate libc.pot for 2.23. 2016-02-18 17:50:24 -02:00
Adhemerval Zanella 792c8ddc60 Updated translations for 2.23.
Cherry-pick from 31ef23afe2.
2016-02-18 17:49:57 -02:00
239 changed files with 19548 additions and 11511 deletions
+1002
View File
File diff suppressed because it is too large Load Diff
+54 -1
View File
@@ -4,6 +4,59 @@ See the end for copying conditions.
Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
Version 2.23.1
Security related changes:
* The getnetbyname implementation in nss_dns had a potentially unbounded
alloca call (in the form of a call to strdupa), leading to a stack
overflow (stack exhaustion) and a crash if getnetbyname is invoked
on a very long name. (CVE-2016-3075)
* The glob function suffered from a stack-based buffer overflow when it was
called with the GLOB_ALTDIRFUNC flag and encountered a long file name.
Reported by Alexander Cherepanov. (CVE-2016-1234)
* The Sun RPC UDP client could exhaust all available stack space when
flooded with crafted ICMP and UDP messages. Reported by Aldy Hernandez'
alloca plugin for GCC. (CVE-2016-4429)
* On ARM EABI (32-bit), generating a backtrace for execution contexts which
have been created with makecontext could fail to terminate due to a
missing .cantunwind annotation. This has been observed to lead to a hang
(denial of service) in some Go applications compiled with gccgo. Reported
by Andreas Schwab. (CVE-2016-6323)
CVE-2019-19126: ld.so failed to ignore the LD_PREFER_MAP_32BIT_EXEC
environment variable during program execution after a security
transition, allowing local attackers to restrict the possible mapping
addresses for loaded libraries and thus bypass ASLR for a setuid
program. Reported by Marcin Kościelnicki.
The following bugs are resolved with this release:
[19679] gcc-4.9.3 C++ exception handling broken due to unaligned stack
[19758] Or bit_Prefer_MAP_32BIT_EXEC in EXTRA_LD_ENVVARS
[19759] Don't inline mempcpy for x86
[19762] Use HAS_ARCH_FEATURE with Fast_Rep_String
[19791] Assertion failure in res_query.c with un-connectable name server
addresses
[19792] MIPS: backtrace yields infinite backtrace with makecontext
[19822] libm.so install clobbers old version
[19879] network: nss_dns: Stack overflow in getnetbyname implementation
(CVE-2016-3075)
[20177] $dp is not initialized correctly in sysdeps/hppa/start.S
[20357] Incorrect cos result for 1.5174239687223976
[21209] Ignore and remove LD_HWCAP_MASK for AT_SECURE programs
[21265] x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve
[21289] Fix symbol redirect for fts_set
[21624] Unsafe alloca allows local attackers to alias stack and heap (CVE-2017-1000366)
[21666] Avoid .symver on common symbols
[22641] x86: Fix mis-merge of XSAVE ld.so trampoline selection
[22715] x86-64: Properly align La_x86_64_retval to VEC_SIZE
[25204] Ignore LD_PREFER_MAP_32BIT_EXEC for SUID programs
Version 2.23
@@ -38,7 +91,7 @@ Version 2.23
unnecessary serialization of memory allocation requests across threads.
The defect is now corrected. Users should see a substantial increase in
the concurent throughput of allocation requests for applications which
trigger this bug. Affected applications typically create create and
trigger this bug. Affected applications typically create and
destroy threads frequently. (Bug 19048 was reported and analyzed by
Ericsson.)
+4 -15
View File
@@ -29,21 +29,6 @@
#include <string.h>
#include <unistd.h>
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || \
defined __STRICT_ANSI__
# define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \
defined __STRICT_ANSI__
# define __format__ format
# define __printf__ printf
# endif
#endif
#if defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)
/* line_wrap_stream is available, so use that. */
#define ARGP_FMTSTREAM_USE_LINEWRAP
@@ -111,6 +96,8 @@ struct argp_fmtstream
typedef struct argp_fmtstream *argp_fmtstream_t;
__BEGIN_DECLS
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
written on it with LMARGIN spaces and limits them to RMARGIN columns
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
@@ -297,6 +284,8 @@ __argp_fmtstream_point (argp_fmtstream_t __fs)
#endif /* __OPTIMIZE__ */
__END_DECLS
#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
#endif /* argp-fmtstream.h */
+2 -40
View File
@@ -28,48 +28,12 @@
#define __need_error_t
#include <errno.h>
#ifndef __THROW
# define __THROW
#endif
#ifndef __NTH
# define __NTH(fct) fct __THROW
#endif
#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || \
defined __STRICT_ANSI__
# define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \
defined __STRICT_ANSI__
# define __format__ format
# define __printf__ printf
# endif
#endif
/* GCC 2.95 and later have "__restrict"; C99 compilers have
"restrict", and "configure" may have defined "restrict". */
#ifndef __restrict
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
# if defined restrict || 199901L <= __STDC_VERSION__
# define __restrict restrict
# else
# define __restrict
# endif
# endif
#endif
#ifndef __error_t_defined
typedef int error_t;
# define __error_t_defined
#endif
#ifdef __cplusplus
extern "C" {
#endif
__BEGIN_DECLS
/* A description of a particular option. A pointer to an array of
these is passed in the OPTIONS field of an argp structure. Each option
@@ -590,8 +554,6 @@ __NTH (__option_is_end (const struct argp_option *__opt))
# endif
#endif /* Use extern inlines. */
#ifdef __cplusplus
}
#endif
__END_DECLS
#endif /* argp.h */
+4 -1
View File
@@ -1,4 +1,4 @@
/* Definition of `struct sockaddr_*' common members. Generic/4.2 BSD version.
/* Definition of struct sockaddr_* common members and sizes, generic version.
Copyright (C) 1995-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -36,4 +36,7 @@ typedef unsigned short int sa_family_t;
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
/* Size of struct sockaddr_storage. */
#define _SS_SIZE 128
#endif /* bits/sockaddr.h */
+4 -4
View File
@@ -152,20 +152,20 @@ struct sockaddr
/* Structure large enough to hold any socket address (with the historical
exception of AF_UNIX). We reserve 128 bytes. */
exception of AF_UNIX). */
#if ULONG_MAX > 0xffffffff
# define __ss_aligntype __uint64_t
#else
# define __ss_aligntype __uint32_t
#endif
#define _SS_SIZE 128
#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
#define _SS_PADSIZE \
(_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype))
struct sockaddr_storage
{
__SOCKADDR_COMMON (ss_); /* Address family, etc. */
__ss_aligntype __ss_align; /* Force desired alignment. */
char __ss_padding[_SS_PADSIZE];
__ss_aligntype __ss_align; /* Force desired alignment. */
};
Vendored
+6 -4
View File
@@ -3864,7 +3864,7 @@ if test -z "$enable_hacker_mode" && test x"$libc_config_ok" != xyes; then
*** The GNU C library is currently unavailable for this platform.
*** If you are interested in seeing glibc on this platform visit
*** the \"How to submit a new port\" in the wiki:
*** https://sourceware.org/glibc/wiki/HomePage#Development
*** https://sourceware.org/glibc/wiki/#Development
*** and join the community!" "$LINENO" 5
;;
esac
@@ -6252,12 +6252,14 @@ echo >&5 "libc_undefs='$libc_undefs'"
# symbols (resolved by the linker), so filter out unknown symbols.
# This will fail to produce the correct result if the compiler
# defaults to -fstack-protector but this produces an undefined symbol
# other than __stack_chk_fail. However, compilers like that have not
# been encountered in practice.
libc_undefs=`echo "$libc_undefs" | egrep '^(foobar|__stack_chk_fail)$'`
# other than __stack_chk_fail or __stack_chk_fail_local. However,
# compilers like that have not been encountered in practice.
libc_undefs=`echo "$libc_undefs" | \
egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'`
case "$libc_undefs" in
foobar) libc_cv_predef_stack_protector=no ;;
'__stack_chk_fail
foobar'|'__stack_chk_fail_local
foobar') libc_cv_predef_stack_protector=yes ;;
*) as_fn_error $? "unexpected symbols in test: $libc_undefs" "$LINENO" 5 ;;
esac
+5 -3
View File
@@ -1603,12 +1603,14 @@ echo >&AS_MESSAGE_LOG_FD "libc_undefs='$libc_undefs'"
# symbols (resolved by the linker), so filter out unknown symbols.
# This will fail to produce the correct result if the compiler
# defaults to -fstack-protector but this produces an undefined symbol
# other than __stack_chk_fail. However, compilers like that have not
# been encountered in practice.
libc_undefs=`echo "$libc_undefs" | egrep '^(foobar|__stack_chk_fail)$'`
# other than __stack_chk_fail or __stack_chk_fail_local. However,
# compilers like that have not been encountered in practice.
libc_undefs=`echo "$libc_undefs" | \
egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'`
case "$libc_undefs" in
foobar) libc_cv_predef_stack_protector=no ;;
'__stack_chk_fail
foobar'|'__stack_chk_fail_local
foobar') libc_cv_predef_stack_protector=yes ;;
*) AC_MSG_ERROR([unexpected symbols in test: $libc_undefs]) ;;
esac],
+6 -1
View File
@@ -163,7 +163,8 @@ endif
endif
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
$(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out
$(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
$(objpfx)tst-ldconfig-X.out
endif
tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@@ -1252,3 +1253,7 @@ $(objpfx)tst-prelink-cmp.out: tst-prelink.exp \
$(objpfx)tst-prelink-conflict.out
cmp $^ > $@; \
$(evaluate-test)
$(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig
$(SHELL) $< '$(common-objpfx)' '$(test-wrapper)' '$(test-wrapper-env)' > $@; \
$(evaluate-test)
+4 -3
View File
@@ -100,7 +100,8 @@ int opt_format = 1;
/* Build cache. */
static int opt_build_cache = 1;
/* Generate links. */
/* Enable symbolic link processing. If set, create or update symbolic
links, and remove stale symbolic links. */
static int opt_link = 1;
/* Only process directories specified on the command line. */
@@ -141,7 +142,7 @@ static const struct argp_option options[] =
{ "print-cache", 'p', NULL, 0, N_("Print cache"), 0},
{ "verbose", 'v', NULL, 0, N_("Generate verbose messages"), 0},
{ NULL, 'N', NULL, 0, N_("Don't build cache"), 0},
{ NULL, 'X', NULL, 0, N_("Don't generate links"), 0},
{ NULL, 'X', NULL, 0, N_("Don't update symbolic links"), 0},
{ NULL, 'r', N_("ROOT"), 0, N_("Change to and use ROOT as root directory"), 0},
{ NULL, 'C', N_("CACHE"), 0, N_("Use CACHE as cache file"), 0},
{ NULL, 'f', N_("CONF"), 0, N_("Use CONF as configuration file"), 0},
@@ -800,7 +801,7 @@ search_dir (const struct dir_entry *entry)
error (0, errno, _("Cannot stat %s"), file_name);
/* Remove stale symlinks. */
if (strstr (direntry->d_name, ".so."))
if (opt_link && strstr (direntry->d_name, ".so."))
unlink (real_file_name);
continue;
}
+165 -33
View File
@@ -99,14 +99,121 @@ uintptr_t __pointer_chk_guard_local
strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
#endif
/* Length limits for names and paths, to protect the dynamic linker,
particularly when __libc_enable_secure is active. */
#ifdef NAME_MAX
# define SECURE_NAME_LIMIT NAME_MAX
#else
# define SECURE_NAME_LIMIT 255
#endif
#ifdef PATH_MAX
# define SECURE_PATH_LIMIT PATH_MAX
#else
# define SECURE_PATH_LIMIT 1024
#endif
/* List of auditing DSOs. */
/* Check that AT_SECURE=0, or that the passed name does not contain
directories and is not overly long. Reject empty names
unconditionally. */
static bool
dso_name_valid_for_suid (const char *p)
{
if (__glibc_unlikely (__libc_enable_secure))
{
/* Ignore pathnames with directories for AT_SECURE=1
programs, and also skip overlong names. */
size_t len = strlen (p);
if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL)
return false;
}
return *p != '\0';
}
/* LD_AUDIT variable contents. Must be processed before the
audit_list below. */
const char *audit_list_string;
/* Cyclic list of auditing DSOs. audit_list->next is the first
element. */
static struct audit_list
{
const char *name;
struct audit_list *next;
} *audit_list;
/* Iterator for audit_list_string followed by audit_list. */
struct audit_list_iter
{
/* Tail of audit_list_string still needing processing, or NULL. */
const char *audit_list_tail;
/* The list element returned in the previous iteration. NULL before
the first element. */
struct audit_list *previous;
/* Scratch buffer for returning a name which is part of
audit_list_string. */
char fname[SECURE_NAME_LIMIT];
};
/* Initialize an audit list iterator. */
static void
audit_list_iter_init (struct audit_list_iter *iter)
{
iter->audit_list_tail = audit_list_string;
iter->previous = NULL;
}
/* Iterate through both audit_list_string and audit_list. */
static const char *
audit_list_iter_next (struct audit_list_iter *iter)
{
if (iter->audit_list_tail != NULL)
{
/* First iterate over audit_list_string. */
while (*iter->audit_list_tail != '\0')
{
/* Split audit list at colon. */
size_t len = strcspn (iter->audit_list_tail, ":");
if (len > 0 && len < sizeof (iter->fname))
{
memcpy (iter->fname, iter->audit_list_tail, len);
iter->fname[len] = '\0';
}
else
/* Do not return this name to the caller. */
iter->fname[0] = '\0';
/* Skip over the substring and the following delimiter. */
iter->audit_list_tail += len;
if (*iter->audit_list_tail == ':')
++iter->audit_list_tail;
/* If the name is valid, return it. */
if (dso_name_valid_for_suid (iter->fname))
return iter->fname;
/* Otherwise, wrap around and try the next name. */
}
/* Fall through to the procesing of audit_list. */
}
if (iter->previous == NULL)
{
if (audit_list == NULL)
/* No pre-parsed audit list. */
return NULL;
/* Start of audit list. The first list element is at
audit_list->next (cyclic list). */
iter->previous = audit_list->next;
return iter->previous->name;
}
if (iter->previous == audit_list)
/* Cyclic list wrap-around. */
return NULL;
iter->previous = iter->previous->next;
return iter->previous->name;
}
#ifndef HAVE_INLINED_SYSCALLS
/* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This
@@ -730,6 +837,42 @@ static const char *preloadlist attribute_relro;
/* Nonzero if information about versions has to be printed. */
static int version_info attribute_relro;
/* The LD_PRELOAD environment variable gives list of libraries
separated by white space or colons that are loaded before the
executable's dependencies and prepended to the global scope list.
(If the binary is running setuid all elements containing a '/' are
ignored since it is insecure.) Return the number of preloads
performed. */
unsigned int
handle_ld_preload (const char *preloadlist, struct link_map *main_map)
{
unsigned int npreloads = 0;
const char *p = preloadlist;
char fname[SECURE_PATH_LIMIT];
while (*p != '\0')
{
/* Split preload list at space/colon. */
size_t len = strcspn (p, " :");
if (len > 0 && len < sizeof (fname))
{
memcpy (fname, p, len);
fname[len] = '\0';
}
else
fname[0] = '\0';
/* Skip over the substring and the following delimiter. */
p += len;
if (*p != '\0')
++p;
if (dso_name_valid_for_suid (fname))
npreloads += do_preload (fname, main_map, "LD_PRELOAD");
}
return npreloads;
}
static void
dl_main (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
@@ -1257,11 +1400,13 @@ of this helper program; chances are you did not intend to run this program.\n\
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
/* If we have auditing DSOs to load, do it now. */
if (__glibc_unlikely (audit_list != NULL))
bool need_security_init = true;
if (__glibc_unlikely (audit_list != NULL)
|| __glibc_unlikely (audit_list_string != NULL))
{
/* Iterate over all entries in the list. The order is important. */
struct audit_ifaces *last_audit = NULL;
struct audit_list *al = audit_list->next;
struct audit_list_iter al_iter;
audit_list_iter_init (&al_iter);
/* Since we start using the auditing DSOs right away we need to
initialize the data structures now. */
@@ -1272,9 +1417,14 @@ of this helper program; chances are you did not intend to run this program.\n\
use different values (especially the pointer guard) and will
fail later on. */
security_init ();
need_security_init = false;
do
while (true)
{
const char *name = audit_list_iter_next (&al_iter);
if (name == NULL)
break;
int tls_idx = GL(dl_tls_max_dtv_idx);
/* Now it is time to determine the layout of the static TLS
@@ -1283,7 +1433,7 @@ of this helper program; chances are you did not intend to run this program.\n\
no DF_STATIC_TLS bit is set. The reason is that we know
glibc will use the static model. */
struct dlmopen_args dlmargs;
dlmargs.fname = al->name;
dlmargs.fname = name;
dlmargs.map = NULL;
const char *objname;
@@ -1296,7 +1446,7 @@ of this helper program; chances are you did not intend to run this program.\n\
not_loaded:
_dl_error_printf ("\
ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
al->name, err_str);
name, err_str);
if (malloced)
free ((char *) err_str);
}
@@ -1400,10 +1550,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
goto not_loaded;
}
}
al = al->next;
}
while (al != audit_list->next);
/* If we have any auditing modules, announce that we already
have two objects loaded. */
@@ -1481,23 +1628,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
if (__glibc_unlikely (preloadlist != NULL))
{
/* The LD_PRELOAD environment variable gives list of libraries
separated by white space or colons that are loaded before the
executable's dependencies and prepended to the global scope
list. If the binary is running setuid all elements
containing a '/' are ignored since it is insecure. */
char *list = strdupa (preloadlist);
char *p;
HP_TIMING_NOW (start);
/* Prevent optimizing strsep. Speed is not important here. */
while ((p = (strsep) (&list, " :")) != NULL)
if (p[0] != '\0'
&& (__builtin_expect (! __libc_enable_secure, 1)
|| strchr (p, '/') == NULL))
npreloads += do_preload (p, main_map, "LD_PRELOAD");
npreloads += handle_ld_preload (preloadlist, main_map);
HP_TIMING_NOW (stop);
HP_TIMING_DIFF (diff, start, stop);
HP_TIMING_ACCUM_NT (load_time, diff);
@@ -1682,7 +1814,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
if (tcbp == NULL)
tcbp = init_tls ();
if (__glibc_likely (audit_list == NULL))
if (__glibc_likely (need_security_init))
/* Initialize security features. But only if we have not done it
earlier. */
security_init ();
@@ -2313,9 +2445,7 @@ process_dl_audit (char *str)
char *p;
while ((p = (strsep) (&str, ":")) != NULL)
if (p[0] != '\0'
&& (__builtin_expect (! __libc_enable_secure, 1)
|| strchr (p, '/') == NULL))
if (dso_name_valid_for_suid (p))
{
/* This is using the local malloc, not the system malloc. The
memory can never be freed. */
@@ -2379,7 +2509,7 @@ process_envvars (enum mode *modep)
break;
}
if (memcmp (envline, "AUDIT", 5) == 0)
process_dl_audit (&envline[6]);
audit_list_string = &envline[6];
break;
case 7:
@@ -2423,7 +2553,8 @@ process_envvars (enum mode *modep)
case 10:
/* Mask for the important hardware capabilities. */
if (memcmp (envline, "HWCAP_MASK", 10) == 0)
if (!__libc_enable_secure
&& memcmp (envline, "HWCAP_MASK", 10) == 0)
GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL,
0, 0);
break;
@@ -2437,7 +2568,8 @@ process_envvars (enum mode *modep)
case 12:
/* The library search path. */
if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
if (!__libc_enable_secure
&& memcmp (envline, "LIBRARY_PATH", 12) == 0)
{
library_path = &envline[13];
break;
+2 -2
View File
@@ -164,11 +164,11 @@ makesymlinks (const char *file)
static int
makesymlink (const char *src, const char *dest)
{
struct stat stats;
struct stat64 stats;
const char *error;
/* Destination must not be a directory. */
if (lstat (dest, &stats) == 0)
if (lstat64 (dest, &stats) == 0)
{
if (S_ISDIR (stats.st_mode))
{
+62
View File
@@ -0,0 +1,62 @@
#!/bin/sh
# Test that ldconfig -X does not remove stale symbolic links.
# Copyright (C) 2000-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/>.
set -ex
common_objpfx=$1
test_wrapper_env=$2
run_program_env=$3
testroot="${common_objpfx}elf/bug19610-test-directory"
cleanup () {
rm -rf "$testroot"
}
trap cleanup 0
rm -rf "$testroot"
mkdir -p $testroot/lib $testroot/etc
# Relative symbolic link target.
ln -s libdoesnotexist.so.1.1 $testroot/lib/libdoesnotexist.so.1
# Absolute symbolic link target.
ln -s $testroot/opt/sw/lib/libdoesnotexist2.so.1.1 $testroot/lib/
errors=0
check_files () {
for name in libdoesnotexist.so.1 libdoesnotexist2.so.1.1 ; do
path="$testroot/lib/$name"
if test ! -h $path ; then
echo "error: missing file: $path"
errors=1
fi
done
}
check_files
${test_wrapper_env} \
${run_program_env} \
${common_objpfx}elf/ldconfig -X -f /dev/null \
-C $testroot/etc/ld.so.cache \
$testroot/lib
check_files
exit $errors
+1 -1
View File
@@ -28,7 +28,7 @@ extra-libs-others = $(extra-libs)
subdir-dirs = nss_hesiod
vpath %.c nss_hesiod
libnss_hesiod-routines := hesiod hesiod-grp hesiod-init hesiod-proto \
libnss_hesiod-routines := hesiod hesiod-grp hesiod-proto \
hesiod-pwd hesiod-service
# Build only shared library
libnss_hesiod-inhibit-o = $(filter-out .os,$(object-suffixes))
+19 -70
View File
@@ -1,6 +1,19 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char rcsid[] = "$BINDId: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie Exp $";
#endif
/* Copyright (C) 1997-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) 1996,1999 by Internet Software Consortium.
@@ -52,18 +65,9 @@ static const char rcsid[] = "$BINDId: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie
/* Forward */
int hesiod_init(void **context);
void hesiod_end(void *context);
char * hesiod_to_bind(void *context, const char *name,
const char *type);
char ** hesiod_resolve(void *context, const char *name,
const char *type);
void hesiod_free_list(void *context, char **list);
static int parse_config_file(struct hesiod_p *ctx, const char *filename);
static char ** get_txt_records(struct hesiod_p *ctx, int class,
const char *name);
static int init(struct hesiod_p *ctx);
/* Public */
@@ -82,7 +86,6 @@ hesiod_init(void **context) {
ctx->LHS = NULL;
ctx->RHS = NULL;
ctx->res = NULL;
/* Set default query classes. */
ctx->classes[0] = C_IN;
ctx->classes[1] = C_HS;
@@ -131,11 +134,6 @@ hesiod_init(void **context) {
goto cleanup;
}
#if 0
if (res_ninit(ctx->res) < 0)
goto cleanup;
#endif
*context = ctx;
return (0);
@@ -152,12 +150,8 @@ hesiod_end(void *context) {
struct hesiod_p *ctx = (struct hesiod_p *) context;
int save_errno = errno;
if (ctx->res)
res_nclose(ctx->res);
free(ctx->RHS);
free(ctx->LHS);
if (ctx->res && ctx->free_res)
(*ctx->free_res)(ctx->res);
free(ctx);
__set_errno(save_errno);
}
@@ -232,10 +226,6 @@ hesiod_resolve(void *context, const char *name, const char *type) {
if (bindname == NULL)
return (NULL);
if (init(ctx) == -1) {
free(bindname);
return (NULL);
}
retvec = get_txt_records(ctx, ctx->classes[0], bindname);
@@ -365,13 +355,13 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
/*
* Construct the query and send it.
*/
n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0,
n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0,
NULL, qbuf, MAX_HESRESP);
if (n < 0) {
__set_errno(EMSGSIZE);
return (NULL);
}
n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP);
n = res_send(qbuf, n, abuf, MAX_HESRESP);
if (n < 0) {
__set_errno(ECONNREFUSED);
return (NULL);
@@ -421,7 +411,7 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
cp += INT16SZ + INT32SZ; /* skip the ttl, too */
rr.dlen = ns_get16(cp);
cp += INT16SZ;
if (cp + rr.dlen > eom) {
if (rr.dlen == 0 || cp + rr.dlen > eom) {
__set_errno(EMSGSIZE);
goto cleanup;
}
@@ -464,44 +454,3 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
free(list);
return (NULL);
}
struct __res_state *
__hesiod_res_get(void *context) {
struct hesiod_p *ctx = context;
if (!ctx->res) {
struct __res_state *res;
res = (struct __res_state *)calloc(1, sizeof *res);
if (res == NULL)
return (NULL);
__hesiod_res_set(ctx, res, free);
}
return (ctx->res);
}
void
__hesiod_res_set(void *context, struct __res_state *res,
void (*free_res)(void *)) {
struct hesiod_p *ctx = context;
if (ctx->res && ctx->free_res) {
res_nclose(ctx->res);
(*ctx->free_res)(ctx->res);
}
ctx->res = res;
ctx->free_res = free_res;
}
static int
init(struct hesiod_p *ctx) {
if (!ctx->res && !__hesiod_res_get(ctx))
return (-1);
if (__res_maybe_init (ctx->res, 0) == -1)
return (-1);
return (0);
}
+22 -12
View File
@@ -1,3 +1,20 @@
/* Copyright (C) 1997-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) 1996,1999 by Internet Software Consortium.
*
@@ -19,22 +36,15 @@
* This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>.
*/
/*
* $BINDId: hesiod.h,v 1.7 1999/01/08 19:22:45 vixie Exp $
*/
#ifndef _HESIOD_H_INCLUDED
#define _HESIOD_H_INCLUDED
int hesiod_init (void **context);
void hesiod_end (void *context);
int hesiod_init (void **context) attribute_hidden;
void hesiod_end (void *context) attribute_hidden;
char * hesiod_to_bind (void *context, const char *name,
const char *type);
const char *type) attribute_hidden;
char ** hesiod_resolve (void *context, const char *name,
const char *type);
void hesiod_free_list (void *context, char **list);
struct __res_state * __hesiod_res_get (void *context);
void __hesiod_res_set (void *context, struct __res_state *,
void (*)(void *));
const char *type) attribute_hidden;
void hesiod_free_list (void *context, char **list) attribute_hidden;
#endif /*_HESIOD_H_INCLUDED*/
+17 -9
View File
@@ -1,3 +1,20 @@
/* Copyright (C) 1997-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) 1996,1999 by Internet Software Consortium.
*
@@ -19,10 +36,6 @@
* This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>.
*/
/*
* $BINDId: hesiod_p.h,v 1.9 1999/01/08 19:24:39 vixie Exp $
*/
/*
* hesiod_p.h -- private definitions for the hesiod library
*/
@@ -36,11 +49,6 @@
struct hesiod_p {
char * LHS; /* normally ".ns" */
char * RHS; /* AKA the default hesiod domain */
struct __res_state * res; /* resolver context */
void (*free_res)(void *);
void (*res_set)(struct hesiod_p *, struct __res_state *,
void (*)(void *));
struct __res_state * (*res_get)(struct hesiod_p *);
int classes[2]; /* The class search order. */
};
+2 -6
View File
@@ -26,8 +26,6 @@
#include <string.h>
#include <sys/param.h>
#include "nss_hesiod.h"
/* Get the declaration of the parser function. */
#define ENTNAME grent
#define STRUCTURE group
@@ -58,8 +56,7 @@ lookup (const char *name, const char *type, struct group *grp,
size_t len;
int olderr = errno;
context = _nss_hesiod_init ();
if (context == NULL)
if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
@@ -179,8 +176,7 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start,
gid_t *groups = *groupsp;
int save_errno;
context = _nss_hesiod_init ();
if (context == NULL)
if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, user, "grplist");
+1 -4
View File
@@ -25,8 +25,6 @@
#include <stdlib.h>
#include <string.h>
#include "nss_hesiod.h"
/* Declare a parser for Hesiod protocol entries. Although the format
of the entries is identical to those in /etc/protocols, here is no
predefined parser for us to use. */
@@ -68,8 +66,7 @@ lookup (const char *name, const char *type, struct protoent *proto,
int found;
int olderr = errno;
context = _nss_hesiod_init ();
if (context == NULL)
if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
+1 -4
View File
@@ -24,8 +24,6 @@
#include <stdlib.h>
#include <string.h>
#include "nss_hesiod.h"
/* Get the declaration of the parser function. */
#define ENTNAME pwent
#define STRUCTURE passwd
@@ -56,8 +54,7 @@ lookup (const char *name, const char *type, struct passwd *pwd,
size_t len;
int olderr = errno;
context = _nss_hesiod_init ();
if (context == NULL)
if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
+1 -4
View File
@@ -25,8 +25,6 @@
#include <stdlib.h>
#include <string.h>
#include "nss_hesiod.h"
/* Hesiod uses a format for service entries that differs from the
traditional format. We therefore declare our own parser. */
@@ -69,8 +67,7 @@ lookup (const char *name, const char *type, const char *protocol,
int found;
int olderr = errno;
context = _nss_hesiod_init ();
if (context == NULL)
if (hesiod_init (&context) < 0)
return NSS_STATUS_UNAVAIL;
list = hesiod_resolve (context, name, type);
+4
View File
@@ -1,6 +1,7 @@
#ifndef _PRINTF_H
#include <stdio-common/printf.h>
#include <xlocale.h>
/* Now define the internal interfaces. */
extern int __printf_fphex (FILE *, const struct printf_info *,
@@ -8,5 +9,8 @@ extern int __printf_fphex (FILE *, const struct printf_info *,
extern int __printf_fp (FILE *, const struct printf_info *,
const void *const *);
libc_hidden_proto (__printf_fp)
extern int __printf_fp_l (FILE *, locale_t, const struct printf_info *,
const void *const *);
libc_hidden_proto (__printf_fp_l)
#endif
+1
View File
@@ -0,0 +1 @@
#include <misc/sys/auxv.h>
+3 -1
View File
@@ -50,7 +50,7 @@ aux := check_pf check_native ifreq
tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
tst-getni1 tst-getni2 tst-inet6_rth tst-checks
tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-sockaddr
include ../Rules
@@ -84,6 +84,8 @@ CFLAGS-either_hton.c = -fexceptions
CFLAGS-getnetgrent.c = -fexceptions
CFLAGS-getnetgrent_r.c = -fexceptions
CFLAGS-tst-sockaddr.c = -fno-strict-aliasing
endif
ifeq ($(build-static-nss),yes)
+346 -252
View File
@@ -1,3 +1,21 @@
/* Convert socket address to string using Name Service Switch modules.
Copyright (C) 1997-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/>. */
/* The Inner Net License, Version 2.00
The author(s) grant permission for redistribution and use in source and
@@ -169,20 +187,322 @@ nrl_domainname (void)
return domain;
};
/* Copy a string to a destination buffer with length checking. Return
EAI_OVERFLOW if the buffer is not large enough, and 0 on
success. */
static int
checked_copy (char *dest, size_t destlen, const char *source)
{
size_t source_length = strlen (source);
if (source_length + 1 > destlen)
return EAI_OVERFLOW;
memcpy (dest, source, source_length + 1);
return 0;
}
/* Helper function for CHECKED_SNPRINTF below. */
static int
check_sprintf_result (int result, size_t destlen)
{
if (result < 0)
return EAI_SYSTEM;
if ((size_t) result >= destlen)
/* If ret == destlen, there was no room for the terminating NUL
character. */
return EAI_OVERFLOW;
return 0;
}
/* Format a string in the destination buffer. Return 0 on success,
EAI_OVERFLOW in case the buffer is too small, or EAI_SYSTEM on any
other error. */
#define CHECKED_SNPRINTF(dest, destlen, format, ...) \
check_sprintf_result \
(__snprintf (dest, destlen, format, __VA_ARGS__), destlen)
/* Convert host name, AF_INET/AF_INET6 case, name only. */
static int
gni_host_inet_name (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *host, socklen_t hostlen, int flags)
{
int herrno;
struct hostent th;
struct hostent *h = NULL;
if (sa->sa_family == AF_INET6)
{
const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa;
while (__gethostbyaddr_r (&sin6p->sin6_addr, sizeof(struct in6_addr),
AF_INET6, &th, tmpbuf->data, tmpbuf->length,
&h, &herrno))
if (herrno == NETDB_INTERNAL && errno == ERANGE)
{
if (!scratch_buffer_grow (tmpbuf))
{
__set_h_errno (herrno);
return EAI_MEMORY;
}
}
else
break;
}
else
{
const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
while (__gethostbyaddr_r (&sinp->sin_addr, sizeof(struct in_addr),
AF_INET, &th, tmpbuf->data, tmpbuf->length,
&h, &herrno))
if (herrno == NETDB_INTERNAL && errno == ERANGE)
{
if (!scratch_buffer_grow (tmpbuf))
{
__set_h_errno (herrno);
return EAI_MEMORY;
}
}
else
break;
}
if (h == NULL)
{
if (herrno == NETDB_INTERNAL)
{
__set_h_errno (herrno);
return EAI_SYSTEM;
}
if (herrno == TRY_AGAIN)
{
__set_h_errno (herrno);
return EAI_AGAIN;
}
}
if (h)
{
char *c;
if ((flags & NI_NOFQDN)
&& (c = nrl_domainname ())
&& (c = strstr (h->h_name, c))
&& (c != h->h_name) && (*(--c) == '.'))
/* Terminate the string after the prefix. */
*c = '\0';
#ifdef HAVE_LIBIDN
/* If requested, convert from the IDN format. */
if (flags & NI_IDN)
{
int idn_flags = 0;
if (flags & NI_IDN_ALLOW_UNASSIGNED)
idn_flags |= IDNA_ALLOW_UNASSIGNED;
if (flags & NI_IDN_USE_STD3_ASCII_RULES)
idn_flags |= IDNA_USE_STD3_ASCII_RULES;
char *out;
int rc = __idna_to_unicode_lzlz (h->h_name, &out,
idn_flags);
if (rc != IDNA_SUCCESS)
{
if (rc == IDNA_MALLOC_ERROR)
return EAI_MEMORY;
if (rc == IDNA_DLOPEN_ERROR)
return EAI_SYSTEM;
return EAI_IDN_ENCODE;
}
if (out != h->h_name)
{
h->h_name = strdupa (out);
free (out);
}
}
#endif
size_t len = strlen (h->h_name) + 1;
if (len > hostlen)
return EAI_OVERFLOW;
memcpy (host, h->h_name, len);
return 0;
}
return EAI_NONAME;
}
/* Convert host name, AF_INET/AF_INET6 case, numeric conversion. */
static int
gni_host_inet_numeric (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *host, socklen_t hostlen, int flags)
{
if (sa->sa_family == AF_INET6)
{
const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa;
if (inet_ntop (AF_INET6, &sin6p->sin6_addr, host, hostlen) == NULL)
return EAI_OVERFLOW;
uint32_t scopeid = sin6p->sin6_scope_id;
if (scopeid != 0)
{
size_t used_hostlen = __strnlen (host, hostlen);
/* Location of the scope string in the host buffer. */
char *scope_start = host + used_hostlen;
size_t scope_length = hostlen - used_hostlen;
if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
|| IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr))
{
char scopebuf[IFNAMSIZ];
if (if_indextoname (scopeid, scopebuf) != NULL)
return CHECKED_SNPRINTF
(scope_start, scope_length,
"%c%s", SCOPE_DELIMITER, scopebuf);
}
return CHECKED_SNPRINTF
(scope_start, scope_length, "%c%u", SCOPE_DELIMITER, scopeid);
}
}
else
{
const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
if (inet_ntop (AF_INET, &sinp->sin_addr, host, hostlen) == NULL)
return EAI_OVERFLOW;
}
return 0;
}
/* Convert AF_INET or AF_INET6 socket address, host part. */
static int
gni_host_inet (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *host, socklen_t hostlen, int flags)
{
if (!(flags & NI_NUMERICHOST))
{
int result = gni_host_inet_name
(tmpbuf, sa, addrlen, host, hostlen, flags);
if (result != EAI_NONAME)
return result;
}
if (flags & NI_NAMEREQD)
return EAI_NONAME;
else
return gni_host_inet_numeric
(tmpbuf, sa, addrlen, host, hostlen, flags);
}
/* Convert AF_LOCAL socket address, host part. */
static int
gni_host_local (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *host, socklen_t hostlen, int flags)
{
if (!(flags & NI_NUMERICHOST))
{
struct utsname utsname;
if (uname (&utsname) == 0)
return checked_copy (host, hostlen, utsname.nodename);
}
if (flags & NI_NAMEREQD)
return EAI_NONAME;
return checked_copy (host, hostlen, "localhost");
}
/* Convert the host part of an AF_LOCAK socket address. */
static int
gni_host (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *host, socklen_t hostlen, int flags)
{
switch (sa->sa_family)
{
case AF_INET:
case AF_INET6:
return gni_host_inet (tmpbuf, sa, addrlen, host, hostlen, flags);
case AF_LOCAL:
return gni_host_local (tmpbuf, sa, addrlen, host, hostlen, flags);
default:
return EAI_FAMILY;
}
}
/* Convert service to string, AF_INET and AF_INET6 variant. */
static int
gni_serv_inet (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *serv, socklen_t servlen, int flags)
{
_Static_assert
(offsetof (struct sockaddr_in, sin_port)
== offsetof (struct sockaddr_in6, sin6_port)
&& sizeof (((struct sockaddr_in) {}).sin_port) == sizeof (in_port_t)
&& sizeof (((struct sockaddr_in6) {}).sin6_port) == sizeof (in_port_t),
"AF_INET and AF_INET6 port consistency");
const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa;
if (!(flags & NI_NUMERICSERV))
{
struct servent *s, ts;
int e;
while ((e = __getservbyport_r (sinp->sin_port,
((flags & NI_DGRAM)
? "udp" : "tcp"), &ts,
tmpbuf->data, tmpbuf->length, &s)))
{
if (e == ERANGE)
{
if (!scratch_buffer_grow (tmpbuf))
return EAI_MEMORY;
}
else
break;
}
if (s)
return checked_copy (serv, servlen, s->s_name);
/* Fall through to numeric conversion. */
}
return CHECKED_SNPRINTF (serv, servlen, "%d", ntohs (sinp->sin_port));
}
/* Convert service to string, AF_LOCAL variant. */
static int
gni_serv_local (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *serv, socklen_t servlen, int flags)
{
return checked_copy
(serv, servlen, ((const struct sockaddr_un *) sa)->sun_path);
}
/* Convert service to string, dispatching to the implementations
above. */
static int
gni_serv (struct scratch_buffer *tmpbuf,
const struct sockaddr *sa, socklen_t addrlen,
char *serv, socklen_t servlen, int flags)
{
switch (sa->sa_family)
{
case AF_INET:
case AF_INET6:
return gni_serv_inet (tmpbuf, sa, addrlen, serv, servlen, flags);
case AF_LOCAL:
return gni_serv_local (tmpbuf, sa, addrlen, serv, servlen, flags);
default:
return EAI_FAMILY;
}
}
int
getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
socklen_t hostlen, char *serv, socklen_t servlen,
int flags)
{
int serrno = errno;
int herrno;
struct hostent th;
int ok = 0;
struct scratch_buffer tmpbuf;
scratch_buffer_init (&tmpbuf);
if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM
#ifdef HAVE_LIBIDN
|NI_IDN|NI_IDN_ALLOW_UNASSIGNED|NI_IDN_USE_STD3_ASCII_RULES
@@ -214,256 +534,30 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
return EAI_FAMILY;
}
struct scratch_buffer tmpbuf;
scratch_buffer_init (&tmpbuf);
if (host != NULL && hostlen > 0)
switch (sa->sa_family)
{
case AF_INET:
case AF_INET6:
if (!(flags & NI_NUMERICHOST))
{
struct hostent *h = NULL;
if (sa->sa_family == AF_INET6)
{
while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr),
sizeof(struct in6_addr),
AF_INET6, &th,
tmpbuf.data, tmpbuf.length,
&h, &herrno))
if (herrno == NETDB_INTERNAL && errno == ERANGE)
{
if (!scratch_buffer_grow (&tmpbuf))
{
__set_h_errno (herrno);
return EAI_MEMORY;
}
}
else
break;
}
else
{
while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr),
sizeof(struct in_addr),
AF_INET, &th,
tmpbuf.data, tmpbuf.length,
&h, &herrno))
if (herrno == NETDB_INTERNAL && errno == ERANGE)
{
if (!scratch_buffer_grow (&tmpbuf))
{
__set_h_errno (herrno);
return EAI_MEMORY;
}
}
else
break;
}
if (h == NULL)
{
if (herrno == NETDB_INTERNAL)
{
__set_h_errno (herrno);
return EAI_SYSTEM;
}
if (herrno == TRY_AGAIN)
{
__set_h_errno (herrno);
return EAI_AGAIN;
}
}
if (h)
{
char *c;
if ((flags & NI_NOFQDN)
&& (c = nrl_domainname ())
&& (c = strstr (h->h_name, c))
&& (c != h->h_name) && (*(--c) == '.'))
/* Terminate the string after the prefix. */
*c = '\0';
#ifdef HAVE_LIBIDN
/* If requested, convert from the IDN format. */
if (flags & NI_IDN)
{
int idn_flags = 0;
if (flags & NI_IDN_ALLOW_UNASSIGNED)
idn_flags |= IDNA_ALLOW_UNASSIGNED;
if (flags & NI_IDN_USE_STD3_ASCII_RULES)
idn_flags |= IDNA_USE_STD3_ASCII_RULES;
char *out;
int rc = __idna_to_unicode_lzlz (h->h_name, &out,
idn_flags);
if (rc != IDNA_SUCCESS)
{
if (rc == IDNA_MALLOC_ERROR)
return EAI_MEMORY;
if (rc == IDNA_DLOPEN_ERROR)
return EAI_SYSTEM;
return EAI_IDN_ENCODE;
}
if (out != h->h_name)
{
h->h_name = strdupa (out);
free (out);
}
}
#endif
size_t len = strlen (h->h_name) + 1;
if (len > hostlen)
return EAI_OVERFLOW;
memcpy (host, h->h_name, len);
ok = 1;
}
}
if (!ok)
{
if (flags & NI_NAMEREQD)
{
__set_errno (serrno);
return EAI_NONAME;
}
else
{
const char *c;
if (sa->sa_family == AF_INET6)
{
const struct sockaddr_in6 *sin6p;
uint32_t scopeid;
sin6p = (const struct sockaddr_in6 *) sa;
c = inet_ntop (AF_INET6,
(const void *) &sin6p->sin6_addr, host, hostlen);
scopeid = sin6p->sin6_scope_id;
if (scopeid != 0)
{
/* Buffer is >= IFNAMSIZ+1. */
char scopebuf[IFNAMSIZ + 1];
char *scopeptr;
int ni_numericscope = 0;
size_t real_hostlen = __strnlen (host, hostlen);
size_t scopelen = 0;
scopebuf[0] = SCOPE_DELIMITER;
scopebuf[1] = '\0';
scopeptr = &scopebuf[1];
if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
|| IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr))
{
if (if_indextoname (scopeid, scopeptr) == NULL)
++ni_numericscope;
else
scopelen = strlen (scopebuf);
}
else
++ni_numericscope;
if (ni_numericscope)
scopelen = 1 + __snprintf (scopeptr,
(scopebuf
+ sizeof scopebuf
- scopeptr),
"%u", scopeid);
if (real_hostlen + scopelen + 1 > hostlen)
/* Signal the buffer is too small. This is
what inet_ntop does. */
c = NULL;
else
memcpy (host + real_hostlen, scopebuf, scopelen + 1);
}
}
else
c = inet_ntop (AF_INET,
(const void *) &(((const struct sockaddr_in *) sa)->sin_addr),
host, hostlen);
if (c == NULL)
return EAI_OVERFLOW;
}
ok = 1;
}
break;
case AF_LOCAL:
if (!(flags & NI_NUMERICHOST))
{
struct utsname utsname;
if (!uname (&utsname))
{
strncpy (host, utsname.nodename, hostlen);
break;
};
};
if (flags & NI_NAMEREQD)
{
__set_errno (serrno);
return EAI_NONAME;
}
strncpy (host, "localhost", hostlen);
break;
default:
return EAI_FAMILY;
{
int result = gni_host (&tmpbuf, sa, addrlen, host, hostlen, flags);
if (result != 0)
{
scratch_buffer_free (&tmpbuf);
return result;
}
}
if (serv && (servlen > 0))
switch (sa->sa_family)
{
case AF_INET:
case AF_INET6:
if (!(flags & NI_NUMERICSERV))
{
struct servent *s, ts;
int e;
while ((e = __getservbyport_r (((const struct sockaddr_in *) sa)->sin_port,
((flags & NI_DGRAM)
? "udp" : "tcp"), &ts,
tmpbuf.data, tmpbuf.length, &s)))
{
if (e == ERANGE)
{
if (!scratch_buffer_grow (&tmpbuf))
return EAI_MEMORY;
}
else
break;
}
if (s)
{
strncpy (serv, s->s_name, servlen);
break;
}
}
if (__snprintf (serv, servlen, "%d",
ntohs (((const struct sockaddr_in *) sa)->sin_port))
+ 1 > servlen)
return EAI_OVERFLOW;
break;
case AF_LOCAL:
strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen);
break;
{
int result = gni_serv (&tmpbuf, sa, addrlen, serv, servlen, flags);
if (result != 0)
{
scratch_buffer_free (&tmpbuf);
return result;
}
}
if (host && (hostlen > 0))
host[hostlen-1] = 0;
if (serv && (servlen > 0))
serv[servlen-1] = 0;
errno = serrno;
scratch_buffer_free (&tmpbuf);
return 0;
}
libc_hidden_def (getnameinfo)
+125
View File
@@ -0,0 +1,125 @@
/* Tests for socket address type definitions.
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; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#include <netinet/in.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
/* This is a copy of the previous definition of struct
sockaddr_storage. It is not equal to the old value of _SS_SIZE
(128) on all architectures. We must stay compatible with the old
definition. */
#define OLD_REFERENCE_SIZE 128
#define OLD_PADSIZE (OLD_REFERENCE_SIZE - (2 * sizeof (__ss_aligntype)))
struct sockaddr_storage_old
{
__SOCKADDR_COMMON (old_);
__ss_aligntype old_align;
char old_padding[OLD_PADSIZE];
};
static bool errors;
static void
check (bool ok, const char *message)
{
if (!ok)
{
printf ("error: failed check: %s\n", message);
errors = true;
}
}
static int
do_test (void)
{
check (OLD_REFERENCE_SIZE >= _SS_SIZE,
"old target size is not smaller than actual size");
check (sizeof (struct sockaddr_storage_old)
== sizeof (struct sockaddr_storage),
"old and new sizes match");
check (__alignof (struct sockaddr_storage_old)
== __alignof (struct sockaddr_storage),
"old and new alignment matches");
check (offsetof (struct sockaddr_storage_old, old_family)
== offsetof (struct sockaddr_storage, ss_family),
"old and new family offsets match");
check (sizeof (struct sockaddr_storage) == _SS_SIZE,
"struct sockaddr_storage size");
/* Check for lack of holes in the struct definition. */
check (offsetof (struct sockaddr_storage, __ss_padding)
== __SOCKADDR_COMMON_SIZE,
"implicit padding before explicit padding");
check (offsetof (struct sockaddr_storage, __ss_align)
== __SOCKADDR_COMMON_SIZE
+ sizeof (((struct sockaddr_storage) {}).__ss_padding),
"implicit padding before explicit padding");
/* Check for POSIX compatibility requirements between struct
sockaddr_storage and struct sockaddr_un. */
check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_un),
"sockaddr_storage is at least as large as sockaddr_un");
check (__alignof (struct sockaddr_storage)
>= __alignof (struct sockaddr_un),
"sockaddr_storage is at least as aligned as sockaddr_un");
check (offsetof (struct sockaddr_storage, ss_family)
== offsetof (struct sockaddr_un, sun_family),
"family offsets match");
/* Check that the compiler preserves bit patterns in aggregate
copies. Based on <https://gcc.gnu.org/PR71120>. */
check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_in),
"sockaddr_storage is at least as large as sockaddr_in");
{
struct sockaddr_storage addr;
memset (&addr, 0, sizeof (addr));
{
struct sockaddr_in *sinp = (struct sockaddr_in *)&addr;
sinp->sin_family = AF_INET;
sinp->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
sinp->sin_port = htons (80);
}
struct sockaddr_storage copy;
copy = addr;
struct sockaddr_storage *p = malloc (sizeof (*p));
if (p == NULL)
{
printf ("error: malloc: %m\n");
return 1;
}
*p = copy;
const struct sockaddr_in *sinp = (const struct sockaddr_in *)p;
check (sinp->sin_family == AF_INET, "sin_family");
check (sinp->sin_addr.s_addr == htonl (INADDR_LOOPBACK), "sin_addr");
check (sinp->sin_port == htons (80), "sin_port");
free (p);
}
return errors;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+1 -1
View File
@@ -193,7 +193,7 @@ FTS *__REDIRECT (fts_open, (char * const *, int,
int (*)(const FTSENT **, const FTSENT **)),
fts64_open);
FTSENT *__REDIRECT (fts_read, (FTS *), fts64_read);
int __REDIRECT (fts_set, (FTS *, FTSENT *, int), fts64_set) __THROW;
int __REDIRECT_NTH (fts_set, (FTS *, FTSENT *, int), fts64_set);
# else
# define fts_children fts64_children
# define fts_close fts64_close
+17 -15
View File
@@ -50,16 +50,14 @@ fmemopen_read (void *cookie, char *b, size_t s)
if (c->pos + s > c->maxpos)
{
if ((size_t) c->pos == c->maxpos)
return 0;
s = c->size - c->pos;
s = c->maxpos - c->pos;
if ((size_t) c->pos > c->maxpos)
s = 0;
}
memcpy (b, &(c->buffer[c->pos]), s);
c->pos += s;
if ((size_t) c->pos > c->maxpos)
c->maxpos = c->pos;
return s;
}
@@ -70,28 +68,29 @@ fmemopen_write (void *cookie, const char *b, size_t s)
{
fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie;;
_IO_off64_t pos = c->append ? c->maxpos : c->pos;
int addnullc;
int addnullc = (s == 0 || b[s - 1] != '\0');
addnullc = (s == 0 || b[s - 1] != '\0');
if (pos + s + addnullc > c->size)
if (pos + s > c->size)
{
if ((size_t) (c->pos + addnullc) >= c->size)
{
__set_errno (ENOSPC);
return 0;
}
s = c->size - pos - addnullc;
s = c->size - pos;
}
memcpy (&(c->buffer[pos]), b, s);
pos += s;
if ((size_t) pos > c->maxpos)
c->pos = pos + s;
if ((size_t) c->pos > c->maxpos)
{
c->maxpos = pos;
if (addnullc)
c->maxpos = c->pos;
if (c->maxpos < c->size && addnullc)
c->buffer[c->maxpos] = '\0';
/* A null byte is written in a stream open for update iff it fits. */
else if (c->append == 0 && addnullc != 0)
c->buffer[c->size-1] = '\0';
}
return s;
@@ -123,7 +122,10 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w)
}
if (np < 0 || (size_t) np > c->size)
return -1;
{
__set_errno (EINVAL);
return -1;
}
*p = c->pos = np;
+35 -14
View File
@@ -43,25 +43,29 @@ static _IO_ssize_t
_IO_cookie_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
cookie_read_function_t *read_cb = cfile->__io_functions.read;
PTR_DEMANGLE (read_cb);
if (cfile->__io_functions.read == NULL)
if (read_cb == NULL)
return -1;
return cfile->__io_functions.read (cfile->__cookie, buf, size);
return read_cb (cfile->__cookie, buf, size);
}
static _IO_ssize_t
_IO_cookie_write (_IO_FILE *fp, const void *buf, _IO_ssize_t size)
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
cookie_write_function_t *write_cb = cfile->__io_functions.write;
PTR_DEMANGLE (write_cb);
if (cfile->__io_functions.write == NULL)
if (write_cb == NULL)
{
fp->_flags |= _IO_ERR_SEEN;
return 0;
}
_IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size);
_IO_ssize_t n = write_cb (cfile->__cookie, buf, size);
if (n < size)
fp->_flags |= _IO_ERR_SEEN;
@@ -72,9 +76,11 @@ static _IO_off64_t
_IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
cookie_seek_function_t *seek_cb = cfile->__io_functions.seek;
PTR_DEMANGLE (seek_cb);
return ((cfile->__io_functions.seek == NULL
|| (cfile->__io_functions.seek (cfile->__cookie, &offset, dir)
return ((seek_cb == NULL
|| (seek_cb (cfile->__cookie, &offset, dir)
== -1)
|| offset == (_IO_off64_t) -1)
? _IO_pos_BAD : offset);
@@ -84,11 +90,13 @@ static int
_IO_cookie_close (_IO_FILE *fp)
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
cookie_close_function_t *close_cb = cfile->__io_functions.close;
PTR_DEMANGLE (close_cb);
if (cfile->__io_functions.close == NULL)
if (close_cb == NULL)
return 0;
return cfile->__io_functions.close (cfile->__cookie);
return close_cb (cfile->__cookie);
}
@@ -126,6 +134,19 @@ static const struct _IO_jump_t _IO_cookie_jumps = {
};
/* Copy the callbacks from SOURCE to *TARGET, with pointer
mangling. */
static void
set_callbacks (_IO_cookie_io_functions_t *target,
_IO_cookie_io_functions_t source)
{
PTR_MANGLE (source.read);
PTR_MANGLE (source.write);
PTR_MANGLE (source.seek);
PTR_MANGLE (source.close);
*target = source;
}
void
_IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
void *cookie, _IO_cookie_io_functions_t io_functions)
@@ -134,7 +155,7 @@ _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
_IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps;
cfile->__cookie = cookie;
cfile->__io_functions = io_functions;
set_callbacks (&cfile->__io_functions, io_functions);
_IO_file_init (&cfile->__fp);
@@ -205,14 +226,14 @@ attribute_compat_text_section
_IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
{
struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
int (*seek) (_IO_FILE *, _IO_off_t, int);
int ret;
int (*seek_cb) (_IO_FILE *, _IO_off_t, int)
= (int (*) (_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;;
PTR_DEMANGLE (seek_cb);
seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;
if (seek == NULL)
if (seek_cb == NULL)
return _IO_pos_BAD;
ret = seek (cfile->__cookie, offset, dir);
int ret = seek_cb (cfile->__cookie, offset, dir);
return (ret == -1) ? _IO_pos_BAD : ret;
}
+21
View File
@@ -299,6 +299,27 @@ extern __thread struct __locale_data *const *_nl_current_##category \
#endif
/* Extract CATEGORY locale's string for ITEM. */
static inline const char *
_nl_lookup (locale_t l, int category, int item)
{
return l->__locales[category]->values[_NL_ITEM_INDEX (item)].string;
}
/* Extract CATEGORY locale's wide string for ITEM. */
static inline const wchar_t *
_nl_lookup_wstr (locale_t l, int category, int item)
{
return (wchar_t *) l->__locales[category]
->values[_NL_ITEM_INDEX (item)].wstr;
}
/* Extract the CATEGORY locale's word for ITEM. */
static inline uint32_t
_nl_lookup_word (locale_t l, int category, int item)
{
return l->__locales[category]->values[_NL_ITEM_INDEX (item)].word;
}
/* Default search path if no LOCPATH environment variable. */
extern const char _nl_default_locale_path[] attribute_hidden;
+21
View File
@@ -1,3 +1,24 @@
2017-06-11 Santhosh Thottingal <santhosh.thottingal@gmail.com>
[BZ #19922]
* locales/iso14651_t1_common: Add collation rules for U+07DA to U+07DF.
[BZ #19919]
* locales/iso14651_t1_common: Correct collation of U+0D36 and U+0D37.
2016-12-30 Mike Frysinger <vapier@gentoo.org>
[BZ #20974]
* localedata/bs_BA (LC_MESSAGES): Delete "*." from the end of
yesexpr and noexpr.
2016-02-19 Florian Weimer <fweimer@redhat.com>
[BZ #19581]
* locales/sr_ME (date_fmt): Remove newline.
* locales/sr_RS (date_fmt): Likewise.
* locales/sr_RS@latin (date_fmt): Likewise.
2016-02-08 Mike Frysinger <vapier@gentoo.org>
* locales/an_ES: Convert to UTF-8 encodings.
+2 -2
View File
@@ -144,8 +144,8 @@ copy "en_DK"
END LC_CTYPE
LC_MESSAGES
yesexpr "<U005E><U005B><U0064><U0044><U0079><U0059><U005D><U002A><U002E>"
noexpr "<U005E><U005B><U006E><U004E><U005D><U002A><U002E>"
yesexpr "<U005E><U005B><U0064><U0044><U0079><U0059><U005D>"
noexpr "<U005E><U005B><U006E><U004E><U005D>"
END LC_MESSAGES
LC_MONETARY
+22 -4
View File
@@ -1035,9 +1035,9 @@ collating-element <ml-bh> from "<U0D2D><U0D4D>"
collating-element <ml-m> from "<U0D2E><U0D4D>"
collating-element <ml-y> from "<U0D2F><U0D4D>"
collating-element <ml-v> from "<U0D35><U0D4D>"
collating-element <ml-s> from "<U0D38><U0D4D>"
collating-element <ml-ss> from "<U0D36><U0D4D>"
collating-element <ml-sh> from "<U0D37><U0D4D>"
collating-element <ml-s> from "<U0D38><U0D4D>"
collating-element <ml-h> from "<U0D39><U0D4D>"
collating-element <ml-zh> from "<U0D34><U0D4D>"
collating-element <ml-rr> from "<U0D31><U0D4D>"
@@ -1096,8 +1096,8 @@ collating-symbol <ml-rra>
collating-symbol <ml-la>
collating-symbol <ml-lla>
collating-symbol <ml-va>
collating-symbol <ml-sha>
collating-symbol <ml-ssa>
collating-symbol <ml-sha>
collating-symbol <ml-sa>
collating-symbol <ml-ha>
collating-symbol <ml-avagrah>
@@ -1119,6 +1119,12 @@ collating-symbol <mlvs-o>
collating-symbol <mlvs-au>
collating-symbol <ml-visarga>
collating-symbol <ml-virama>
collating-symbol <ml-atomic-chillu-k>
collating-symbol <ml-atomic-chillu-n>
collating-symbol <ml-atomic-chillu-nn>
collating-symbol <ml-atomic-chillu-l>
collating-symbol <ml-atomic-chillu-ll>
collating-symbol <ml-atomic-chillu-r>
#
# <BENGALI>
#
@@ -4545,6 +4551,12 @@ collating-symbol <TIB-subA>
<mlvs-o>
<mlvs-au>
<ml-visarga>
<ml-atomic-chillu-k>
<ml-atomic-chillu-n>
<ml-atomic-chillu-nn>
<ml-atomic-chillu-l>
<ml-atomic-chillu-ll>
<ml-atomic-chillu-r>
#
# <BENGALI>
#
@@ -7245,6 +7257,7 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<U0D13> <mlvw-o>;<BAS>;<MIN>;IGNORE
<U0D14> <mlvw-au>;<BAS>;<MIN>;IGNORE
<ml-chillu-k> "<ml-ka><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D7F> "<ml-ka><ml-virama>";<ml-atomic-chillu-k>;<MIN>;IGNORE
<U0D15> "<ml-ka><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-kh> "<ml-kha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D16> "<ml-kha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
@@ -7273,6 +7286,7 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<ml-dh> "<ml-dha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D22> "<ml-dha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-nn> "<ml-nna><ml-virama>";<BAS>;<MIN>;IGNORE # ണ്‍ = ണ + ് + zwj
<U0D7A> "<ml-nna><ml-virama>";<ml-atomic-chillu-nn>;<MIN>;IGNORE
<U0D23> "<ml-nna><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ണ = ണ + ് + അ
<ml-th> "<ml-tha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D24> "<ml-tha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
@@ -7283,6 +7297,7 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<ml-ddh> "<ml-ddha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D27> "<ml-ddha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-n> "<ml-na><ml-virama>";<BAS>;<MIN>;IGNORE # ന്‍= ന + ് + zwj
<U0D7B> "<ml-na><ml-virama>";<ml-atomic-chillu-n>;<MIN>;IGNORE
<U0D28> "<ml-na><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE #ന = ന + ് + അ
<ml-p> "<ml-pa><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D2A> "<ml-pa><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
@@ -7298,20 +7313,23 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<ml-y> "<ml-ya><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D2F> "<ml-ya><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-r> "<ml-ra><ml-virama>";<BAS>;<MIN>;IGNORE # ര = ര + ് + zwj
<U0D7C> "<ml-ra><ml-virama>";<ml-atomic-chillu-r>;<MIN>;IGNORE
<U0D30> "<ml-ra><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ര = ര + ് + അ
<ml-chillu-l> <ml-la>;<BAS>;<MIN>;IGNORE # ല്‍ = ല + ് + zwj
<U0D7D> "<ml-la><ml-virama>";<ml-atomic-chillu-l>;<MIN>;IGNORE
<U0D32> "<ml-la><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ല = ല + ് + അ
<ml-v> "<ml-va><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D35> "<ml-va><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-ss> "<ml-ssa><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D37> "<ml-ssa><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<U0D36> "<ml-ssa><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-sh> "<ml-sha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D36> "<ml-sha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<U0D37> "<ml-sha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-s> "<ml-sa><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D38> "<ml-sa><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-h> "<ml-ha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D39> "<ml-ha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-ll> "<ml-lla><ml-virama>";<BAS>;<MIN>;IGNORE # ള്‍ = ള + ് + zwj
<U0D7E> "<ml-lla><ml-virama>";<ml-atomic-chillu-ll>;<MIN>;IGNORE
<U0D33> "<ml-lla><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ള = ള + ് + അ
<ml-zh> "<ml-zha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D34> "<ml-zha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
+1 -1
View File
@@ -119,7 +119,7 @@ am_pm "";""
t_fmt_ampm "<U0025><U0054>"
date_fmt "<U0025><U0061><U002c><U0020><U0025><U0065><U002E><U0020>/
<U0025><U0062><U0020><U0025><U0059><U002E><U0020><U0020><U0025><U0048>/
<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U000A>"
<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
week 7;19971130;4
first_weekday 2
first_workday 2
+1 -1
View File
@@ -300,7 +300,7 @@ am_pm "";""
t_fmt_ampm "<U0025><U0054>"
date_fmt "<U0025><U0061><U002C><U0020><U0025><U0065><U002E><U0020>/
<U0025><U0062><U0020><U0025><U0059><U002E><U0020><U0020><U0025><U0048>/
<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U000A>"
<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
week 7;19971130;4
first_weekday 2
first_workday 2
+1 -1
View File
@@ -120,7 +120,7 @@ am_pm "";""
t_fmt_ampm "<U0025><U0054>"
date_fmt "<U0025><U0061><U002c><U0020><U0025><U0065><U002E><U0020>/
<U0025><U0062><U0020><U0025><U0059><U002E><U0020><U0020><U0025><U0048>/
<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U000A>"
<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
week 7;19971130;4
first_weekday 2
first_workday 2
+6 -7
View File
@@ -29,7 +29,8 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc-usable tst-realloc tst-posix_memalign \
tst-pvalloc tst-memalign tst-mallopt tst-scratch_buffer \
tst-malloc-backtrace tst-malloc-thread-exit \
tst-malloc-thread-fail
tst-malloc-thread-fail tst-malloc-fork-deadlock \
tst-mallocfork2
test-srcs = tst-mtrace
routines = malloc morecore mcheck mtrace obstack \
@@ -46,12 +47,10 @@ extra-libs-others = $(extra-libs)
libmemusage-routines = memusage
libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
$(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \
$(common-objpfx)nptl/libpthread_nonshared.a
$(objpfx)tst-malloc-thread-exit: $(common-objpfx)nptl/libpthread.so \
$(common-objpfx)nptl/libpthread_nonshared.a
$(objpfx)tst-malloc-thread-fail: $(common-objpfx)nptl/libpthread.so \
$(common-objpfx)nptl/libpthread_nonshared.a
$(objpfx)tst-malloc-backtrace: $(shared-thread-library)
$(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
$(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
$(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
# These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a
+65 -169
View File
@@ -130,149 +130,43 @@ int __malloc_initialized = -1;
/**************************************************************************/
#ifndef NO_THREADS
/* atfork support. */
static void *(*save_malloc_hook)(size_t __size, const void *);
static void (*save_free_hook) (void *__ptr, const void *);
static void *save_arena;
/* The following three functions are called around fork from a
multi-threaded process. We do not use the general fork handler
mechanism to make sure that our handlers are the last ones being
called, so that other fork handlers can use the malloc
subsystem. */
# ifdef ATFORK_MEM
ATFORK_MEM;
# endif
/* Magic value for the thread-specific arena pointer when
malloc_atfork() is in use. */
# define ATFORK_ARENA_PTR ((void *) -1)
/* The following hooks are used while the `atfork' handling mechanism
is active. */
static void *
malloc_atfork (size_t sz, const void *caller)
void
internal_function
__malloc_fork_lock_parent (void)
{
void *victim;
if (thread_arena == ATFORK_ARENA_PTR)
{
/* We are the only thread that may allocate at all. */
if (save_malloc_hook != malloc_check)
{
return _int_malloc (&main_arena, sz);
}
else
{
if (top_check () < 0)
return 0;
victim = _int_malloc (&main_arena, sz + 1);
return mem2mem_check (victim, sz);
}
}
else
{
/* Suspend the thread until the `atfork' handlers have completed.
By that time, the hooks will have been reset as well, so that
mALLOc() can be used again. */
(void) mutex_lock (&list_lock);
(void) mutex_unlock (&list_lock);
return __libc_malloc (sz);
}
}
static void
free_atfork (void *mem, const void *caller)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
if (mem == 0) /* free(0) has no effect */
return;
p = mem2chunk (mem); /* do not bother to replicate free_check here */
if (chunk_is_mmapped (p)) /* release mmapped memory. */
{
munmap_chunk (p);
return;
}
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, thread_arena == ATFORK_ARENA_PTR);
}
/* Counter for number of times the list is locked by the same thread. */
static unsigned int atfork_recursive_cntr;
/* The following two functions are registered via thread_atfork() to
make sure that the mutexes remain in a consistent state in the
fork()ed version of a thread. Also adapt the malloc and free hooks
temporarily, because the `atfork' handler mechanism may use
malloc/free internally (e.g. in LinuxThreads). */
static void
ptmalloc_lock_all (void)
{
mstate ar_ptr;
if (__malloc_initialized < 1)
return;
/* We do not acquire free_list_lock here because we completely
reconstruct free_list in ptmalloc_unlock_all2. */
reconstruct free_list in __malloc_fork_unlock_child. */
if (mutex_trylock (&list_lock))
{
if (thread_arena == ATFORK_ARENA_PTR)
/* This is the same thread which already locks the global list.
Just bump the counter. */
goto out;
(void) mutex_lock (&list_lock);
/* This thread has to wait its turn. */
(void) mutex_lock (&list_lock);
}
for (ar_ptr = &main_arena;; )
for (mstate ar_ptr = &main_arena;; )
{
(void) mutex_lock (&ar_ptr->mutex);
ar_ptr = ar_ptr->next;
if (ar_ptr == &main_arena)
break;
}
save_malloc_hook = __malloc_hook;
save_free_hook = __free_hook;
__malloc_hook = malloc_atfork;
__free_hook = free_atfork;
/* Only the current thread may perform malloc/free calls now.
save_arena will be reattached to the current thread, in
ptmalloc_lock_all, so save_arena->attached_threads is not
updated. */
save_arena = thread_arena;
thread_arena = ATFORK_ARENA_PTR;
out:
++atfork_recursive_cntr;
}
static void
ptmalloc_unlock_all (void)
void
internal_function
__malloc_fork_unlock_parent (void)
{
mstate ar_ptr;
if (__malloc_initialized < 1)
return;
if (--atfork_recursive_cntr != 0)
return;
/* Replace ATFORK_ARENA_PTR with save_arena.
save_arena->attached_threads was not changed in ptmalloc_lock_all
and is still correct. */
thread_arena = save_arena;
__malloc_hook = save_malloc_hook;
__free_hook = save_free_hook;
for (ar_ptr = &main_arena;; )
for (mstate ar_ptr = &main_arena;; )
{
(void) mutex_unlock (&ar_ptr->mutex);
ar_ptr = ar_ptr->next;
@@ -282,35 +176,23 @@ ptmalloc_unlock_all (void)
(void) mutex_unlock (&list_lock);
}
# ifdef __linux__
/* In NPTL, unlocking a mutex in the child process after a
fork() is currently unsafe, whereas re-initializing it is safe and
does not leak resources. Therefore, a special atfork handler is
installed for the child. */
static void
ptmalloc_unlock_all2 (void)
void
internal_function
__malloc_fork_unlock_child (void)
{
mstate ar_ptr;
if (__malloc_initialized < 1)
return;
thread_arena = save_arena;
__malloc_hook = save_malloc_hook;
__free_hook = save_free_hook;
/* Push all arenas to the free list, except save_arena, which is
/* Push all arenas to the free list, except thread_arena, which is
attached to the current thread. */
mutex_init (&free_list_lock);
if (save_arena != NULL)
((mstate) save_arena)->attached_threads = 1;
if (thread_arena != NULL)
thread_arena->attached_threads = 1;
free_list = NULL;
for (ar_ptr = &main_arena;; )
for (mstate ar_ptr = &main_arena;; )
{
mutex_init (&ar_ptr->mutex);
if (ar_ptr != save_arena)
if (ar_ptr != thread_arena)
{
/* This arena is no longer attached to any thread. */
ar_ptr->attached_threads = 0;
@@ -323,15 +205,8 @@ ptmalloc_unlock_all2 (void)
}
mutex_init (&list_lock);
atfork_recursive_cntr = 0;
}
# else
# define ptmalloc_unlock_all2 ptmalloc_unlock_all
# endif
#endif /* !NO_THREADS */
/* Initialization routine. */
#include <string.h>
extern char **_environ;
@@ -400,7 +275,6 @@ ptmalloc_init (void)
#endif
thread_arena = &main_arena;
thread_atfork (ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
const char *s = NULL;
if (__glibc_likely (_environ != NULL))
{
@@ -475,14 +349,6 @@ ptmalloc_init (void)
__malloc_initialized = 1;
}
/* There are platforms (e.g. Hurd) with a link-time hook mechanism. */
#ifdef thread_atfork_static
thread_atfork_static (ptmalloc_lock_all, ptmalloc_unlock_all, \
ptmalloc_unlock_all2)
#endif
/* Managing heaps and arenas (for concurrent threads) */
#if MALLOC_DEBUG > 1
@@ -831,7 +697,8 @@ _int_new_arena (size_t size)
limit is reached). At this point, some arena has to be attached
to two threads. We could acquire the arena lock before list_lock
to make it less likely that reused_arena picks this new arena,
but this could result in a deadlock with ptmalloc_lock_all. */
but this could result in a deadlock with
__malloc_fork_lock_parent. */
(void) mutex_lock (&a->mutex);
@@ -839,8 +706,7 @@ _int_new_arena (size_t size)
}
/* Remove an arena from free_list. The arena may be in use because it
was attached concurrently to a thread by reused_arena below. */
/* Remove an arena from free_list. */
static mstate
get_free_list (void)
{
@@ -855,7 +721,8 @@ get_free_list (void)
free_list = result->next_free;
/* The arena will be attached to this thread. */
++result->attached_threads;
assert (result->attached_threads == 0);
result->attached_threads = 1;
detach_arena (replaced_arena);
}
@@ -872,6 +739,26 @@ get_free_list (void)
return result;
}
/* Remove the arena from the free list (if it is present).
free_list_lock must have been acquired by the caller. */
static void
remove_from_free_list (mstate arena)
{
mstate *previous = &free_list;
for (mstate p = free_list; p != NULL; p = p->next_free)
{
assert (p->attached_threads == 0);
if (p == arena)
{
/* Remove the requested arena from the list. */
*previous = p->next_free;
break;
}
else
previous = &p->next_free;
}
}
/* Lock and return an arena that can be reused for memory allocation.
Avoid AVOID_ARENA as we have already failed to allocate memory in
it and it is currently locked. */
@@ -908,27 +795,36 @@ reused_arena (mstate avoid_arena)
{
result = result->next;
if (result == begin)
break;
/* We looped around the arena list. We could not find any
arena that was either not corrupted or not the one we
wanted to avoid. */
return NULL;
}
/* We could not find any arena that was either not corrupted or not the one
we wanted to avoid. */
if (result == begin || result == avoid_arena)
return NULL;
/* No arena available without contention. Wait for the next in line. */
LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena);
(void) mutex_lock (&result->mutex);
out:
/* Attach the arena to the current thread. Note that we may have
selected an arena which was on free_list. */
/* Attach the arena to the current thread. */
{
/* Update the arena thread attachment counters. */
mstate replaced_arena = thread_arena;
(void) mutex_lock (&free_list_lock);
detach_arena (replaced_arena);
/* We may have picked up an arena on the free list. We need to
preserve the invariant that no arena on the free list has a
positive attached_threads counter (otherwise,
arena_thread_freeres cannot use the counter to determine if the
arena needs to be put on the free list). We unconditionally
remove the selected arena from the free list. The caller of
reused_arena checked the free list and observed it to be empty,
so the list is very short. */
remove_from_free_list (result);
++result->attached_threads;
(void) mutex_unlock (&free_list_lock);
}
+32
View File
@@ -0,0 +1,32 @@
/* Internal declarations for malloc, for use within libc.
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; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#ifndef _MALLOC_PRIVATE_H
#define _MALLOC_PRIVATE_H
/* Called in the parent process before a fork. */
void __malloc_fork_lock_parent (void) internal_function attribute_hidden;
/* Called in the parent process after a fork. */
void __malloc_fork_unlock_parent (void) internal_function attribute_hidden;
/* Called in the child process after a fork. */
void __malloc_fork_unlock_child (void) internal_function attribute_hidden;
#endif /* _MALLOC_PRIVATE_H */
+1 -4
View File
@@ -244,6 +244,7 @@
/* For ALIGN_UP et. al. */
#include <libc-internal.h>
#include <malloc/malloc-internal.h>
/*
Debugging:
@@ -1074,10 +1075,6 @@ static void* realloc_check(void* oldmem, size_t bytes,
const void *caller);
static void* memalign_check(size_t alignment, size_t bytes,
const void *caller);
#ifndef NO_THREADS
static void* malloc_atfork(size_t sz, const void *caller);
static void free_atfork(void* mem, const void *caller);
#endif
/* ------------------ MMAP support ------------------ */
+220
View File
@@ -0,0 +1,220 @@
/* Test concurrent fork, getline, and fflush (NULL).
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; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
#include <signal.h>
static int do_test (void);
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
enum {
/* Number of threads which call fork. */
fork_thread_count = 4,
/* Number of threads which call getline (and, indirectly,
malloc). */
read_thread_count = 8,
};
static bool termination_requested;
static void *
fork_thread_function (void *closure)
{
while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
{
pid_t pid = fork ();
if (pid < 0)
{
printf ("error: fork: %m\n");
abort ();
}
else if (pid == 0)
_exit (17);
int status;
if (waitpid (pid, &status, 0) < 0)
{
printf ("error: waitpid: %m\n");
abort ();
}
if (!WIFEXITED (status) || WEXITSTATUS (status) != 17)
{
printf ("error: waitpid returned invalid status: %d\n", status);
abort ();
}
}
return NULL;
}
static char *file_to_read;
static void *
read_thread_function (void *closure)
{
FILE *f = fopen (file_to_read, "r");
if (f == NULL)
{
printf ("error: fopen (%s): %m\n", file_to_read);
abort ();
}
while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
{
rewind (f);
char *line = NULL;
size_t line_allocated = 0;
ssize_t ret = getline (&line, &line_allocated, f);
if (ret < 0)
{
printf ("error: getline: %m\n");
abort ();
}
free (line);
}
fclose (f);
return NULL;
}
static void *
flushall_thread_function (void *closure)
{
while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
if (fflush (NULL) != 0)
{
printf ("error: fflush (NULL): %m\n");
abort ();
}
return NULL;
}
static void
create_threads (pthread_t *threads, size_t count, void *(*func) (void *))
{
for (size_t i = 0; i < count; ++i)
{
int ret = pthread_create (threads + i, NULL, func, NULL);
if (ret != 0)
{
errno = ret;
printf ("error: pthread_create: %m\n");
abort ();
}
}
}
static void
join_threads (pthread_t *threads, size_t count)
{
for (size_t i = 0; i < count; ++i)
{
int ret = pthread_join (threads[i], NULL);
if (ret != 0)
{
errno = ret;
printf ("error: pthread_join: %m\n");
abort ();
}
}
}
/* Create a file which consists of a single long line, and assigns
file_to_read. The hope is that this triggers an allocation in
getline which needs a lock. */
static void
create_file_with_large_line (void)
{
int fd = create_temp_file ("bug19431-large-line", &file_to_read);
if (fd < 0)
{
printf ("error: create_temp_file: %m\n");
abort ();
}
FILE *f = fdopen (fd, "w+");
if (f == NULL)
{
printf ("error: fdopen: %m\n");
abort ();
}
for (int i = 0; i < 50000; ++i)
fputc ('x', f);
fputc ('\n', f);
if (ferror (f))
{
printf ("error: fputc: %m\n");
abort ();
}
if (fclose (f) != 0)
{
printf ("error: fclose: %m\n");
abort ();
}
}
static int
do_test (void)
{
/* Make sure that we do not exceed the arena limit with the number
of threads we configured. */
if (mallopt (M_ARENA_MAX, 400) == 0)
{
printf ("error: mallopt (M_ARENA_MAX) failed\n");
return 1;
}
/* Leave some room for shutting down all threads gracefully. */
int timeout = 3;
if (timeout > TIMEOUT)
timeout = TIMEOUT - 1;
create_file_with_large_line ();
pthread_t fork_threads[fork_thread_count];
create_threads (fork_threads, fork_thread_count, fork_thread_function);
pthread_t read_threads[read_thread_count];
create_threads (read_threads, read_thread_count, read_thread_function);
pthread_t flushall_threads[1];
create_threads (flushall_threads, 1, flushall_thread_function);
struct timespec ts = {timeout, 0};
if (nanosleep (&ts, NULL))
{
printf ("error: error: nanosleep: %m\n");
abort ();
}
__atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED);
join_threads (flushall_threads, 1);
join_threads (read_threads, read_thread_count);
join_threads (fork_threads, fork_thread_count);
free (file_to_read);
return 0;
}
+220
View File
@@ -0,0 +1,220 @@
/* Test case for async-signal-safe fork (with respect to malloc).
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; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
/* This test will fail if the process is multi-threaded because we
only have an async-signal-safe fork in the single-threaded case
(where we skip acquiring the malloc heap locks).
This test only checks async-signal-safety with regards to malloc;
other, more rarely-used glibc subsystems could have locks which
still make fork unsafe, even in single-threaded processes. */
#include <errno.h>
#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
/* How many malloc objects to keep arond. */
enum { malloc_objects = 1009 };
/* The maximum size of an object. */
enum { malloc_maximum_size = 70000 };
/* How many signals need to be delivered before the test exits. */
enum { signal_count = 1000 };
/* Process ID of the subprocess which sends SIGUSR1 signals. */
static pid_t sigusr1_sender_pid;
/* Set to 1 if SIGUSR1 is received. Used to detect a signal during
malloc/free. */
static volatile sig_atomic_t sigusr1_received;
/* Periodically set to 1, to indicate that the process is making
progress. Checked by liveness_signal_handler. */
static volatile sig_atomic_t progress_indicator = 1;
/* Write the message to standard output. Usable from signal
handlers. */
static void
write_message (const char *str)
{
write (STDOUT_FILENO, str, strlen (str));
}
static void
sigusr1_handler (int signo)
{
/* Let the main program make progress, by temporarily suspending
signals from the subprocess. */
if (sigusr1_received)
return;
/* sigusr1_sender_pid might not be initialized in the parent when
the first SIGUSR1 signal arrives. */
if (sigusr1_sender_pid > 0 && kill (sigusr1_sender_pid, SIGSTOP) != 0)
{
write_message ("error: kill (SIGSTOP)\n");
abort ();
}
sigusr1_received = 1;
/* Perform a fork with a trivial subprocess. */
pid_t pid = fork ();
if (pid == -1)
{
write_message ("error: fork\n");
abort ();
}
if (pid == 0)
_exit (0);
int status;
int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
if (ret < 0)
{
write_message ("error: waitpid\n");
abort ();
}
if (status != 0)
{
write_message ("error: unexpected exit status from subprocess\n");
abort ();
}
}
static void
liveness_signal_handler (int signo)
{
if (progress_indicator)
progress_indicator = 0;
else
write_message ("warning: process seems to be stuck\n");
}
static void
__attribute__ ((noreturn))
signal_sender (int signo, bool sleep)
{
pid_t target = getppid ();
while (true)
{
if (kill (target, signo) != 0)
{
dprintf (STDOUT_FILENO, "error: kill: %m\n");
abort ();
}
if (sleep)
usleep (1 * 1000 * 1000);
else
/* Reduce the rate at which we send signals. */
sched_yield ();
}
}
static int
do_test (void)
{
struct sigaction action =
{
.sa_handler = sigusr1_handler,
};
sigemptyset (&action.sa_mask);
if (sigaction (SIGUSR1, &action, NULL) != 0)
{
printf ("error: sigaction: %m");
return 1;
}
action.sa_handler = liveness_signal_handler;
if (sigaction (SIGUSR2, &action, NULL) != 0)
{
printf ("error: sigaction: %m");
return 1;
}
pid_t sigusr2_sender_pid = fork ();
if (sigusr2_sender_pid == 0)
signal_sender (SIGUSR2, true);
sigusr1_sender_pid = fork ();
if (sigusr1_sender_pid == 0)
signal_sender (SIGUSR1, false);
void *objects[malloc_objects] = {};
unsigned signals = 0;
unsigned seed = 1;
time_t last_report = 0;
while (signals < signal_count)
{
progress_indicator = 1;
int slot = rand_r (&seed) % malloc_objects;
size_t size = rand_r (&seed) % malloc_maximum_size;
if (kill (sigusr1_sender_pid, SIGCONT) != 0)
{
printf ("error: kill (SIGCONT): %m\n");
signal (SIGUSR1, SIG_IGN);
kill (sigusr1_sender_pid, SIGKILL);
kill (sigusr2_sender_pid, SIGKILL);
return 1;
}
sigusr1_received = false;
free (objects[slot]);
objects[slot] = malloc (size);
if (sigusr1_received)
{
++signals;
time_t current = time (0);
if (current != last_report)
{
printf ("info: SIGUSR1 signal count: %u\n", signals);
last_report = current;
}
}
if (objects[slot] == NULL)
{
printf ("error: malloc: %m\n");
signal (SIGUSR1, SIG_IGN);
kill (sigusr1_sender_pid, SIGKILL);
kill (sigusr2_sender_pid, SIGKILL);
return 1;
}
}
/* Clean up allocations. */
for (int slot = 0; slot < malloc_objects; ++slot)
free (objects[slot]);
/* Terminate the signal-sending subprocess. The SIGUSR1 handler
should no longer run because it uses sigusr1_sender_pid. */
signal (SIGUSR1, SIG_IGN);
kill (sigusr1_sender_pid, SIGKILL);
kill (sigusr2_sender_pid, SIGKILL);
return 0;
}
#define TIMEOUT 20
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+42
View File
@@ -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 <dirent.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
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;
}
-8
View File
@@ -1051,14 +1051,6 @@ systems that do not support @w{ISO C11}.
@c _dl_addr_inside_object ok
@c determine_info ok
@c __rtld_lock_unlock_recursive (dl_load_lock) @aculock
@c thread_atfork @asulock @aculock @acsfd @acsmem
@c __register_atfork @asulock @aculock @acsfd @acsmem
@c lll_lock (__fork_lock) @asulock @aculock
@c fork_handler_alloc @asulock @aculock @acsfd @acsmem
@c calloc dup @asulock @aculock @acsfd @acsmem
@c __linkin_atfork ok
@c catomic_compare_and_exchange_bool_acq ok
@c lll_unlock (__fork_lock) @aculock
@c *_environ @mtsenv
@c next_env_entry ok
@c strcspn dup ok
+38 -1
View File
@@ -237,7 +237,44 @@ function used to read the contents of a directory. It is used if the
@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}
+2 -1
View File
@@ -100,7 +100,8 @@ $(inst_libdir)/libm.so: $(common-objpfx)format.lds \
cat $<; \
echo 'GROUP ( $(slibdir)/libm.so$(libm.so-version) ' \
'AS_NEEDED ( $(libdir)/libmvec_nonshared.a $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \
) > $@
) > $@.new
mv -f $@.new $@
endif
# Rules for the test suite.
+3
View File
@@ -1144,6 +1144,7 @@ cos 0x4.7857dp+68
cos -0x1.02e34cp+0
cos 0xf.f0274p+4
cos 0x3.042d88p+0
cos 0x1.8475e5afd4481p+0
cosh 0
cosh -0
@@ -3780,6 +3781,7 @@ sin min
sin -min
sin min_subnorm
sin -min_subnorm
sin 0x1.8475e5afd4481p+0
sincos 0
sincos -0
@@ -3814,6 +3816,7 @@ sincos min
sincos -min
sincos min_subnorm
sincos -min_subnorm
sincos 0x1.8475e5afd4481p+0
sinh 0
sinh -0
+207
View File
@@ -103416,6 +103416,75 @@ cos 0x3.042d88p+0
= cos tonearest ldbl-128ibm 0x3.042d88p+0L : -0xf.dfe6f2169e24f276e8027d91bcp-4L : inexact-ok
= cos towardzero ldbl-128ibm 0x3.042d88p+0L : -0xf.dfe6f2169e24f276e8027d91b8p-4L : inexact-ok
= cos upward ldbl-128ibm 0x3.042d88p+0L : -0xf.dfe6f2169e24f276e8027d91b8p-4L : inexact-ok
cos 0x1.8475e5afd4481p+0
= cos downward flt-32 0x1.8475e6p+0f : 0xd.a8263p-8f : inexact-ok
= cos tonearest flt-32 0x1.8475e6p+0f : 0xd.a8263p-8f : inexact-ok
= cos towardzero flt-32 0x1.8475e6p+0f : 0xd.a8263p-8f : inexact-ok
= cos upward flt-32 0x1.8475e6p+0f : 0xd.a8264p-8f : inexact-ok
= cos downward dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6dp-8 : inexact-ok
= cos tonearest dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6dp-8 : inexact-ok
= cos towardzero dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6dp-8 : inexact-ok
= cos upward dbl-64 0x1.8475e6p+0 : 0xd.a8263394be6d8p-8 : inexact-ok
= cos downward ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
= cos tonearest ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
= cos towardzero ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
= cos upward ldbl-96-intel 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
= cos downward ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
= cos tonearest ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
= cos towardzero ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e5p-8L : inexact-ok
= cos upward ldbl-96-m68k 0x1.8475e6p+0L : 0xd.a8263394be6d0e6p-8L : inexact-ok
= cos downward ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
= cos tonearest ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
= cos towardzero ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
= cos upward ldbl-128 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3ba8p-8L : inexact-ok
= cos downward ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
= cos tonearest ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
= cos towardzero ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
= cos upward ldbl-128ibm 0x1.8475e6p+0L : 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
= cos downward flt-32 0x1.8475e4p+0f : 0xd.a8283p-8f : inexact-ok
= cos tonearest flt-32 0x1.8475e4p+0f : 0xd.a8283p-8f : inexact-ok
= cos towardzero flt-32 0x1.8475e4p+0f : 0xd.a8283p-8f : inexact-ok
= cos upward flt-32 0x1.8475e4p+0f : 0xd.a8284p-8f : inexact-ok
= cos downward dbl-64 0x1.8475e4p+0 : 0xd.a82832da19f98p-8 : inexact-ok
= cos tonearest dbl-64 0x1.8475e4p+0 : 0xd.a82832da19f98p-8 : inexact-ok
= cos towardzero dbl-64 0x1.8475e4p+0 : 0xd.a82832da19f98p-8 : inexact-ok
= cos upward dbl-64 0x1.8475e4p+0 : 0xd.a82832da19fap-8 : inexact-ok
= cos downward ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
= cos tonearest ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
= cos towardzero ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
= cos upward ldbl-96-intel 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
= cos downward ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
= cos tonearest ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
= cos towardzero ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9891p-8L : inexact-ok
= cos upward ldbl-96-m68k 0x1.8475e4p+0L : 0xd.a82832da19f9892p-8L : inexact-ok
= cos downward ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
= cos tonearest ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
= cos towardzero ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
= cos upward ldbl-128 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
= cos downward ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
= cos tonearest ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
= cos towardzero ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
= cos upward ldbl-128ibm 0x1.8475e4p+0L : 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
= cos downward dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbe8p-8 : inexact-ok
= cos tonearest dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbe8p-8 : inexact-ok
= cos towardzero dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbe8p-8 : inexact-ok
= cos upward dbl-64 0x1.8475e5afd4481p+0 : 0xd.a82683a33cbfp-8 : inexact-ok
= cos downward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
= cos tonearest ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
= cos towardzero ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
= cos upward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
= cos downward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
= cos tonearest ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
= cos towardzero ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebffp-8L : inexact-ok
= cos upward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbecp-8L : inexact-ok
= cos downward ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
= cos tonearest ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
= cos towardzero ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
= cos upward ldbl-128 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa296688p-8L : inexact-ok
= cos downward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
= cos tonearest ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
= cos towardzero ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
= cos upward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xd.a82683a33cbebfffffffa2966cp-8L : inexact-ok
cosh 0
= cosh downward flt-32 0x0p+0f : 0x1p+0f : inexact-ok
= cosh tonearest flt-32 0x0p+0f : 0x1p+0f : inexact-ok
@@ -262073,6 +262142,75 @@ sin -min_subnorm
= sin tonearest ldbl-128 -0x4p-16496L : -0x4p-16496L : inexact-ok underflow errno-erange-ok
= sin towardzero ldbl-128 -0x4p-16496L : -0x0p+0L : inexact-ok underflow errno-erange-ok
= sin upward ldbl-128 -0x4p-16496L : -0x0p+0L : inexact-ok underflow errno-erange-ok
sin 0x1.8475e5afd4481p+0
= sin downward flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f : inexact-ok
= sin tonearest flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f : inexact-ok
= sin towardzero flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f : inexact-ok
= sin upward flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f : inexact-ok
= sin downward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 : inexact-ok
= sin tonearest dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 : inexact-ok
= sin towardzero dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 : inexact-ok
= sin upward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e5895p-4 : inexact-ok
= sin downward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
= sin tonearest ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
= sin towardzero ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
= sin upward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L : inexact-ok
= sin downward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
= sin tonearest ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
= sin towardzero ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L : inexact-ok
= sin upward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L : inexact-ok
= sin downward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L : inexact-ok
= sin tonearest ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L : inexact-ok
= sin towardzero ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L : inexact-ok
= sin upward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L : inexact-ok
= sin downward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L : inexact-ok
= sin tonearest ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L : inexact-ok
= sin towardzero ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L : inexact-ok
= sin upward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L : inexact-ok
= sin downward flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f : inexact-ok
= sin tonearest flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f : inexact-ok
= sin towardzero flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f : inexact-ok
= sin upward flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f : inexact-ok
= sin downward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 : inexact-ok
= sin tonearest dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 : inexact-ok
= sin towardzero dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 : inexact-ok
= sin upward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953ae8p-4 : inexact-ok
= sin downward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
= sin tonearest ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
= sin towardzero ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
= sin upward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L : inexact-ok
= sin downward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
= sin tonearest ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
= sin towardzero ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L : inexact-ok
= sin upward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L : inexact-ok
= sin downward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L : inexact-ok
= sin tonearest ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L : inexact-ok
= sin towardzero ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L : inexact-ok
= sin upward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L : inexact-ok
= sin downward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L : inexact-ok
= sin tonearest ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L : inexact-ok
= sin towardzero ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L : inexact-ok
= sin upward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L : inexact-ok
= sin downward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 : inexact-ok
= sin tonearest dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 : inexact-ok
= sin towardzero dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 : inexact-ok
= sin upward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 : inexact-ok
= sin downward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
= sin tonearest ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
= sin towardzero ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
= sin upward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
= sin downward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
= sin tonearest ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
= sin towardzero ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L : inexact-ok
= sin upward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L : inexact-ok
= sin downward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L : inexact-ok
= sin tonearest ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L : inexact-ok
= sin towardzero ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L : inexact-ok
= sin upward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L : inexact-ok
= sin downward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L : inexact-ok
= sin tonearest ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L : inexact-ok
= sin towardzero ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L : inexact-ok
= sin upward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L : inexact-ok
sincos 0
= sincos downward flt-32 0x0p+0f : 0x0p+0f 0x1p+0f : inexact-ok
= sincos tonearest flt-32 0x0p+0f : 0x0p+0f 0x1p+0f : inexact-ok
@@ -264170,6 +264308,75 @@ sincos -min_subnorm
= sincos tonearest ldbl-128 -0x4p-16496L : -0x4p-16496L 0x1p+0L : inexact-ok underflow errno-erange-ok
= sincos towardzero ldbl-128 -0x4p-16496L : -0x0p+0L 0xf.fffffffffffffffffffffffffff8p-4L : inexact-ok underflow errno-erange-ok
= sincos upward ldbl-128 -0x4p-16496L : -0x0p+0L 0x1p+0L : inexact-ok underflow errno-erange-ok
sincos 0x1.8475e5afd4481p+0
= sincos downward flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f 0xd.a8263p-8f : inexact-ok
= sincos tonearest flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f 0xd.a8263p-8f : inexact-ok
= sincos towardzero flt-32 0x1.8475e6p+0f : 0xf.fa2adp-4f 0xd.a8263p-8f : inexact-ok
= sincos upward flt-32 0x1.8475e6p+0f : 0xf.fa2aep-4f 0xd.a8264p-8f : inexact-ok
= sincos downward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 0xd.a8263394be6dp-8 : inexact-ok
= sincos tonearest dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 0xd.a8263394be6dp-8 : inexact-ok
= sincos towardzero dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e58948p-4 0xd.a8263394be6dp-8 : inexact-ok
= sincos upward dbl-64 0x1.8475e6p+0 : 0xf.fa2add3e5895p-4 0xd.a8263394be6d8p-8 : inexact-ok
= sincos downward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
= sincos tonearest ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
= sincos towardzero ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
= sincos upward ldbl-96-intel 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
= sincos downward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
= sincos tonearest ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
= sincos towardzero ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d1p-4L 0xd.a8263394be6d0e5p-8L : inexact-ok
= sincos upward ldbl-96-m68k 0x1.8475e6p+0L : 0xf.fa2add3e58948d2p-4L 0xd.a8263394be6d0e6p-8L : inexact-ok
= sincos downward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
= sincos tonearest ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
= sincos towardzero ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b5618p-4L 0xd.a8263394be6d0e58c1c35a8a3bap-8L : inexact-ok
= sincos upward ldbl-128 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b562p-4L 0xd.a8263394be6d0e58c1c35a8a3ba8p-8L : inexact-ok
= sincos downward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
= sincos tonearest ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
= sincos towardzero ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b54p-4L 0xd.a8263394be6d0e58c1c35a8a38p-8L : inexact-ok
= sincos upward ldbl-128ibm 0x1.8475e6p+0L : 0xf.fa2add3e58948d10238cc27b58p-4L 0xd.a8263394be6d0e58c1c35a8a3cp-8L : inexact-ok
= sincos downward flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f 0xd.a8283p-8f : inexact-ok
= sincos tonearest flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f 0xd.a8283p-8f : inexact-ok
= sincos towardzero flt-32 0x1.8475e4p+0f : 0xf.fa2adp-4f 0xd.a8283p-8f : inexact-ok
= sincos upward flt-32 0x1.8475e4p+0f : 0xf.fa2aep-4f 0xd.a8284p-8f : inexact-ok
= sincos downward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 0xd.a82832da19f98p-8 : inexact-ok
= sincos tonearest dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 0xd.a82832da19f98p-8 : inexact-ok
= sincos towardzero dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953aep-4 0xd.a82832da19f98p-8 : inexact-ok
= sincos upward dbl-64 0x1.8475e4p+0 : 0xf.fa2adb8953ae8p-4 0xd.a82832da19fap-8 : inexact-ok
= sincos downward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
= sincos tonearest ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9892p-8L : inexact-ok
= sincos towardzero ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
= sincos upward ldbl-96-intel 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L 0xd.a82832da19f9892p-8L : inexact-ok
= sincos downward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
= sincos tonearest ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9892p-8L : inexact-ok
= sincos towardzero ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae262p-4L 0xd.a82832da19f9891p-8L : inexact-ok
= sincos upward ldbl-96-m68k 0x1.8475e4p+0L : 0xf.fa2adb8953ae263p-4L 0xd.a82832da19f9892p-8L : inexact-ok
= sincos downward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
= sincos tonearest ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
= sincos towardzero ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6b8p-4L 0xd.a82832da19f9891d9762fa659ff8p-8L : inexact-ok
= sincos upward ldbl-128 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f6cp-4L 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
= sincos downward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
= sincos tonearest ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
= sincos towardzero ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f4p-4L 0xd.a82832da19f9891d9762fa659cp-8L : inexact-ok
= sincos upward ldbl-128ibm 0x1.8475e4p+0L : 0xf.fa2adb8953ae26229c919ec8f8p-4L 0xd.a82832da19f9891d9762fa65ap-8L : inexact-ok
= sincos downward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 0xd.a82683a33cbe8p-8 : inexact-ok
= sincos tonearest dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 0xd.a82683a33cbe8p-8 : inexact-ok
= sincos towardzero dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea838p-4 0xd.a82683a33cbe8p-8 : inexact-ok
= sincos upward dbl-64 0x1.8475e5afd4481p+0 : 0xf.fa2adcf9ea84p-4 0xd.a82683a33cbfp-8 : inexact-ok
= sincos downward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
= sincos tonearest ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
= sincos towardzero ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
= sincos upward ldbl-96-intel 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
= sincos downward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
= sincos tonearest ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
= sincos towardzero ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdp-4L 0xd.a82683a33cbebffp-8L : inexact-ok
= sincos upward ldbl-96-m68k 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbep-4L 0xd.a82683a33cbecp-8L : inexact-ok
= sincos downward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
= sincos tonearest ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
= sincos towardzero ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea68p-4L 0xd.a82683a33cbebfffffffa2966878p-8L : inexact-ok
= sincos upward ldbl-128 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ea7p-4L 0xd.a82683a33cbebfffffffa296688p-8L : inexact-ok
= sincos downward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
= sincos tonearest ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
= sincos towardzero ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455e8p-4L 0xd.a82683a33cbebfffffffa29668p-8L : inexact-ok
= sincos upward ldbl-128ibm 0x1.8475e5afd4481p+0L : 0xf.fa2adcf9ea83dbdd053ee455ecp-4L 0xd.a82683a33cbebfffffffa2966cp-8L : inexact-ok
sinh 0
= sinh downward flt-32 0x0p+0f : 0x0p+0f : inexact-ok
= sinh tonearest flt-32 0x0p+0f : 0x0p+0f : inexact-ok
+6 -1
View File
@@ -30,12 +30,17 @@ do_test (void)
header fix this test will not compile. */
if (isinff (1.0f)
|| !isinff (INFINITY)
#ifndef NO_LONG_DOUBLE
|| isinfl (1.0L)
|| !isinfl (INFINITY)
#endif
|| isnanf (2.0f)
|| !isnanf (NAN)
#ifndef NO_LONG_DOUBLE
|| isnanl (2.0L)
|| !isnanl (NAN))
|| !isnanl (NAN)
#endif
)
{
printf ("FAIL: Failed to call is* functions.\n");
exit (1);
+5 -4
View File
@@ -29,14 +29,15 @@
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_23)
/* Define the variables used for the interface. */
char *loc1;
char *loc2;
/* Define the variables used for the interface. Avoid .symver on common
symbol, which just creates a new common symbol, not an alias. */
char *loc1 __attribute__ ((nocommon));
char *loc2 __attribute__ ((nocommon));
compat_symbol (libc, loc1, loc1, GLIBC_2_0);
compat_symbol (libc, loc2, loc2, GLIBC_2_0);
/* Although we do not support the use we define this variable as well. */
char *locs;
char *locs __attribute__ ((nocommon));
compat_symbol (libc, locs, locs, GLIBC_2_0);
+11 -9
View File
@@ -680,16 +680,18 @@ nis_server_cache_add (const_nis_name name, int search_parent,
/* Choose which entry should be evicted from the cache. */
loc = &nis_server_cache[0];
if (*loc != NULL)
for (i = 1; i < 16; ++i)
if (nis_server_cache[i] == NULL)
{
{
for (i = 1; i < 16; ++i)
if (nis_server_cache[i] == NULL)
{
loc = &nis_server_cache[i];
break;
}
else if ((*loc)->uses > nis_server_cache[i]->uses
|| ((*loc)->uses == nis_server_cache[i]->uses
&& (*loc)->expires > nis_server_cache[i]->expires))
loc = &nis_server_cache[i];
break;
}
else if ((*loc)->uses > nis_server_cache[i]->uses
|| ((*loc)->uses == nis_server_cache[i]->uses
&& (*loc)->expires > nis_server_cache[i]->expires))
loc = &nis_server_cache[i];
}
old = *loc;
*loc = new;
+11 -5
View File
@@ -266,7 +266,7 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
tmpbuf = __alloca (buflen);
do
while (1)
{
while ((status =
internal_getgrent_r (&grpbuf, tmpbuf, buflen, errnop,
@@ -275,8 +275,11 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
if (status != NSS_STATUS_SUCCESS)
goto done;
{
if (status == NSS_STATUS_NOTFOUND)
status = NSS_STATUS_SUCCESS;
goto done;
}
g = &grpbuf;
if (g->gr_gid != group)
@@ -304,7 +307,11 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
newgroups = realloc (groups, newsize * sizeof (*groups));
if (newgroups == NULL)
goto done;
{
status = NSS_STATUS_TRYAGAIN;
*errnop = errno;
goto done;
}
*groupsp = groups = newgroups;
*size = newsize;
}
@@ -316,7 +323,6 @@ _nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
}
}
}
while (status == NSS_STATUS_SUCCESS);
done:
while (intern.start != NULL)
+10 -33
View File
@@ -25,48 +25,25 @@
the historical ABI requires it. For static linking, there is no need to
provide anything here--the libc version will be linked in. For shared
library ABI compatibility, there must be __fork and fork symbols in
libpthread.so; so we define them using IFUNC to redirect to the libc
function. */
libpthread.so.
With an IFUNC resolver, it would be possible to avoid the
indirection, but the IFUNC resolver might run before the
__libc_fork symbol has been relocated, in which case the IFUNC
resolver would not be able to provide the correct address. */
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
# if HAVE_IFUNC
static __typeof (fork) *
__attribute__ ((used))
fork_resolve (void)
{
return &__libc_fork;
}
# ifdef HAVE_ASM_SET_DIRECTIVE
# define DEFINE_FORK(name) \
asm (".set " #name ", fork_resolve\n" \
".globl " #name "\n" \
".type " #name ", %gnu_indirect_function");
# else
# define DEFINE_FORK(name) \
asm (#name " = fork_resolve\n" \
".globl " #name "\n" \
".type " #name ", %gnu_indirect_function");
# endif
# else /* !HAVE_IFUNC */
static pid_t __attribute__ ((used))
fork_compat (void)
{
return __libc_fork ();
}
# define DEFINE_FORK(name) strong_alias (fork_compat, name)
strong_alias (fork_compat, fork_alias)
compat_symbol (libpthread, fork_alias, fork, GLIBC_2_0);
# endif /* HAVE_IFUNC */
DEFINE_FORK (fork_ifunc)
compat_symbol (libpthread, fork_ifunc, fork, GLIBC_2_0);
DEFINE_FORK (__fork_ifunc)
compat_symbol (libpthread, __fork_ifunc, __fork, GLIBC_2_0);
strong_alias (fork_compat, __fork_alias)
compat_symbol (libpthread, __fork_alias, __fork, GLIBC_2_0);
#endif
+16
View File
@@ -333,6 +333,22 @@ do_test (void)
puts ("early cancellation succeeded");
if (ap == &a2)
{
/* The aio_read(&a) was not canceled because the read request was
already in progress. In the meanwhile aio_write(ap) wrote something
to the pipe and the read request either has already been finished or
is able to read the requested byte.
Wait for the read request before returning from this function because
the return value and error code from the read syscall will be written
to the struct aiocb a, which lies on the stack of this function.
Otherwise the stack from subsequent function calls - e.g. _dl_fini -
will be corrupted, which can lead to undefined behaviour like a
segmentation fault. */
const struct aiocb *l[1] = { &a };
TEMP_FAILURE_RETRY (aio_suspend(l, 1, NULL));
}
return 0;
}
+2
View File
@@ -75,5 +75,7 @@ do_test (void)
return result;
}
// The test currently hangs and is XFAILed. Reduce the timeout.
#define TIMEOUT 1
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+9 -3
View File
@@ -77,7 +77,7 @@ CONCAT(_nss_db_set,ENTNAME) (int stayopen)
keep_db |= stayopen;
/* Reset the sequential index. */
entidx = (const char *) state.header + state.header->valstroffset;
entidx = NULL;
}
__libc_lock_unlock (lock);
@@ -253,8 +253,14 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
H_ERRNO_SET (NETDB_INTERNAL);
goto out;
}
entidx = NULL;
}
/* Start from the beginning if freshly initialized or reset
requested by set*ent. */
if (entidx == NULL)
entidx = (const char *) state.header + state.header->valstroffset;
status = NSS_STATUS_UNAVAIL;
if (state.header != MAP_FAILED)
{
@@ -288,8 +294,8 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
}
if (err < 0)
{
H_ERRNO_SET (HOST_NOT_FOUND);
status = NSS_STATUS_NOTFOUND;
H_ERRNO_SET (NETDB_INTERNAL);
status = NSS_STATUS_TRYAGAIN;
break;
}
+357 -296
View File
File diff suppressed because it is too large Load Diff
+356 -321
View File
File diff suppressed because it is too large Load Diff
+440 -366
View File
File diff suppressed because it is too large Load Diff
+370 -304
View File
File diff suppressed because it is too large Load Diff
+368 -300
View File
File diff suppressed because it is too large Load Diff
+363 -299
View File
File diff suppressed because it is too large Load Diff
+356 -296
View File
File diff suppressed because it is too large Load Diff
+368 -297
View File
File diff suppressed because it is too large Load Diff
+368 -298
View File
File diff suppressed because it is too large Load Diff
+370 -305
View File
File diff suppressed because it is too large Load Diff
+367 -301
View File
File diff suppressed because it is too large Load Diff
+368 -297
View File
File diff suppressed because it is too large Load Diff
+352 -295
View File
File diff suppressed because it is too large Load Diff
+364 -296
View File
File diff suppressed because it is too large Load Diff
+367 -299
View File
File diff suppressed because it is too large Load Diff
+376 -301
View File
File diff suppressed because it is too large Load Diff
+371 -300
View File
File diff suppressed because it is too large Load Diff
+468 -452
View File
File diff suppressed because it is too large Load Diff
+372 -303
View File
File diff suppressed because it is too large Load Diff
+359 -298
View File
File diff suppressed because it is too large Load Diff
+373 -307
View File
File diff suppressed because it is too large Load Diff
+357 -298
View File
File diff suppressed because it is too large Load Diff
+356 -295
View File
File diff suppressed because it is too large Load Diff
+360 -300
View File
File diff suppressed because it is too large Load Diff
+511 -427
View File
File diff suppressed because it is too large Load Diff
+368 -297
View File
File diff suppressed because it is too large Load Diff
+367 -300
View File
File diff suppressed because it is too large Load Diff
+1122 -1025
View File
File diff suppressed because it is too large Load Diff
+367 -296
View File
File diff suppressed because it is too large Load Diff
+14 -2
View File
@@ -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;
+125 -118
View File
@@ -24,7 +24,9 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/* Outcomment the following line for production quality code. */
/* #define NDEBUG 1 */
@@ -57,10 +59,8 @@
#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
@@ -75,82 +75,8 @@
# endif /* HAVE_VMSDIR_H */
#endif
/* In GNU systems, <dirent.h> 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 <stdlib.h>
#include <string.h>
/* NAME_MAX is usually defined in <dirent.h> or <limits.h>. */
#include <limits.h>
#ifndef NAME_MAX
# define NAME_MAX (sizeof (((struct dirent *) 0)->d_name))
#endif
#include <alloca.h>
#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
@@ -1553,56 +1582,36 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
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 (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
{
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)
{
@@ -1622,12 +1631,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
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;
}
}
+1 -1
View File
@@ -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;
-20
View File
@@ -70,7 +70,6 @@ static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
#include <resolv.h>
#include <ctype.h>
#include <errno.h>
#include <syslog.h>
#define RESOLVSORT
@@ -100,9 +99,6 @@ static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
#define MAXALIASES 35
#define MAXADDRS 35
static const char AskedForGot[] =
"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
static char *h_addr_ptrs[MAXADDRS + 1];
static struct hostent host;
@@ -335,20 +331,12 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
* uses many different types in responses that do not
* match QTYPE.
*/
if ((_res.options & RES_USE_DNSSEC) == 0) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
qname, p_class(C_IN), p_type(qtype),
p_type(type));
}
cp += n;
continue; /* XXX - had_error++ ? */
}
switch (type) {
case T_PTR:
if (strcasecmp(tname, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
AskedForGot, qname, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -397,8 +385,6 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype)
case T_A:
case T_AAAA:
if (strcasecmp(host.h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
AskedForGot, host.h_name, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -740,9 +726,6 @@ gethostbyaddr (const void *addr, socklen_t len, int af)
_res.options &= ~RES_DNSRCH;
_res.options |= RES_DEFNAMES;
if (!(rhp = gethostbyname(hname2))) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostbyaddr: No A record for %s (verifying [%s])",
hname2, inet_ntoa(*((struct in_addr *)addr)));
_res.options = old_options;
__set_h_errno (HOST_NOT_FOUND);
return (NULL);
@@ -752,9 +735,6 @@ gethostbyaddr (const void *addr, socklen_t len, int af)
if (!memcmp(*haddr, addr, INADDRSZ))
break;
if (!*haddr) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostbyaddr: A record of %s != PTR record [%s]",
hname2, inet_ntoa(*((struct in_addr *)addr)));
__set_h_errno (HOST_NOT_FOUND);
return (NULL);
}
+20 -3
View File
@@ -103,6 +103,11 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
ptr += s;
/* Check that there are enough bytes for the RR
metadata. */
if (endptr - ptr < 10)
goto unavail;
/* Check whether type and class match. */
uint_fast16_t type;
NS_GET16 (type, ptr);
@@ -137,13 +142,25 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
if (__ns_get16 (ptr) != ns_c_in)
goto unavail;
/* Also skip over the TTL. */
/* Also skip over class and TTL. */
ptr += sizeof (uint16_t) + sizeof (uint32_t);
/* Skip over the data length and data. */
ptr += sizeof (uint16_t) + __ns_get16 (ptr);
/* Skip over RDATA length and RDATA itself. */
uint16_t rdatalen = __ns_get16 (ptr);
ptr += sizeof (uint16_t);
/* Not enough room for RDATA. */
if (endptr - ptr < rdatalen)
goto unavail;
ptr += rdatalen;
}
}
/* Restore original buffer before retry. */
if (ansp.ptr != buf)
{
free (ansp.ptr);
ansp.ptr = buf;
}
}
out:
+54 -42
View File
@@ -78,7 +78,6 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/syslog.h>
#include "nsswitch.h"
@@ -99,10 +98,6 @@
#endif
#define MAXHOSTNAMELEN 256
static const char AskedForGot[] = "\
gethostby*.getanswer: asked for \"%s\", got \"%s\"";
/* We need this time later. */
typedef union querybuf
{
@@ -139,6 +134,22 @@ extern enum nss_status _nss_dns_gethostbyname3_r (const char *name, int af,
char **canonp);
hidden_proto (_nss_dns_gethostbyname3_r)
/* Return the expected RDATA length for an address record type (A or
AAAA). */
static int
rrtype_to_rdata_length (int type)
{
switch (type)
{
case T_A:
return INADDRSZ;
case T_AAAA:
return IN6ADDRSZ;
default:
return -1;
}
}
enum nss_status
_nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
char *buffer, size_t buflen, int *errnop,
@@ -751,6 +762,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
cp += INT32SZ; /* TTL */
n = __ns_get16 (cp);
cp += INT16SZ; /* len */
if (end_of_message - cp < n)
{
/* RDATA extends beyond the end of the packet. */
++had_error;
continue;
}
if (__glibc_unlikely (class != C_IN))
{
/* XXX - debug? syslog? */
@@ -830,14 +849,6 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
have_to_map = 1;
else if (__glibc_unlikely (type != qtype))
{
/* Log a low priority message if we get an unexpected record, but
skip it if we are using DNSSEC since it uses many different types
in responses that do not match QTYPE. */
if ((_res.options & RES_USE_DNSSEC) == 0)
syslog (LOG_NOTICE | LOG_AUTH,
"gethostby*.getanswer: asked for \"%s %s %s\", "
"got type \"%s\"",
qname, p_class (C_IN), p_type (qtype), p_type (type));
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -847,7 +858,6 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
case T_PTR:
if (__glibc_unlikely (strcasecmp (tname, bp) != 0))
{
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
@@ -891,10 +901,18 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
case T_AAAA:
if (__builtin_expect (strcasecmp (result->h_name, bp), 0) != 0)
{
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
/* Stop parsing at a record whose length is incorrect. */
if (n != rrtype_to_rdata_length (type))
{
++had_error;
break;
}
/* Skip records of the wrong type. */
if (n != result->h_length)
{
cp += n;
@@ -1077,6 +1095,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
n = __ns_get16 (cp);
cp += INT16SZ; /* len */
if (end_of_message - cp < n)
{
/* RDATA extends beyond the end of the packet. */
++had_error;
continue;
}
if (class != C_IN)
{
cp += n;
@@ -1124,32 +1149,25 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
}
continue;
}
#if 1
// We should not see any types other than those explicitly listed
// below. Some types sent by server seem missing, though. Just
// collect the data for now.
if (__glibc_unlikely (type != T_A && type != T_AAAA))
#else
if (__builtin_expect (type == T_SIG, 0)
|| __builtin_expect (type == T_KEY, 0)
|| __builtin_expect (type == T_NXT, 0)
|| __builtin_expect (type == T_PTR, 0)
|| __builtin_expect (type == T_DNAME, 0))
#endif
{
/* We don't support DNSSEC yet. For now, ignore the record
and send a low priority message to syslog.
We also don't expect T_PTR or T_DNAME messages. */
syslog (LOG_DEBUG | LOG_AUTH,
"getaddrinfo*.gaih_getanswer: got type \"%s\"",
p_type (type));
/* Stop parsing if we encounter a record with incorrect RDATA
length. */
if (type == T_A || type == T_AAAA)
{
if (n != rrtype_to_rdata_length (type))
{
++had_error;
continue;
}
}
else
{
/* Skip unknown records. */
cp += n;
continue;
}
if (type != T_A && type != T_AAAA)
abort ();
assert (type == T_A || type == T_AAAA);
if (*pat == NULL)
{
uintptr_t pad = (-(uintptr_t) buffer
@@ -1183,12 +1201,6 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
}
(*pat)->family = type == T_A ? AF_INET : AF_INET6;
if (__builtin_expect ((type == T_A && n != INADDRSZ)
|| (type == T_AAAA && n != IN6ADDRSZ), 0))
{
++had_error;
continue;
}
memcpy ((*pat)->addr, cp, n);
cp += n;
(*pat)->scopeid = 0;
+19 -6
View File
@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
} net_buffer;
querybuf *orig_net_buffer;
int anslen;
char *qbuf;
enum nss_status status;
if (__res_maybe_init (&_res, 0) == -1)
return NSS_STATUS_UNAVAIL;
qbuf = strdupa (name);
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
if (anslen < 0)
{
@@ -348,10 +345,23 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
if (n < 0 || res_dnok (bp) == 0)
break;
cp += n;
if (end_of_message - cp < 10)
{
__set_h_errno (NO_RECOVERY);
return NSS_STATUS_UNAVAIL;
}
GETSHORT (type, cp);
GETSHORT (class, cp);
cp += INT32SZ; /* TTL */
GETSHORT (n, cp);
uint16_t rdatalen;
GETSHORT (rdatalen, cp);
if (end_of_message - cp < rdatalen)
{
__set_h_errno (NO_RECOVERY);
return NSS_STATUS_UNAVAIL;
}
if (class == C_IN && type == T_PTR)
{
@@ -373,7 +383,7 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
cp += n;
return NSS_STATUS_UNAVAIL;
}
cp += n;
cp += rdatalen;
if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES])
{
*alias_pointer++ = bp;
@@ -384,6 +394,9 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
++have_answer;
}
}
else
/* Skip over unknown record data. */
cp += rdatalen;
}
if (have_answer)
+1 -1
View File
@@ -594,7 +594,7 @@ __res_iclose(res_state statp, bool free_addr) {
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]);
+58 -44
View File
@@ -649,6 +649,18 @@ get_nsaddr (res_state statp, int n)
return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
}
/* 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;
}
/* 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
@@ -750,8 +762,6 @@ send_vc(res_state statp,
u_short len2;
u_char *cp;
if (resplen2 != NULL)
*resplen2 = 0;
connreset = 0;
same_ns:
truncating = 0;
@@ -777,6 +787,8 @@ send_vc(res_state statp,
if (statp->_vcsock < 0) {
*terrno = errno;
Perror(statp, stderr, "socket(vc)", errno);
if (resplen2 != NULL)
*resplen2 = 0;
return (-1);
}
__set_errno (0);
@@ -786,8 +798,7 @@ send_vc(res_state statp,
: sizeof (struct sockaddr_in6)) < 0) {
*terrno = errno;
Aerror(statp, stderr, "connect/vc", errno, nsap);
__res_iclose(statp, false);
return (0);
return close_and_return_error (statp, resplen2);
}
statp->_flags |= RES_F_VC;
}
@@ -810,8 +821,7 @@ send_vc(res_state statp,
if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) {
*terrno = errno;
Perror(statp, stderr, "write failed", errno);
__res_iclose(statp, false);
return (0);
return close_and_return_error (statp, resplen2);
}
/*
* Receive length & response
@@ -833,7 +843,6 @@ send_vc(res_state statp,
if (n <= 0) {
*terrno = errno;
Perror(statp, stderr, "read failed", errno);
__res_iclose(statp, false);
/*
* A long running process might get its TCP
* connection reset if the remote server was
@@ -843,11 +852,13 @@ send_vc(res_state statp,
* instead of failing. We only allow one reset
* per query to prevent looping.
*/
if (*terrno == ECONNRESET && !connreset) {
connreset = 1;
goto same_ns;
}
return (0);
if (*terrno == ECONNRESET && !connreset)
{
__res_iclose (statp, false);
connreset = 1;
goto same_ns;
}
return close_and_return_error (statp, resplen2);
}
int rlen = ntohs (rlen16);
@@ -879,11 +890,11 @@ send_vc(res_state statp,
/* Always allocate MAXPACKET, callers expect
this specific size. */
u_char *newp = malloc (MAXPACKET);
if (newp == NULL) {
*terrno = ENOMEM;
__res_iclose(statp, false);
return (0);
}
if (newp == NULL)
{
*terrno = ENOMEM;
return close_and_return_error (statp, resplen2);
}
*thisanssizp = MAXPACKET;
*thisansp = newp;
if (thisansp == ansp2)
@@ -910,8 +921,7 @@ send_vc(res_state statp,
Dprint(statp->options & RES_DEBUG,
(stdout, ";; undersized: %d\n", len));
*terrno = EMSGSIZE;
__res_iclose(statp, false);
return (0);
return close_and_return_error (statp, resplen2);
}
cp = *thisansp;
@@ -922,8 +932,7 @@ send_vc(res_state statp,
if (__glibc_unlikely (n <= 0)) {
*terrno = errno;
Perror(statp, stderr, "read(vc)", errno);
__res_iclose(statp, false);
return (0);
return close_and_return_error (statp, resplen2);
}
if (__glibc_unlikely (truncating)) {
/*
@@ -1114,7 +1123,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);
@@ -1127,8 +1140,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:
@@ -1136,9 +1147,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;
@@ -1185,7 +1194,9 @@ send_dg(res_state statp,
}
*gotsomewhere = 1;
return (0);
if (resplen2 != NULL)
*resplen2 = 0;
return 0;
}
if (n < 0) {
if (errno == EINTR)
@@ -1253,7 +1264,7 @@ send_dg(res_state statp,
fail_sendmmsg:
Perror(statp, stderr, "sendmmsg", errno);
goto err_out;
return close_and_return_error (statp, resplen2);
}
}
else
@@ -1271,7 +1282,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)
@@ -1349,7 +1360,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 (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
@@ -1360,7 +1371,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)) {
@@ -1409,7 +1420,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)
@@ -1461,10 +1472,10 @@ send_dg(res_state statp,
goto wait;
}
__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) {
@@ -1486,6 +1497,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. */
@@ -1501,21 +1514,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 ();
+1 -1
View File
@@ -58,7 +58,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 \
tst-printf-bz18872
tst-printf-bz18872 tst-fmemopen4
test-srcs = tst-unbputc tst-printf
+32 -19
View File
@@ -209,9 +209,9 @@ hack_digit (struct hack_digit_param *p)
}
int
___printf_fp (FILE *fp,
const struct printf_info *info,
const void *const *args)
__printf_fp_l (FILE *fp, locale_t loc,
const struct printf_info *info,
const void *const *args)
{
/* The floating-point value to output. */
union
@@ -263,18 +263,19 @@ ___printf_fp (FILE *fp,
/* Figure out the decimal point character. */
if (info->extra == 0)
{
decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
decimal = _nl_lookup (loc, LC_NUMERIC, DECIMAL_POINT);
decimalwc = _nl_lookup_word
(loc, LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
}
else
{
decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
decimal = _nl_lookup (loc, LC_MONETARY, MON_DECIMAL_POINT);
if (*decimal == '\0')
decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
decimal = _nl_lookup (loc, LC_NUMERIC, DECIMAL_POINT);
decimalwc = _nl_lookup_word (loc, LC_MONETARY,
_NL_MONETARY_DECIMAL_POINT_WC);
if (decimalwc == L'\0')
decimalwc = _NL_CURRENT_WORD (LC_NUMERIC,
decimalwc = _nl_lookup_word (loc, LC_NUMERIC,
_NL_NUMERIC_DECIMAL_POINT_WC);
}
/* The decimal point character must not be zero. */
@@ -284,9 +285,9 @@ ___printf_fp (FILE *fp,
if (info->group)
{
if (info->extra == 0)
grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
grouping = _nl_lookup (loc, LC_NUMERIC, GROUPING);
else
grouping = _NL_CURRENT (LC_MONETARY, MON_GROUPING);
grouping = _nl_lookup (loc, LC_MONETARY, MON_GROUPING);
if (*grouping <= 0 || *grouping == CHAR_MAX)
grouping = NULL;
@@ -296,19 +297,20 @@ ___printf_fp (FILE *fp,
if (wide)
{
if (info->extra == 0)
thousands_sepwc =
_NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
thousands_sepwc = _nl_lookup_word
(loc, LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
else
thousands_sepwc =
_NL_CURRENT_WORD (LC_MONETARY,
_nl_lookup_word (loc, LC_MONETARY,
_NL_MONETARY_THOUSANDS_SEP_WC);
}
else
{
if (info->extra == 0)
thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
thousands_sep = _nl_lookup (loc, LC_NUMERIC, THOUSANDS_SEP);
else
thousands_sep = _NL_CURRENT (LC_MONETARY, MON_THOUSANDS_SEP);
thousands_sep = _nl_lookup
(loc, LC_MONETARY, MON_THOUSANDS_SEP);
}
if ((wide && thousands_sepwc == L'\0')
@@ -1171,9 +1173,11 @@ ___printf_fp (FILE *fp,
size_t decimal_len;
size_t thousands_sep_len;
wchar_t *copywc;
size_t factor = (info->i18n
? _NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX)
: 1);
size_t factor;
if (info->i18n)
factor = _nl_lookup_word (loc, LC_CTYPE, _NL_CTYPE_MB_CUR_MAX);
else
factor = 1;
decimal_len = strlen (decimal);
@@ -1244,8 +1248,17 @@ ___printf_fp (FILE *fp,
}
return done;
}
libc_hidden_def (__printf_fp_l)
int
___printf_fp (FILE *fp, const struct printf_info *info,
const void *const *args)
{
return __printf_fp_l (fp, _NL_CURRENT_LOCALE, info, args);
}
ldbl_hidden_def (___printf_fp, __printf_fp)
ldbl_strong_alias (___printf_fp, __printf_fp)
/* Return the number of extra grouping characters that will be inserted
into a number with INTDIG_MAX integer digits. */
+117 -1
View File
@@ -25,8 +25,13 @@ static void
print_buffer (const char *s, size_t n)
{
size_t i;
printf ("{");
for (i=0; i<n; ++i)
printf ("0x%02X (%c), ", s[i], s[i]);
{
printf ("0x%02X (%c)", s[i], s[i]);
if (i != n)
printf (", ");
}
}
/* This test check append mode initial position (a/a+) based on POSIX defition
@@ -185,6 +190,112 @@ do_test_read_seek_negative (void)
return ret;
}
static int
do_test_write_append_2 (const char *str)
{
char buf[10];
size_t strn = strlen (str);
strcpy (buf, str);
FILE *fp = fmemopen (buf, sizeof (buf), "a+");
size_t r = ftell (fp);
size_t e = strlen (buf);
if (r != e)
{
printf ("%s: ftell returned %zu, expected %zu\n", __FUNCTION__, r, e);
return 1;
}
if (fseek (fp, 0, SEEK_SET) == -1)
{
printf ("%s: fseek returned -1\n", __FUNCTION__);
return 1;
}
int gr;
for (int i=0; i<strn; ++i)
{
if ((gr = getc (fp)) != str[i])
{
printf ("%s: getc failed returned %d, expected %d\n", __FUNCTION__,
gr, str[i]);
return 1;
}
}
if ((gr = getc (fp)) != EOF)
{
printf ("%s: getc failed returned %d, expected EOF\n", __FUNCTION__,
gr);
return 1;
}
if (fseek (fp, e+1, SEEK_SET) == -1)
{
printf ("%s: fseek returned -1\n", __FUNCTION__);
return 1;
}
if ((r = ftell (fp)) != e+1)
{
printf ("%s: ftell returned %zu, expected %zu\n", __FUNCTION__, r, e+1);
return 1;
}
if ((gr = getc (fp)) != EOF)
{
printf ("%s: getc failed returned %i\n", __FUNCTION__, gr);
return 1;
}
/* Check if internal position is not changed with a getc returning EOF. */
if ((r = ftell (fp)) != e+1)
{
printf ("%s: ftell returned %zu, expected %zu\n", __FUNCTION__, r, e+1);
return 1;
}
if (fseek (fp, 0, SEEK_CUR) == -1)
{
printf ("%s: fseek returned -1\n", __FUNCTION__);
return 1;
}
/* This should be overwritten by fprintf + fflush. */
buf[e+2] = 'X';
if ((r = fprintf (fp, "%d", 101)) != 3)
{
printf ("%s: fprintf returned %zu, expected %d\n", __FUNCTION__, r, 3);
return 1;
}
fflush (fp);
/* Check if internal position is changed by 3 (strlen of '101'). */
if ((r = ftell (fp)) != e+3)
{
printf ("%s: ftell returned %zu, expected %zu\n", __FUNCTION__, r, e+3);
return 1;
}
char exp[20];
sprintf (exp, "%s%d", str, 101);
if (memcmp (buf, exp, strlen (exp)) != 0)
{
printf ("%s: check failed:", __FUNCTION__);
printf ("\nexpected: ");
print_buffer (buf, sizeof (buf));
printf ("\nbuffer: ");
print_buffer (exp, sizeof (exp));
printf ("\n");
return 1;
}
fclose(fp);
return 0;
}
static int
do_test (void)
{
@@ -199,6 +310,11 @@ do_test (void)
ret += do_test_read_seek_negative ();
/* First test plus addend will fit in the define buffer of size 10. */
ret += do_test_write_append_2 ("test");
/* The second test will also fit, but not the final '\0'. */
ret += do_test_write_append_2 ("testing");
return ret;
}
+71
View File
@@ -0,0 +1,71 @@
/* fmemopen tests for BZ#1930 and BZ#20005.
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 <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
/* Check if fflush does not reset the file position. */
static int
do_test (void)
{
char buffer[500] = "x";
FILE *stream = fmemopen (buffer, sizeof (buffer), "r+");
if (stream == NULL)
{
printf ("error: fmemopen could not open stream\n");
return 1;
}
const char test[] = "test";
size_t r = fwrite (test, sizeof (char), sizeof (test), stream);
if (r != sizeof (test))
{
printf ("error: fwrite returned %zu, expected %zu\n", r, sizeof(test));
return 1;
}
r = ftell (stream);
if (r != sizeof (test))
{
printf ("error: ftell return %zu, expected %zu\n", r, sizeof(test));
return 1;
}
if (fflush (stream) != 0)
{
printf ("error: fflush failed\n");
return 1;
}
r = ftell (stream);
if (r != sizeof (test))
{
printf ("error: ftell return %zu, expected %zu\n", r, sizeof(test));
return 1;
}
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+4 -2
View File
@@ -76,7 +76,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
tst-secure-getenv tst-strtod-overflow tst-strtod-round \
tst-tininess tst-strtod-underflow tst-tls-atexit \
tst-setcontext3 tst-tls-atexit-nodelete \
tst-strtol-locale tst-strtod-nan-locale
tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l
tests-static := tst-secure-getenv
modules-names = tst-tls-atexit-lib
@@ -126,7 +126,8 @@ include ../Rules
ifeq ($(run-built-tests),yes)
LOCALES := cs_CZ.UTF-8 de_DE.UTF-8 en_US.ISO-8859-1 tr_TR.UTF-8 \
tr_TR.ISO-8859-9
tr_TR.ISO-8859-9 tg_TJ.UTF-8 te_IN.UTF-8 bn_IN.UTF-8 \
el_GR.UTF-8
include ../gen-locales.mk
$(objpfx)bug-strtod2.out: $(gen-locales)
@@ -137,6 +138,7 @@ $(objpfx)tst-strtod4.out: $(gen-locales)
$(objpfx)tst-strtod5.out: $(gen-locales)
$(objpfx)tst-strtol-locale.out: $(gen-locales)
$(objpfx)tst-strtod-nan-locale.out: $(gen-locales)
$(objpfx)tst-strfmon_l.out: $(gen-locales)
endif
# Testdir has to be named stdlib and needs to be writable
+13 -11
View File
@@ -278,18 +278,20 @@ unsetenv (const char *name)
ep = __environ;
if (ep != NULL)
while (*ep != NULL)
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
{
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
do
dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
}
else
++ep;
do
dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
}
else
++ep;
}
UNLOCK;

Some files were not shown because too many files have changed in this diff Show More