Compare commits

..
Author SHA1 Message Date
Carlos O'Donell b2a77206b3 Add generic C.UTF-8 locale (Bug 17318)
We add a new C.UTF-8 locale.  This locale is not builtin to glibc, but
is provided as a distinct locale.  The locale provides full support
for UTF-8 and this includes full code point sorting via strcmp-based
collation.

The collation uses a new keyword 'strcmp_collation' which drops all
collation rules and generates an empty zero rules collation to enable
strcmp usage in collation. This ensures that we get full code point
sorting for C.UTF-8 with a minimal 92 bytes of overhead (LC_COLLATE
structure information).

The new locale is added to SUPPORTED.  Minimal test data for specific
code points (minus those not supported by collate-test) is provided
in C.UTF-8.in, and this verifies code point sorting is working
reasonably across the range.  The locale was tested manually with the
full set of code points without failure.

The locale is harmonized with locales already shipping in Gentoo,
Debian, Ubuntu, Fedora, CentOS Stream, and RHEL. A new tst-iconv9 test
is added which verifies the C.UTF-8 locale is generally usable.

Testing for fnmatch, regexec, and recomp is provided by extending
bug-regex1, bugregex19, bug-regex4, bug-regex6, transbug, tst-fnmatch,
tst-regcomp-truncated, and tst-regex to use C.UTF-8.

Tested on x86_64 or i686 without regression.
2021-07-29 01:31:39 -04:00
Carlos O'Donell 7de41f96a1 Add 'strcmp_collation' support for LC_COLLATE.
Support a new directive 'strcmp_collation' in the LC_COLLATE
section of a locale source file. This new directive causes all
collation rules to be dropped and instead 'strcmp' is used for
collation of the input character set. This is required to allow
for a C.UTF-8 that contains zero collation rules (minimal size)
and sorts using code point sorting.

Tested on x86_64 and i686 without regression.
2021-07-29 01:22:55 -04:00
Carlos O'Donell 52d5eb7e06 Add support for locales with zero collation rules.
While there is code to handle 'nrules == 0' in various locations
within posix/fnmatch_loop.c, posix/regcomp.c and posix/regexec.c,
these conditionals do not work.  The only collation with zero
rules in effect today is the builtin C/POSIX locale which is
built by hand, and despite have zero rules it has a collseqmb
and collseqwc tables stored in the locale data. These tables are
simple identity tables which are not actually required and could
be removed at a later date after this change.  The changes are in
order to prepare for C.UTF-8 which has zero rules and has no
collation sequence tables (multibyte or widechar).

No regressions on x86_64 or i686.
2021-07-29 01:16:54 -04:00
460 changed files with 10682 additions and 50287 deletions
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -491,7 +491,7 @@ build the GNU C Library:
GCC 6.2 or higher is required. In general it is recommended to use
the newest version of the compiler that is known to work for
building the GNU C Library, as newer compilers usually produce
better code. As of release time, GCC 11.2 is the newest compiler
better code. As of release time, GCC 10.2 is the newest compiler
verified to work to build the GNU C Library.
For PowerPC 64-bits little-endian (powerpc64le), a GCC version with
@@ -563,7 +563,7 @@ build the GNU C Library:
Perl is not required, but if present it is used in some tests and
the 'mtrace' program, to build the GNU C Library manual. As of
release time 'perl' version 5.32.1 is the newest verified to work
release time 'perl' version 5.32.0 is the newest verified to work
to build the GNU C Library.
* GNU 'sed' 3.02 or newer
@@ -575,7 +575,7 @@ build the GNU C Library:
* Python 3.4 or later
Python is required to build the GNU C Library. As of release time,
Python 3.9.6 is the newest verified to work for building and
Python 3.8.6 is the newest verified to work for building and
testing the GNU C Library.
* PExpect 4.0
@@ -592,7 +592,7 @@ build the GNU C Library:
use the pretty printers. Notice that your system having Python
available doesn't imply that GDB supports it, nor that your
system's Python and GDB's have the same version. As of release
time GNU 'debugger' 10.2 is the newest verified to work to test the
time GNU 'debugger' 10.1 is the newest verified to work to test the
pretty printers.
Unless Python, PExpect and GDB with Python support are present, the
+7 -16
View File
@@ -412,13 +412,12 @@ link-extra-libs-tests = $(libsupport)
# Command for linking PIE programs with the C library.
ifndef +link-pie
+link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
-Wl,-O1 -nostdlib -nostartfiles \
+link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
-Wl,-O1 -nostdlib -nostartfiles -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)S$(start-installed-name)) \
$(+preinit) $(+prectorS)
+link-pie-before-libc = -o $@ $(+link-pie-before-inputs) \
$(+preinit) $(+prectorS) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
S$(start-installed-name))\
$(+preinit) $(link-extra-libs) \
@@ -443,12 +442,11 @@ endef
endif
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static-before-inputs = -nostdlib -nostartfiles -static \
+link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \
$(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
$(+preinit) $(+prectorT)
+link-static-before-libc = -o $@ $(+link-static-before-inputs) \
$(+preinit) $(+prectorT) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
$(+preinit) $(link-extra-libs-static) \
@@ -475,16 +473,13 @@ endif
ifeq (yes,$(build-pie-default))
+link = $(+link-pie)
+link-tests = $(+link-pie-tests)
+link-tests-before-inputs = $(+link-pie-before-inputs) $(rtld-tests-LDFLAGS)
+link-tests-after-inputs = $(link-libc-tests) $(+link-pie-after-libc)
+link-printers-tests = $(+link-pie-printers-tests)
else # not build-pie-default
+link-before-inputs = -nostdlib -nostartfiles \
+link-before-libc = -nostdlib -nostartfiles -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \
$(+preinit) $(+prector)
+link-before-libc = -o $@ $(+link-before-inputs) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
$(+preinit) $(link-extra-libs) \
@@ -496,8 +491,6 @@ $(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \
$(link-extra-flags) $(link-libc) $(+link-after-libc)
$(call after-link,$@)
endef
+link-tests-before-inputs = $(+link-before-inputs) $(rtld-tests-LDFLAGS)
+link-tests-after-inputs = $(link-libc-tests) $(+link-after-libc)
define +link-tests
$(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
$(+link-after-libc)
@@ -512,8 +505,6 @@ endif # build-pie-default
else # build-static
+link = $(+link-static)
+link-tests = $(+link-static-tests)
+link-tests-before-inputs = $(+link-static-before-inputs)
+link-tests-after-inputs = $(link-libc-static-tests) $(+link-static-after-libc)
+link-printers-tests = $(+link-static-tests)
endif # build-shared
endif # +link
-6
View File
@@ -424,12 +424,6 @@ $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
endef
object-suffixes-left := $(all-object-suffixes)
include $(o-iterator)
define o-iterator-doit
$(objpfx)%$o: $(objpfx)%.cc $(before-compile); $$(compile-command.cc)
endef
object-suffixes-left := $(all-object-suffixes)
include $(o-iterator)
endif
# Generate .dT files as we compile.
+16 -265
View File
@@ -4,117 +4,19 @@ See the end for copying conditions.
Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
Version 2.34.1
Major new features:
* The audit libraries will avoid unnecessary slowdown if it is not required
PLT tracking (by not implementing the la_pltenter or la_pltexit callbacks).
Deprecated and removed features, and other changes affecting compatibility:
* The audit module interface version LAV_CURRENT is increased to enable
proper bind-now support. The loader now advertises via the la_symbind
flags that PLT trace is not possible.
* The audit interface on aarch64 is extended to support both the indirect
result location register (x8) and NEON Q register. Old audit modules are
rejected by the loader.
Security related changes:
CVE-2022-23219: Passing an overlong file name to the clnt_create
legacy function could result in a stack-based buffer overflow when
using the "unix" protocol. Reported by Martin Sebor.
CVE-2022-23218: Passing an overlong file name to the svcunix_create
legacy function could result in a stack-based buffer overflow.
CVE-2021-3998: Passing a path longer than PATH_MAX to the realpath
function could result in a memory leak and potential access of
uninitialized memory. Reported by Qualys.
CVE-2021-3999: Passing a buffer of size exactly 1 byte to the getcwd
function may result in an off-by-one buffer underflow and overflow
when the current working directory is longer than PATH_MAX and also
corresponds to the / directory through an unprivileged mount
namespace. Reported by Qualys.
The following bugs are resolved with this release:
[12889] nptl: Fix race between pthread_kill and thread exit
[19193] nptl: pthread_kill, pthread_cancel should not fail after exit
[22542] CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix"
[28036] Incorrect types for pthread_mutexattr_set/getrobust_np
[28182] _TIME_BITS=64 in C++ has issues with fcntl, ioctl, prctl
[28223] mips: clone does not align stack
[28310] Do not use affinity mask for sysconf (_SC_NPROCESSORS_CONF)
[28338] undefined behavior in __tzfile_compute with oddball TZif file
[28340] ld.so crashes while loading a DSO with a read-only dynamic section
[28349] libc: Segfault for ping -R on qemux86 caused by recvmsg()
[28350] libc: ping receives SIGABRT on lib32-qemux86-64 caused by
recvmsg()
[28353] Race condition in __opensock
[28357] deadlock between pthread_create and ELF constructors
[28361] nptl: Avoid setxid deadlock with blocked signals in thread exit
[28407] pthread_kill assumes that kill and tgkill are equivalent
[28524] Conversion from ISO-2022-JP-3 with iconv may emit spurious NULs
[28532] powerpc64[le]: CFI for assembly templated syscalls is incorrect
[28607] Masked signals are delivered on thread exit
[28678] nptl/tst-create1 hangs sporadically
[28700] "dns [!UNAVAIL=return] files" NSS default for hosts is not useful
[28702] RISC-V: clone does not align stack
[28703] RISC-V: _dl_init might be called with unaligned stack
[28704] elf/tst-cpu-features-cpuinfo fails for KVM guests on some AMD systems
[28707] assert in tzfile.c __tzfile_read striking with truncated timezones
[28744] A64FX string functions are selected without SVE HWCAP
[28755] overflow bug in wcsncmp_avx2 and wcsncmp_evex
[28771] %ebx optimization macros are incompatible with .altmacro
[28768] CVE-2022-23218: Buffer overflow in sunrpc svcunix_create
[28769] CVE-2021-3999: Off-by-one buffer overflow/underflow in getcwd()
[28770] CVE-2021-3998: Unexpected return value from realpath() for too long results
[28784] x86: crash in 32bit memset-sse2.s when the cache size can not be determined
[28850] linux: __get_nprocs_sched reads uninitialized memory from the stack
[28860] build: --enable-kernel=5.1.0 build fails because of missing
__convert_scm_timestamps
[28865] linux: _SC_NPROCESSORS_CONF and _SC_NPROCESSORS_ONLN are inaccurate
without /sys and /proc
[28896] strncmp-avx2-rtm and wcsncmp-avx2-rtm fallback on non-rtm
variants when avoiding overflow
[28953] nss: Protect against errno changes in function lookup
Version 2.34
Major new features:
* In order to support smoother in-place-upgrades and to simplify
the implementation of the runtime all functionality formerly
implemented in the libraries libpthread, libdl, libutil, libanl has
been integrated into libc. New applications do not need to link with
-lpthread, -ldl, -lutil, -lanl anymore. For backwards compatibility,
empty static archives libpthread.a, libdl.a, libutil.a, libanl.a are
provided, so that the linker options keep working. Applications which
have been linked against glibc 2.33 or earlier continue to load the
corresponding shared objects (which are now empty). The integration
of those libraries into libc means that additional symbols become
available by default. This can cause applications that contain weak
references to take unexpected code paths that would only have been
used in previous glibc versions when e.g. preloading libpthread.so.0,
potentially exposing application bugs.
* When _DYNAMIC_STACK_SIZE_SOURCE or _GNU_SOURCE are defined,
PTHREAD_STACK_MIN is no longer constant and is redefined to
sysconf(_SC_THREAD_STACK_MIN). This supports dynamic sized register
sets for modern architectural features like Arm SVE.
sysconf(_SC_THREAD_STACK_MIN).
* Add _SC_MINSIGSTKSZ and _SC_SIGSTKSZ. When _DYNAMIC_STACK_SIZE_SOURCE
or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ are no longer
constant on Linux. MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ)
and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ). This supports
dynamic sized register sets for modern architectural features like
Arm SVE.
and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ).
* The dynamic linker implements the --list-diagnostics option, printing
a dump of information related to IFUNC resolver operation and
@@ -139,10 +41,9 @@ Major new features:
* Add support for 64-bit time_t on configurations like x86 where time_t
is traditionally 32-bit. Although time_t still defaults to 32-bit on
these configurations, this default may change in future versions.
This is enabled with the _TIME_BITS preprocessor macro set to 64 and is
only supported when LFS (_FILE_OFFSET_BITS=64) is also enabled. It is
only enabled for Linux and the full support requires a minimum kernel
version of 5.1.
This is enabled with the _TIME_BITS preprocessor set to 64 and only
supported when LFS (_FILE_OFFSET_BITS=64) is also enabled. It is only
enabled for Linux and the full support requires a minimum version of 5.1.
* The main gconv-modules file in glibc now contains only a small set of
essential converter modules and the rest have been moved into a supplementary
@@ -167,13 +68,13 @@ Major new features:
closing a range of file descriptors on recent kernels (version 5.9).
* The function closefrom has been added. It closes all file descriptors
greater than or equal to a given integer. This function is a GNU extension,
although it is also present in other systems.
greater than given integer. This function is a GNU extension, although it
also present in other systems.
* The posix_spawn_file_actions_addclosefrom_np function has been added,
enabling posix_spawn and posix_spawnp to close all file descriptors greater
than or equal to a given integer. This function is a GNU extension,
although Solaris also provides a similar function.
* The posix_spawn_file_actions_closefrom_np function has been added, enabling
posix_spawn and posix_spawnp to close all file descriptors great than or
equal to a giver integer. This function is a GNU extension, although
Solaris also provides a similar function.
Deprecated and removed features, and other changes affecting compatibility:
@@ -206,22 +107,13 @@ Deprecated and removed features, and other changes affecting compatibility:
ns_format_ttl, ns_makecanon, ns_parse_ttl, ns_samedomain, ns_samename,
ns_sprintrr, ns_sprintrrf, ns_subdomain have been deprecated.
* Various symbols previously defined in libresolv have been moved to libc
in order to prepare for libresolv moving entirely into libc (see earlier
entry for merging libraries into libc). The symbols __dn_comp,
__dn_expand, __dn_skipname, __res_dnok, __res_hnok, __res_mailok,
__res_mkquery, __res_nmkquery, __res_nquery, __res_nquerydomain,
__res_nsearch, __res_nsend, __res_ownok, __res_query, __res_querydomain,
__res_search, __res_send formerly in libresolv have been renamed and no
longer have a __ prefix. They are now available in libc.
* The pthread cancellation handler is now installed with SA_RESTART and
pthread_cancel will always send the internal SIGCANCEL on a cancellation
request. It should not be visible to applications since the cancellation
request. It should not be visible to application since the cancellation
handler should either act upon cancellation (if asynchronous cancellation
is enabled) or ignore the cancellation internal signal. However there are
buggy kernel interfaces (for instance some CIFS versions) that could still
see a spurious EINTR error when cancellation interrupts a blocking syscall.
buggy kernel interfaces (for instance some CIFS version) that could still
see spurious EINTR error when cancellation interrupts a blocking syscall.
* Previously, glibc installed its various shared objects under versioned
file names such as libc-2.33.so. The ABI sonames (e.g., libc.so.6)
@@ -279,151 +171,10 @@ Security related changes:
issue when using a notification type of SIGEV_THREAD and a thread
attribute with a non-default affinity mask.
CVE-2021-35942: The wordexp function may overflow the positional
parameter number when processing the expansion resulting in a crash.
Reported by Philippe Antoine.
The following bugs are resolved with this release:
[4737] libc: fork is not async-signal-safe
[5781] math: Slow dbl-64 sin/cos/sincos for special values
[10353] libc: Methods for deleting all file descriptors greater than
given integer (closefrom)
[14185] glob: fnmatch() fails when '*' wildcard is applied on the file
name containing multi-byte character(s)
[14469] math: Inaccurate j0f function
[14470] math: Inaccurate j1f function
[14471] math: Inaccurate y0f function
[14472] math: Inaccurate y1f function
[14744] nptl: kill -32 $pid or kill -33 $pid on a process cancels a
random thread
[15271] dynamic-link: dlmopen()ed shared library with LM_ID_NEWLM
crashes if it fails dlsym() twice
[15648] nptl: multiple definition of `__lll_lock_wait_private'
[16063] nptl: Provide a pthread_once variant in libc directly
[17144] libc: syslog is not thread-safe if NO_SIGPIPE is not defined
[17145] libc: syslog with LOG_CONS leaks console file descriptor
[17183] manual: description of ENTRY struct in <search.h> in glibc
manual is incorrect
[18435] nptl: pthread_once hangs when init routine throws an exception
[18524] nptl: Missing calloc error checking in
__cxa_thread_atexit_impl
[19329] dynamic-link: dl-tls.c assert failure at concurrent
pthread_create and dlopen
[19366] nptl: returning from a thread should disable cancellation
[19511] nptl: 8MB memory leak in pthread_create in case of failure
when non-root user changes priority
[20802] dynamic-link: getauxval NULL pointer dereference after static
dlopen
[20813] nptl: pthread_exit is inconsistent between libc and libpthread
[22057] malloc: malloc_usable_size is broken with mcheck
[22668] locale: LC_COLLATE: the last character of ellipsis is not
ordered correctly
[23323] libc: [RFE] CSU startup hardening.
[23328] malloc: Remove malloc hooks and ensure related APIs return no
data.
[23462] dynamic-link: Static binary with dynamic string tokens ($LIB,
$PLATFORM, $ORIGIN) crashes
[23489] libc: "gcc -lmcheck" aborts on free when using posix_memalign
[23554] nptl: pthread_getattr_np reports wrong stack size with
MULTI_PAGE_ALIASING
[24106] libc: Bash interpreter in ldd script is taken from host
[24773] dynamic-link: dlerror in an secondary namespace does not use
the right free implementation
[25036] localedata: Update collation order for Swedish
[25383] libc: where_is_shmfs/__shm_directory/SHM_GET_NAME may cause
shm_open to pick wrong directory
[25680] dynamic-link: ifuncmain9picstatic and ifuncmain9picstatic
crash in IFUNC resolver due to stack canary (--enable-stack-
protector=all)
[26874] build: -Warray-bounds in _IO_wdefault_doallocate
[26983] math: [x86_64] x86_64 tgamma has too large ULP error
[27111] dynamic-link: pthread_create and tls access use link_map
objects that may be concurrently freed by dlclose
[27132] malloc: memusagestat is linked to system librt, leading to
undefined symbols on major version upgrade
[27136] dynamic-link: dtv setup at thread creation may leave an entry
uninitialized
[27249] libc: libSegFault.so does not output signal number properly
[27304] nptl: pthread_cond_destroy does not pass private flag to futex
system calls
[27318] dynamic-link: glibc fails to load binaries when built with
-march=sandybridge: CPU ISA level is lower than required
[27343] nss: initgroups() SIGSEGVs when called on a system without
nsswich.conf (in a chroot)
[27346] dynamic-link: x86: PTWRITE feature check is missing
[27389] network: NSS chroot hardening causes regressions in chroot
deployments
[27403] dynamic-link: aarch64: tlsdesc htab is not freed on dlclose
[27444] libc: sysconf reports unsupported option (-1) for
_SC_LEVEL1_ICACHE_LINESIZE on X86 since v2.33
[27462] nscd: double-free in nscd (CVE-2021-27645)
[27468] malloc: aarch64: realloc crash with heap tagging: FAIL:
malloc/tst-malloc-thread-fail
[27498] dynamic-link: __dl_iterate_phdr lacks unwinding information
[27511] libc: S390 memmove assumes Vector Facility when MIE Facility 3
is present
[27522] glob: glob, glob64 incorrectly marked as __THROW
[27555] dynamic-link: Static tests fail with --enable-stack-
protector=all
[27559] libc: fstat(AT_FDCWD) succeeds (it shouldn't) and returns
information for the current directory
[27577] dynamic-link: elf/ld.so --help doesn't work
[27605] libc: tunables can't control xsave/xsavec selection in
dl_runtime_resolve_*
[27623] libc: powerpc: Missing registers in sc[v] clobbers list
[27645] libc: [linux] sysconf(_SC_NPROCESSOR...) breaks down on
containers
[27646] dynamic-link: Linker error for non-existing NSS symbols (e.g.
_nss_files_getcanonname_r) from within a dlmopen namespace.
[27648] libc: FAIL: misc/tst-select
[27650] stdio: vfscanf returns too early if a match is longer than
INT_MAX
[27651] libc: Performance regression after updating to 2.33
[27655] string: Wrong size calculation in string/test-strnlen.c
[27706] libc: select fails to update timeout on error
[27709] libc: arm: FAIL: debug/tst-longjmp_chk2
[27721] dynamic-link: x86: ld_audit ignores bind now for TLSDESC and
tries resolving them lazily
[27744] nptl: Support different libpthread/ld.so load orders in
libthread_db
[27749] libc: Data race __run_exit_handlers
[27761] libc: getconf: Segmentation fault when passing '-vq' as
argument
[27832] nss: makedb.c:797:7: error: 'writev' specified size 4294967295
exceeds maximum object size 2147483647
[27870] malloc: MALLOC_CHECK_ causes realloc(valid_ptr, TOO_LARGE) to
not set ENOMEM
[27872] build: Obsolete configure option --enable-stackguard-
randomization
[27873] build: tst-cpu-features-cpuinfo fail when building on AMD cpu
[27882] localedata: Use U+00AF MACRON in more EBCDIC charsets
[27892] libc: powerpc: scv ABI error handling fails to check
IS_ERR_VALUE
[27896] nptl: mq_notify does not handle separately allocated thread
attributes (CVE-2021-33574)
[27901] libc: TEST_STACK_ALIGN doesn't work
[27902] libc: The x86-64 clone wrapper fails to align child stack
[27914] nptl: Install SIGSETXID handler with SA_ONSTACK
[27939] libc: aarch64: clone does not align the stack
[27968] libc: s390x: clone does not align the stack
[28011] libc: Wild read in wordexp (parse_param) (CVE-2021-35942)
[28024] string: s390(31bit): Wrong result of memchr (MEMCHR_Z900_G5)
with n >= 0x80000000
[28028] malloc: malloc: tcache shutdown sequence does not work if the
thread never allocated anything
[28033] libc: Need to check RTM_ALWAYS_ABORT for RTM
[28064] string: x86_64:wcslen implementation list has wcsnlen
[28067] libc: FAIL: posix/tst-spawn5
[28068] malloc: FAIL: malloc/tst-mallocalign1-mcheck
[28071] time: clock_gettime, gettimeofday, time lost vDSO acceleration
on older kernels
[28075] nis: Out-of-bounds static buffer read in nis_local_domain
[28089] build: tst-tls20 fails when linker defaults to --as-needed
[28090] build: elf/tst-cpu-features-cpuinfo-static fails on certain
AMD64 cpus
[28091] network: ns_name_skip may return 0 for domain names without
terminator
[The release manager will add the list generated by
scripts/list-fixed-bugs.py just before the release.]
Version 2.33
-25
View File
@@ -1,25 +0,0 @@
/* Data structure for communication from the run-time dynamic linker for
loaded ELF shared objects. LAV_CURRENT definition.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#ifndef _LINK_H
# error "Never include <bits/link_lavcurrent.h> directly; use <link.h> instead."
#endif
/* Version numbers for la_version handshake interface. */
#define LAV_CURRENT 2
+2 -11
View File
@@ -29,23 +29,14 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size,
while (__l < __u)
{
__idx = (__l + __u) / 2;
__p = (const void *) (((const char *) __base) + (__idx * __size));
__p = (void *) (((const char *) __base) + (__idx * __size));
__comparison = (*__compar) (__key, __p);
if (__comparison < 0)
__u = __idx;
else if (__comparison > 0)
__l = __idx + 1;
else
{
#if __GNUC_PREREQ(4, 6)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-qual"
#endif
return (void *) __p;
#if __GNUC_PREREQ(4, 6)
# pragma GCC diagnostic pop
#endif
}
return (void *) __p;
}
return NULL;
+4
View File
@@ -283,6 +283,10 @@
/* Define if static PIE is enabled. */
#define ENABLE_STATIC_PIE 0
/* Some compiler options may now allow to use ebp in __asm__ (used mainly
in i386 6 argument syscall issue). */
#define CAN_USE_REGISTER_ASM_EBP 0
/* The default value of x86 CET control. */
#define DEFAULT_DL_X86_CET_CONTROL cet_elf_property
+1 -5
View File
@@ -175,11 +175,7 @@ $(conformtest-header-tests): $(objpfx)%/conform.out: \
conformtest.py $(conformtest-headers-data)
(set -e; std_hdr=$*; std=$${std_hdr%%/*}; hdr=$${std_hdr#*/}; \
mkdir -p $(@D); \
$(PYTHON) $< --cc='$(CC) $(pie-default)' \
--flags='$(conformtest-cc-flags)' \
--ldflags='$(+link-tests-before-inputs)' \
--libs='$(+link-tests-after-inputs)' \
--run-program-prefix='$(run-program-prefix)' \
$(PYTHON) $< --cc='$(CC)' --flags='$(conformtest-cc-flags)' \
--standard=$$std --header=$$hdr $(conformtest-xfail) \
$(conformtest-cross) \
> $@ 2>&1); \
+3 -17
View File
@@ -381,16 +381,12 @@ class MacroStrTest(object):
class HeaderTests(object):
"""The set of tests run for a header."""
def __init__(self, header, standard, cc, flags, ldflags, libs,
run_program_prefix, cross, xfail):
def __init__(self, header, standard, cc, flags, cross, xfail):
"""Initialize a HeaderTests object."""
self.header = header
self.standard = standard
self.cc = cc
self.flags = flags
self.ldflags = ldflags
self.libs = libs
self.run_program_prefix = run_program_prefix
self.cross = cross
self.xfail_str = xfail
self.cflags_namespace = ('%s -fno-builtin %s -D_ISOMAC'
@@ -594,8 +590,7 @@ class HeaderTests(object):
exe_file = os.path.join(self.temp_dir, 'test')
with open(c_file, 'w') as c_file_out:
c_file_out.write('#include <%s>\n%s' % (self.header, text))
cmd = ('%s %s %s %s %s -o %s' % (self.cc, self.cflags, self.ldflags,
c_file, self.libs, exe_file))
cmd = ('%s %s %s -o %s' % (self.cc, self.cflags, c_file, exe_file))
try:
subprocess.check_call(cmd, shell=True)
except subprocess.CalledProcessError:
@@ -605,9 +600,7 @@ class HeaderTests(object):
self.note_skip(name)
return
try:
subprocess.check_call('%s %s' % (self.run_program_prefix,
exe_file),
shell=True)
subprocess.check_call(exe_file, shell=True)
except subprocess.CalledProcessError:
self.note_error(name, self.group_xfail)
return
@@ -726,19 +719,12 @@ def main():
help='C compiler to use')
parser.add_argument('--flags', metavar='CFLAGS',
help='Compiler flags to use with CC')
parser.add_argument('--ldflags', metavar='LDFLAGS',
help='Compiler arguments for linking before inputs')
parser.add_argument('--libs', metavar='LIBS',
help='Compiler arguments for linking after inputs')
parser.add_argument('--run-program-prefix', metavar='RUN-PROGRAM-PREFIX',
help='Wrapper for running newly built program')
parser.add_argument('--cross', action='store_true',
help='Do not run compiled test programs')
parser.add_argument('--xfail', metavar='COND',
help='Name of condition for XFAILs')
args = parser.parse_args()
tests = HeaderTests(args.header, args.standard, args.cc, args.flags,
args.ldflags, args.libs, args.run_program_prefix,
args.cross, args.xfail)
tests.run()
+23 -6
View File
@@ -377,15 +377,32 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
/* This is a current program. Use the dynamic segment to find
constructors. */
call_init (argc, argv, __environ);
/* Auditing checkpoint: we have a new object. */
_dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
#else /* !SHARED */
call_init (argc, argv, __environ);
#endif /* SHARED */
#ifdef SHARED
/* Auditing checkpoint: we have a new object. */
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
struct audit_ifaces *afct = GLRO(dl_audit);
struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->preinit != NULL)
afct->preinit (&link_map_audit_state (head, cnt)->cookie);
afct = afct->next;
}
}
#endif
#ifdef SHARED
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
#endif
#ifndef SHARED
_dl_debug_initialize (0, LM_ID_BASE);
#endif
+38 -75
View File
@@ -1,5 +1,4 @@
# Copyright (C) 1998-2022 Free Software Foundation, Inc.
# Copyright The GNU Toolchain Authors.
# Copyright (C) 1998-2021 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
@@ -109,68 +108,30 @@ CFLAGS-tst-longjmp_chk2.c += -fexceptions -fasynchronous-unwind-tables
CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1
CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
# _FORTIFY_SOURCE tests.
# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and
# preprocessor conditions based on tst-fortify.c.
#
# To add a new test condition, define a cflags-$(cond) make variable to set
# CFLAGS for the file.
tests-all-chk = tst-fortify
tests-c-chk =
tests-cc-chk =
CFLAGS-tst-fortify.c += -Wno-format -Wno-deprecated-declarations -Wno-error
# No additional flags for the default tests.
define cflags-default
endef
define cflags-lfs
CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
endef
define cflags-nongnu
CFLAGS-tst-fortify-$(1)-nongnu-$(2).$(1) += -D_LARGEFILE64_SOURCE=1
endef
src-chk-nongnu = \#undef _GNU_SOURCE
# We know these tests have problems with format strings, this is what
# we are testing. Disable that warning. They are also testing
# deprecated functions (notably gets) so disable that warning as well.
# And they also generate warnings from warning attributes, which
# cannot be disabled via pragmas, so require -Wno-error to be used.
define gen-chk-test
tests-$(1)-chk += tst-fortify-$(1)-$(2)-$(3)
CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
-Wno-deprecated-declarations \
-Wno-error
$(eval $(call cflags-$(2),$(1),$(3)))
$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
( echo "/* Autogenerated from Makefile. */"; \
echo "$(src-chk-$(2))"; \
echo "#include \"tst-fortify.c\"" ) > $$@.tmp
mv $$@.tmp $$@
endef
chk-extensions = c cc
chk-types = default lfs nongnu
chk-levels = 1 2 3
$(foreach e,$(chk-extensions), \
$(foreach t,$(chk-types), \
$(foreach l,$(chk-levels), \
$(eval $(call gen-chk-test,$(e),$(t),$(l))))))
tests-all-chk += $(tests-c-chk) $(tests-cc-chk)
define link-cc
LDLIBS-$(1) = -lstdc++
endef
$(foreach t,$(tests-cc-chk), $(eval $(call link-cc,$(t))))
CFLAGS-tst-chk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-chk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-lfschk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-lfschk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
LDLIBS-tst-chk4 = -lstdc++
LDLIBS-tst-chk5 = -lstdc++
LDLIBS-tst-chk6 = -lstdc++
LDLIBS-tst-lfschk4 = -lstdc++
LDLIBS-tst-lfschk5 = -lstdc++
LDLIBS-tst-lfschk6 = -lstdc++
# backtrace_symbols only works if we link with -rdynamic. backtrace
# requires unwind tables on most architectures.
@@ -187,25 +148,19 @@ LDFLAGS-tst-backtrace6 = -rdynamic
CFLAGS-tst-ssp-1.c += -fstack-protector-all
tests = backtrace-tst \
tst-longjmp_chk \
test-strcpy_chk \
test-stpcpy_chk \
tst-longjmp_chk2 \
tst-backtrace2 \
tst-backtrace3 \
tst-backtrace4 \
tst-backtrace5 \
tst-backtrace6 \
tst-realpath-chk \
$(tests-all-chk)
tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
tst-backtrace5 tst-backtrace6
ifeq ($(have-ssp),yes)
tests += tst-ssp-1
endif
ifeq (,$(CXX))
tests-unsupported = $(tests-cc-chk)
tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
tst-lfschk4 tst-lfschk5 tst-lfschk6
endif
extra-libs = libSegFault libpcprofile
@@ -232,10 +187,18 @@ ifeq ($(run-built-tests),yes)
LOCALES := de_DE.UTF-8
include ../gen-locales.mk
define chk-gen-locales
$(objpfx)$(1).out: $(gen-locales)
endef
$(foreach t, $(tests-all-chk), $(eval $(call chk-gen-locales,$(t))))
$(objpfx)tst-chk1.out: $(gen-locales)
$(objpfx)tst-chk2.out: $(gen-locales)
$(objpfx)tst-chk3.out: $(gen-locales)
$(objpfx)tst-chk4.out: $(gen-locales)
$(objpfx)tst-chk5.out: $(gen-locales)
$(objpfx)tst-chk6.out: $(gen-locales)
$(objpfx)tst-lfschk1.out: $(gen-locales)
$(objpfx)tst-lfschk2.out: $(gen-locales)
$(objpfx)tst-lfschk3.out: $(gen-locales)
$(objpfx)tst-lfschk4.out: $(gen-locales)
$(objpfx)tst-lfschk5.out: $(gen-locales)
$(objpfx)tst-lfschk6.out: $(gen-locales)
endif
sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
+55 -98
View File
@@ -1,5 +1,4 @@
/* Copyright (C) 2004-2022 Free Software Foundation, Inc.
Copyright The GNU Toolchain Authors.
/* Copyright (C) 2004-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
@@ -38,17 +37,6 @@
#include <sys/socket.h>
#include <sys/un.h>
#ifndef _GNU_SOURCE
# define MEMPCPY memcpy
# define WMEMPCPY wmemcpy
# define MEMPCPY_RET(x) 0
# define WMEMPCPY_RET(x) 0
#else
# define MEMPCPY mempcpy
# define WMEMPCPY wmempcpy
# define MEMPCPY_RET(x) __builtin_strlen (x)
# define WMEMPCPY_RET(x) wcslen (x)
#endif
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
@@ -95,14 +83,8 @@ handler (int sig)
_exit (127);
}
#if __USE_FORTIFY_LEVEL == 3
volatile size_t buf_size = 10;
#else
char buf[10];
wchar_t wbuf[10];
#define buf_size sizeof (buf)
#endif
volatile size_t l0;
volatile char *p;
volatile wchar_t *wp;
@@ -141,10 +123,6 @@ int num2 = 987654;
static int
do_test (void)
{
#if __USE_FORTIFY_LEVEL == 3
char *buf = (char *) malloc (buf_size);
wchar_t *wbuf = (wchar_t *) malloc (buf_size * sizeof (wchar_t));
#endif
set_fortify_handler (handler);
struct A { char buf1[9]; char buf2[1]; } a;
@@ -175,7 +153,7 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10))
FAIL ();
if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
if (mempcpy (buf + 5, "abcde", 5) != buf + 10
|| memcmp (buf, "aabcdabcde", 10))
FAIL ();
@@ -220,7 +198,7 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10))
FAIL ();
if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
|| memcmp (buf, "aabcdabcde", 10))
FAIL ();
@@ -279,8 +257,7 @@ do_test (void)
if (memcmp (a.buf1, "aabcdefghi", 10))
FAIL ();
if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
!= a.buf1 + 5 + MEMPCPY_RET ("abcde")
if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
|| memcmp (a.buf1, "aabcdabcde", 10))
FAIL ();
@@ -361,7 +338,6 @@ do_test (void)
bcopy (buf + 1, buf + 2, l0 + 9);
CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START
p = (char *) mempcpy (buf + 6, "abcde", 5);
CHK_FAIL_END
@@ -369,7 +345,6 @@ do_test (void)
CHK_FAIL_START
p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
CHK_FAIL_END
#endif
CHK_FAIL_START
memset (buf + 9, 'j', 2);
@@ -480,7 +455,6 @@ do_test (void)
bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9);
CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START
p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
CHK_FAIL_END
@@ -488,7 +462,6 @@ do_test (void)
CHK_FAIL_START
p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
CHK_FAIL_END
#endif
CHK_FAIL_START
memset (a.buf1 + 9, 'j', 2);
@@ -568,7 +541,7 @@ do_test (void)
if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL ();
if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
|| wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL ();
@@ -601,8 +574,7 @@ do_test (void)
if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL ();
if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
!= wbuf + 5 + WMEMPCPY_RET (L"abcde")
if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
|| wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL ();
@@ -644,8 +616,7 @@ do_test (void)
if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
FAIL ();
if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
!= wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
|| wmemcmp (wa.buf1, L"aabcdabcde", 10))
FAIL ();
@@ -714,7 +685,6 @@ do_test (void)
wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START
wp = wmempcpy (wbuf + 6, L"abcde", 5);
CHK_FAIL_END
@@ -722,7 +692,6 @@ do_test (void)
CHK_FAIL_START
wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
CHK_FAIL_END
#endif
CHK_FAIL_START
wmemset (wbuf + 9, L'j', 2);
@@ -790,7 +759,6 @@ do_test (void)
wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START
wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
CHK_FAIL_END
@@ -798,7 +766,6 @@ do_test (void)
CHK_FAIL_START
wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
CHK_FAIL_END
#endif
CHK_FAIL_START
wmemset (wa.buf1 + 9, L'j', 2);
@@ -930,7 +897,6 @@ do_test (void)
if (fprintf (fp, buf2 + 4, str5) != 7)
FAIL ();
#ifdef _GNU_SOURCE
char *my_ptr = NULL;
strcpy (buf2 + 2, "%n%s%n");
/* When the format string is writable and contains %n,
@@ -960,7 +926,6 @@ do_test (void)
if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
FAIL ();
obstack_free (&obs, NULL);
#endif
if (freopen (temp_filename, "r", stdin) == NULL)
{
@@ -982,95 +947,93 @@ do_test (void)
rewind (stdin);
if (fgets (buf, buf_size, stdin) != buf
if (fgets (buf, sizeof (buf), stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
FAIL ();
rewind (stdin);
if (fgets (buf, l0 + buf_size, stdin) != buf
if (fgets (buf, l0 + sizeof (buf), stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fgets (buf, buf_size + 1, stdin) != buf)
if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fgets (buf, l0 + buf_size + 1, stdin) != buf)
if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
#endif
rewind (stdin);
#ifdef _GNU_SOURCE
if (fgets_unlocked (buf, buf_size, stdin) != buf
if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
if (fgets_unlocked (buf, buf_size, stdin) != buf
if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
|| memcmp (buf, "ABCDEFGHI", 10))
FAIL ();
rewind (stdin);
if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf
if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fgets_unlocked (buf, buf_size + 1, stdin) != buf)
if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf)
if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
#endif
rewind (stdin);
#endif
if (fread (buf, 1, buf_size, stdin) != buf_size
if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread (buf, buf_size, 1, stdin) != 1
if (fread (buf, sizeof (buf), 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
rewind (stdin);
if (fread (buf, l0 + 1, buf_size, stdin) != buf_size
if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread (buf, buf_size, l0 + 1, stdin) != 1
if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1)
if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1)
if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
FAIL ();
CHK_FAIL_END
#endif
rewind (stdin);
if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size
if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread_unlocked (buf, buf_size, 1, stdin) != 1
if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
@@ -1085,100 +1048,100 @@ do_test (void)
rewind (stdin);
if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size
if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1
if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1)
if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1)
if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
FAIL ();
CHK_FAIL_END
#endif
lseek (fileno (stdin), 0, SEEK_SET);
if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|| memcmp (buf, "ABCDEFGHI", 9))
FAIL ();
lseek (fileno (stdin), 0, SEEK_SET);
if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1
if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1)
if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1)
if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
#endif
if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2)
!= buf_size - 1
if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
!= sizeof (buf) - 1
|| memcmp (buf, "\nABCDEFGH", 9))
FAIL ();
if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
!= buf_size - 1
if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
!= sizeof (buf) - 1
|| memcmp (buf, "h\nABCDEFG", 9))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
!= buf_size + 1)
if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
!= buf_size + 1)
if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
#endif
if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2)
!= buf_size - 1
if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
!= sizeof (buf) - 1
|| memcmp (buf, "\nABCDEFGH", 9))
FAIL ();
if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
!= buf_size - 1
if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
!= sizeof (buf) - 1
|| memcmp (buf, "h\nABCDEFG", 9))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
!= buf_size + 1)
if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
!= buf_size + 1)
if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
FAIL ();
CHK_FAIL_END
#endif
@@ -1216,7 +1179,7 @@ do_test (void)
CHK_FAIL2_END
CHK_FAIL2_START
snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4);
snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
CHK_FAIL2_END
int sp[2];
@@ -1606,10 +1569,7 @@ do_test (void)
ret = 1;
}
int fd;
#ifdef _GNU_SOURCE
fd = posix_openpt (O_RDWR);
int fd = posix_openpt (O_RDWR);
if (fd != -1)
{
char enough[1000];
@@ -1625,7 +1585,6 @@ do_test (void)
#endif
close (fd);
}
#endif
#if PATH_MAX > 0
confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
@@ -1743,9 +1702,8 @@ do_test (void)
poll (fds, l0 + 2, 0);
CHK_FAIL_END
#endif
#ifdef _GNU_SOURCE
ppoll (fds, 1, NULL, NULL);
# if __USE_FORTIFY_LEVEL >= 1
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
ppoll (fds, 2, NULL, NULL);
CHK_FAIL_END
@@ -1753,7 +1711,6 @@ do_test (void)
CHK_FAIL_START
ppoll (fds, l0 + 2, NULL, NULL);
CHK_FAIL_END
# endif
#endif
return ret;
+2
View File
@@ -0,0 +1,2 @@
#define _FORTIFY_SOURCE 1
#include "tst-chk1.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FORTIFY_SOURCE 2
#include "tst-chk1.c"
+1
View File
@@ -0,0 +1 @@
#include "tst-chk1.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FORTIFY_SOURCE 1
#include "tst-chk1.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FORTIFY_SOURCE 2
#include "tst-chk1.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk1.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk2.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk3.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk1.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk2.c"
+2
View File
@@ -0,0 +1,2 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk3.c"
-37
View File
@@ -1,37 +0,0 @@
/* Smoke test to verify that realpath does not cause spurious warnings.
Copyright The GNU Toolchain Authors.
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
<https://www.gnu.org/licenses/>. */
#include <limits.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/support.h>
static int
do_test (void)
{
#ifdef PATH_MAX
char buf[PATH_MAX + 1];
char *res = realpath (".", buf);
TEST_VERIFY (res == buf);
#endif
return 0;
}
#include <support/test-driver.c>
+215 -850
View File
File diff suppressed because it is too large Load Diff
-4
View File
@@ -48,9 +48,6 @@ ld {
# stack canary
__stack_chk_guard;
}
GLIBC_2.34 {
__rtld_version_placeholder;
}
GLIBC_PRIVATE {
# Those are in the dynamic linker, but used by libc.so.
__libc_enable_secure;
@@ -58,7 +55,6 @@ ld {
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
_dl_deallocate_tls; _dl_make_stack_executable;
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
_dl_audit_symbind_alt; _dl_audit_preinit;
_rtld_global; _rtld_global_ro;
# Only here for gdb while a better method is developed.
-381
View File
@@ -1,381 +0,0 @@
/* Audit common functions.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <assert.h>
#include <link.h>
#include <ldsodefs.h>
#include <dl-machine.h>
#include <dl-runtime.h>
#include <dl-fixup-attribute.h>
void
_dl_audit_activity_map (struct link_map *l, int action)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&link_map_audit_state (l, cnt)->cookie, action);
afct = afct->next;
}
}
void
_dl_audit_activity_nsid (Lmid_t nsid, int action)
{
/* If head is NULL, the namespace has become empty, and the audit interface
does not give us a way to signal LA_ACT_CONSISTENT for it because the
first loaded module is used to identify the namespace. */
struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
if (__glibc_likely (GLRO(dl_naudit) == 0)
|| head == NULL || head->l_auditing)
return;
_dl_audit_activity_map (head, action);
}
const char *
_dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code)
{
if (l == NULL || l->l_auditing || code == 0)
return name;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objsearch != NULL)
{
struct auditstate *state = link_map_audit_state (l, cnt);
name = afct->objsearch (name, &state->cookie, code);
if (name == NULL)
return NULL;
}
afct = afct->next;
}
return name;
}
void
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
{
if (__glibc_likely (GLRO(dl_naudit) == 0))
return;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objopen != NULL)
{
struct auditstate *state = link_map_audit_state (l, cnt);
state->bindflags = afct->objopen (l, nsid, &state->cookie);
l->l_audit_any_plt |= state->bindflags != 0;
}
afct = afct->next;
}
}
void
_dl_audit_objclose (struct link_map *l)
{
if (__glibc_likely (GLRO(dl_naudit) == 0)
|| GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
return;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objclose != NULL)
{
struct auditstate *state= link_map_audit_state (l, cnt);
/* Return value is ignored. */
afct->objclose (&state->cookie);
}
afct = afct->next;
}
}
void
_dl_audit_preinit (struct link_map *l)
{
if (__glibc_likely (GLRO(dl_naudit) == 0))
return;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->preinit != NULL)
afct->preinit (&link_map_audit_state (l, cnt)->cookie);
afct = afct->next;
}
}
void
_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
lookup_t result)
{
if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
return;
const char *strtab = (const char *) D_PTR (result, l_info[DT_STRTAB]);
/* Compute index of the symbol entry in the symbol table of the DSO with
the definition. */
unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, l_info[DT_SYMTAB]));
unsigned int altvalue = 0;
/* Synthesize a symbol record where the st_value field is the result. */
ElfW(Sym) sym = *ref;
sym.st_value = (ElfW(Addr)) *value;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
struct auditstate *match_audit = link_map_audit_state (l, cnt);
struct auditstate *result_audit = link_map_audit_state (result, cnt);
if (afct->symbind != NULL
&& ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|| ((result_audit->bindflags & LA_FLG_BINDTO)
!= 0)))
{
unsigned int flags = altvalue | LA_SYMB_DLSYM;
uintptr_t new_value = afct->symbind (&sym, ndx,
&match_audit->cookie,
&result_audit->cookie,
&flags, strtab + ref->st_name);
if (new_value != (uintptr_t) sym.st_value)
{
altvalue = LA_SYMB_ALTVALUE;
sym.st_value = new_value;
}
afct = afct->next;
}
*value = (void *) sym.st_value;
}
}
rtld_hidden_def (_dl_audit_symbind_alt)
void
_dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
lookup_t result)
{
bool for_jmp_slot = reloc_result == NULL;
/* Compute index of the symbol entry in the symbol table of the DSO
with the definition. */
unsigned int boundndx = defsym - (ElfW(Sym) *) D_PTR (result,
l_info[DT_SYMTAB]);
if (!for_jmp_slot)
{
reloc_result->bound = result;
reloc_result->boundndx = boundndx;
}
if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
{
/* Set all bits since this symbol binding is not interesting. */
if (!for_jmp_slot)
reloc_result->enterexit = (1u << DL_NNS) - 1;
return;
}
/* Synthesize a symbol record where the st_value field is the result. */
ElfW(Sym) sym = *defsym;
sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
/* Keep track whether there is any interest in tracing the call in the lower
two bits. */
assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
uint32_t enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
unsigned int flags = 0;
struct audit_ifaces *afct = GLRO(dl_audit);
uintptr_t new_value = (uintptr_t) sym.st_value;
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
/* XXX Check whether both DSOs must request action or only one */
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *result_state = link_map_audit_state (result, cnt);
if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
&& (result_state->bindflags & LA_FLG_BINDTO) != 0)
{
if (afct->symbind != NULL)
{
flags |= for_jmp_slot ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT
: 0;
new_value = afct->symbind (&sym, boundndx,
&l_state->cookie,
&result_state->cookie, &flags,
strtab2 + defsym->st_name);
if (new_value != (uintptr_t) sym.st_value)
{
flags |= LA_SYMB_ALTVALUE;
sym.st_value = for_jmp_slot
? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value;
}
}
/* Remember the results for every audit library and store a summary
in the first two bits. */
enterexit &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
enterexit |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
<< ((cnt + 1) * 2));
}
else
/* If the bind flags say this auditor is not interested, set the bits
manually. */
enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
<< ((cnt + 1) * 2));
afct = afct->next;
}
if (!for_jmp_slot)
{
reloc_result->enterexit = enterexit;
reloc_result->flags = flags;
}
DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
}
void
_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize)
{
/* Don't do anything if no auditor wants to intercept this call. */
if (GLRO(dl_naudit) == 0
|| (reloc_result->enterexit & LA_SYMB_NOPLTENTER))
return;
/* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
initialized earlier in this function or in another thread. */
assert (DL_FIXUP_VALUE_CODE_ADDR (*value) != 0);
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);
/* Set up the sym parameter. */
ElfW(Sym) sym = *defsym;
sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
/* Get the symbol name. */
const char *strtab = (const void *) D_PTR (reloc_result->bound,
l_info[DT_STRTAB]);
const char *symname = strtab + sym.st_name;
/* Keep track of overwritten addresses. */
unsigned int flags = reloc_result->flags;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->ARCH_LA_PLTENTER != NULL
&& (reloc_result->enterexit
& (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
{
long int new_framesize = -1;
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *bound_state
= link_map_audit_state (reloc_result->bound, cnt);
uintptr_t new_value
= afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
&l_state->cookie, &bound_state->cookie,
regs, &flags, symname, &new_framesize);
if (new_value != (uintptr_t) sym.st_value)
{
flags |= LA_SYMB_ALTVALUE;
sym.st_value = new_value;
}
/* Remember the results for every audit library and store a summary
in the first two bits. */
reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
| LA_SYMB_NOPLTEXIT))
<< (2 * (cnt + 1)));
if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
<< (2 * (cnt + 1))))
== 0 && new_framesize != -1 && *framesize != -2)
{
/* If this is the first call providing information, use it. */
if (*framesize == -1)
*framesize = new_framesize;
/* If two pltenter calls provide conflicting information, use
the larger value. */
else if (new_framesize != *framesize)
*framesize = MAX (new_framesize, *framesize);
}
}
afct = afct->next;
}
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
}
void
DL_ARCH_FIXUP_ATTRIBUTE
_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
const void *inregs, void *outregs)
{
const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
/* This is the address in the array where we store the result of previous
relocations. */
// XXX Maybe the bound information must be stored on the stack since
// XXX with bind_not a new value could have been stored in the meantime.
struct reloc_result *reloc_result =
&l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);
/* Set up the sym parameter. */
ElfW(Sym) sym = *defsym;
sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
/* Get the symbol name. */
const char *strtab = (const void *) D_PTR (reloc_result->bound,
l_info[DT_STRTAB]);
const char *symname = strtab + sym.st_name;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->ARCH_LA_PLTEXIT != NULL
&& (reloc_result->enterexit
& (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
{
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *bound_state
= link_map_audit_state (reloc_result->bound, cnt);
afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
&l_state->cookie, &bound_state->cookie,
inregs, outregs, symname);
}
afct = afct->next;
}
}
+64 -11
View File
@@ -266,6 +266,9 @@ _dl_close_worker (struct link_map *map, bool force)
used + (nsid == LM_ID_BASE), true);
/* Call all termination functions at once. */
#ifdef SHARED
bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
#endif
bool unload_any = false;
bool scope_mem_left = false;
unsigned int unload_global = 0;
@@ -299,7 +302,22 @@ _dl_close_worker (struct link_map *map, bool force)
#ifdef SHARED
/* Auditing checkpoint: we remove an object. */
_dl_audit_objclose (imap);
if (__glibc_unlikely (do_audit))
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objclose != NULL)
{
struct auditstate *state
= link_map_audit_state (imap, cnt);
/* Return value is ignored. */
(void) afct->objclose (&state->cookie);
}
afct = afct->next;
}
}
#endif
/* This object must not be used anymore. */
@@ -460,7 +478,25 @@ _dl_close_worker (struct link_map *map, bool force)
#ifdef SHARED
/* Auditing checkpoint: we will start deleting objects. */
_dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
if (__glibc_unlikely (do_audit))
{
struct link_map *head = ns->_ns_loaded;
struct audit_ifaces *afct = GLRO(dl_audit);
/* Do not call the functions for any auditing object. */
if (head->l_auditing == 0)
{
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
{
struct auditstate *state = link_map_audit_state (head, cnt);
afct->activity (&state->cookie, LA_ACT_DELETE);
}
afct = afct->next;
}
}
}
#endif
/* Notify the debugger we are about to remove some loaded objects. */
@@ -513,9 +549,6 @@ _dl_close_worker (struct link_map *map, bool force)
size_t tls_free_end;
tls_free_start = tls_free_end = NO_TLS_OFFSET;
/* Protects global and module specitic TLS state. */
__rtld_lock_lock_recursive (GL(dl_load_tls_lock));
/* We modify the list of loaded objects. */
__rtld_lock_lock_recursive (GL(dl_load_write_lock));
@@ -751,13 +784,33 @@ _dl_close_worker (struct link_map *map, bool force)
GL(dl_tls_static_used) = tls_free_start;
}
/* TLS is cleaned up for the unloaded modules. */
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
#ifdef SHARED
/* Auditing checkpoint: we have deleted all objects. Also, do not notify
auditors of the cleanup of a failed audit module loading attempt. */
_dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
/* Auditing checkpoint: we have deleted all objects. */
if (__glibc_unlikely (do_audit))
{
struct link_map *head = ns->_ns_loaded;
/* If head is NULL, the namespace has become empty, and the
audit interface does not give us a way to signal
LA_ACT_CONSISTENT for it because the first loaded module is
used to identify the namespace.
Furthermore, do not notify auditors of the cleanup of a
failed audit module loading attempt. */
if (head != NULL && head->l_auditing == 0)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
{
struct auditstate *state = link_map_audit_state (head, cnt);
afct->activity (&state->cookie, LA_ACT_CONSISTENT);
}
afct = afct->next;
}
}
}
#endif
if (__builtin_expect (ns->_ns_loaded == NULL, 0)
-32
View File
@@ -1,32 +0,0 @@
/* Placeholder compatibility symbols.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <shlib-compat.h>
#include <sys/cdefs.h>
/* GLIBC_2.34 placeholder for future symbol moves. */
void
attribute_compat_text_section
__attribute_used__
__rtld_version_placeholder_1 (void)
{
}
compat_symbol (ld, __rtld_version_placeholder_1,
__rtld_version_placeholder, GLIBC_2_34);
+18 -22
View File
@@ -17,7 +17,6 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <https://www.gnu.org/licenses/>. */
#include <assert.h>
#include <errno.h>
#include <libintl.h>
#include <stdlib.h>
@@ -28,24 +27,6 @@
#include <sys/types.h>
#include "dynamic-link.h"
/* Used at loading time solely for prelink executable. It is not called
concurrently so it is be safe to defined as static. */
static struct link_map *resolve_conflict_map __attribute__ ((__unused__));
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL)
#define RESOLVE(ref, version, flags) (*ref = NULL, 0)
#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
do { \
while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset)) \
|| (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset))) \
resolve_conflict_map = resolve_conflict_map->l_next; \
\
(map) = resolve_conflict_map; \
} while (0)
#include "dynamic-link.h"
void
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
@@ -58,9 +39,24 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
/* Do the conflict relocation of the object and library GOT and other
data. */
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
#define RESOLVE(ref, version, flags) (*ref = NULL, 0)
#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
do { \
while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset)) \
|| (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset))) \
resolve_conflict_map = resolve_conflict_map->l_next; \
\
(map) = resolve_conflict_map; \
} while (0)
/* Prelinking makes no sense for anything but the main namespace. */
assert (l->l_ns == LM_ID_BASE);
resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
struct link_map *resolve_conflict_map __attribute__ ((__unused__))
= GL(dl_ns)[LM_ID_BASE]._ns_loaded;
#include "dynamic-link.h"
/* Override these, defined in dynamic-link.h. */
#undef CHECK_STATIC_TLS
@@ -71,8 +67,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
GL(dl_num_cache_relocations) += conflictend - conflict;
for (; conflict < conflictend; ++conflict)
elf_machine_rela (l, NULL, conflict, NULL, NULL,
(void *) conflict->r_offset, 0);
elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
0);
}
#endif
}
+15 -9
View File
@@ -64,10 +64,6 @@ _dl_fini (void)
__rtld_lock_unlock_recursive (GL(dl_load_lock));
else
{
#ifdef SHARED
_dl_audit_activity_nsid (ns, LA_ACT_DELETE);
#endif
/* Now we can allocate an array to hold all the pointers and
copy the pointers in. */
struct link_map *maps[nloaded];
@@ -151,17 +147,27 @@ _dl_fini (void)
#ifdef SHARED
/* Auditing checkpoint: another object closed. */
_dl_audit_objclose (l);
if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0))
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objclose != NULL)
{
struct auditstate *state
= link_map_audit_state (l, cnt);
/* Return value is ignored. */
(void) afct->objclose (&state->cookie);
}
afct = afct->next;
}
}
#endif
}
/* Correct the previous increment. */
--l->l_direct_opencount;
}
#ifdef SHARED
_dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
#endif
}
}
+112 -57
View File
@@ -58,7 +58,6 @@ struct filebuf
};
#include "dynamic-link.h"
#include "get-dynamic-info.h"
#include <abi-tag.h>
#include <stackinfo.h>
#include <sysdep.h>
@@ -1054,6 +1053,42 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
/* This is the ELF header. We read it in `open_verify'. */
header = (void *) fbp->buf;
/* Signal that we are going to add new objects. */
if (r->r_state == RT_CONSISTENT)
{
#ifdef SHARED
/* Auditing checkpoint: we are going to add new objects. */
if ((mode & __RTLD_AUDIT) == 0
&& __glibc_unlikely (GLRO(dl_naudit) > 0))
{
struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
/* Do not call the functions for any auditing object. */
if (head->l_auditing == 0)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&link_map_audit_state (head, cnt)->cookie,
LA_ACT_ADD);
afct = afct->next;
}
}
}
#endif
/* Notify the debugger we have added some objects. We need to
call _dl_debug_initialize in a static program in case dynamic
linking has not been used before. */
r->r_state = RT_ADD;
_dl_debug_state ();
LIBC_PROBE (map_start, 2, nsid, r);
make_consistent = true;
}
else
assert (r->r_state == RT_ADD);
/* Enter the new object in the list of loaded objects. */
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
if (__glibc_unlikely (l == NULL))
@@ -1095,7 +1130,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
struct loadcmd loadcmds[l->l_phnum];
size_t nloadcmds = 0;
bool has_holes = false;
bool empty_dynamic = false;
/* The struct is initialized to zero so this is not necessary:
l->l_ld = 0;
@@ -1108,16 +1142,13 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
segments are mapped in. We record the addresses it says
verbatim, and later correct for the run-time load address. */
case PT_DYNAMIC:
if (ph->p_filesz == 0)
empty_dynamic = true; /* Usually separate debuginfo. */
else
if (ph->p_filesz)
{
/* Debuginfo only files from "objcopy --only-keep-debug"
contain a PT_DYNAMIC segment with p_filesz == 0. Skip
such a segment to avoid a crash later. */
l->l_ld = (void *) ph->p_vaddr;
l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
}
break;
@@ -1233,13 +1264,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
goto lose;
}
/* This check recognizes most separate debuginfo files. */
if (__glibc_unlikely ((l->l_ld == 0 && type == ET_DYN) || empty_dynamic))
{
errstring = N_("object file has no dynamic section");
goto lose;
}
/* Length of the sections to be loaded. */
maplength = loadcmds[nloadcmds - 1].allocend - loadcmds[0].mapstart;
@@ -1257,10 +1281,18 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
}
}
if (l->l_ld != 0)
if (l->l_ld == 0)
{
if (__glibc_unlikely (type == ET_DYN))
{
errstring = N_("object file has no dynamic section");
goto lose;
}
}
else
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
elf_get_dynamic_info (l);
elf_get_dynamic_info (l, NULL);
/* Make sure we are not dlopen'ing an object that has the
DF_1_NOOPEN flag set, or a PIE object. */
@@ -1475,32 +1507,24 @@ cannot enable executable stack as shared object requires");
/* Now that the object is fully initialized add it to the object list. */
_dl_add_to_namespace_list (l, nsid);
/* Signal that we are going to add new objects. */
if (r->r_state == RT_CONSISTENT)
{
#ifdef SHARED
/* Auditing checkpoint: we are going to add new objects. Since this
is called after _dl_add_to_namespace_list the namespace is guaranteed
to not be empty. */
if ((mode & __RTLD_AUDIT) == 0)
_dl_audit_activity_nsid (nsid, LA_ACT_ADD);
#endif
/* Notify the debugger we have added some objects. We need to
call _dl_debug_initialize in a static program in case dynamic
linking has not been used before. */
r->r_state = RT_ADD;
_dl_debug_state ();
LIBC_PROBE (map_start, 2, nsid, r);
make_consistent = true;
}
else
assert (r->r_state == RT_ADD);
#ifdef SHARED
/* Auditing checkpoint: we have a new object. */
if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
_dl_audit_objopen (l, nsid);
if (__glibc_unlikely (GLRO(dl_naudit) > 0)
&& !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objopen != NULL)
{
struct auditstate *state = link_map_audit_state (l, cnt);
state->bindflags = afct->objopen (l, nsid, &state->cookie);
l->l_audit_any_plt |= state->bindflags != 0;
}
afct = afct->next;
}
}
#endif
return l;
@@ -1596,20 +1620,32 @@ open_verify (const char *name, int fd,
#ifdef SHARED
/* Give the auditing libraries a chance. */
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
&& loader->l_auditing == 0)
{
const char *original_name = name;
name = _dl_audit_objsearch (name, loader, whatcode);
if (name == NULL)
return -1;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objsearch != NULL)
{
struct auditstate *state = link_map_audit_state (loader, cnt);
name = afct->objsearch (name, &state->cookie, whatcode);
if (name == NULL)
/* Ignore the path. */
return -1;
}
afct = afct->next;
}
if (fd != -1 && name != original_name && strcmp (name, original_name))
{
/* An audit library changed what we're supposed to open,
so FD no longer matches it. */
__close_nocancel (fd);
fd = -1;
}
{
/* An audit library changed what we're supposed to open,
so FD no longer matches it. */
__close_nocancel (fd);
fd = -1;
}
}
#endif
@@ -2048,17 +2084,36 @@ _dl_map_object (struct link_map *loader, const char *name,
#ifdef SHARED
/* Give the auditing libraries a chance to change the name before we
try anything. */
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
if (__glibc_unlikely (GLRO(dl_naudit) > 0)
&& (loader == NULL || loader->l_auditing == 0))
{
const char *before = name;
name = _dl_audit_objsearch (name, loader, LA_SER_ORIG);
if (name == NULL)
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
fd = -1;
goto no_file;
if (afct->objsearch != NULL)
{
const char *before = name;
struct auditstate *state = link_map_audit_state (loader, cnt);
name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
if (name == NULL)
{
/* Do not try anything further. */
fd = -1;
goto no_file;
}
if (before != name && strcmp (before, name) != 0)
{
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
_dl_debug_printf ("audit changed filename %s -> %s\n",
before, name);
if (origname == NULL)
origname = before;
}
}
afct = afct->next;
}
if (before != name && strcmp (before, name) != 0)
origname = before;
}
#endif
+7 -10
View File
@@ -59,19 +59,16 @@ _dl_new_object (char *realname, const char *libname, int type,
{
#ifdef SHARED
unsigned int naudit;
if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0))
if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0))
{
if (mode & __RTLD_OPENEXEC)
{
assert (type == lt_executable);
assert (nsid == LM_ID_BASE);
assert (type == lt_executable);
assert (nsid == LM_ID_BASE);
/* Ignore the specified libname for the main executable. It is
only known with an explicit loader invocation. */
libname = "";
}
/* Ignore the specified libname for the main executable. It is
only known with an explicit loader invocation. */
libname = "";
/* We create the map for the executable and vDSO before we know whether
/* We create the map for the executable before we know whether
we have auditing libraries and if yes, how many. Assume the
worst. */
naudit = DL_NNS;
+32 -38
View File
@@ -66,9 +66,6 @@ struct dl_open_args
libc_map value in the namespace in case of a dlopen failure. */
bool libc_already_loaded;
/* Set to true if the end of dl_open_worker_begin was reached. */
bool worker_continue;
/* Original parameters to the program and the current environment. */
int argc;
char **argv;
@@ -485,7 +482,7 @@ call_dl_init (void *closure)
}
static void
dl_open_worker_begin (void *a)
dl_open_worker (void *a)
{
struct dl_open_args *args = a;
const char *file = args->file;
@@ -611,7 +608,25 @@ dl_open_worker_begin (void *a)
#ifdef SHARED
/* Auditing checkpoint: we have added all objects. */
_dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
/* Do not call the functions for any auditing object. */
if (head->l_auditing == 0)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
{
struct auditstate *state = link_map_audit_state (head, cnt);
afct->activity (&state->cookie, LA_ACT_CONSISTENT);
}
afct = afct->next;
}
}
}
#endif
/* Notify the debugger all new objects are now ready to go. */
@@ -754,41 +769,18 @@ dl_open_worker_begin (void *a)
namespace. */
if (!args->libc_already_loaded)
{
/* dlopen cannot be used to load an initial libc by design. */
struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map;
_dl_call_libc_early_init (libc_map, false);
#ifdef SHARED
bool initial = libc_map->l_ns == LM_ID_BASE;
#else
/* In the static case, there is only one namespace, but it
contains a secondary libc (the primary libc is statically
linked). */
bool initial = false;
#endif
_dl_call_libc_early_init (libc_map, initial);
}
args->worker_continue = true;
}
static void
dl_open_worker (void *a)
{
struct dl_open_args *args = a;
args->worker_continue = false;
{
/* Protects global and module specific TLS state. */
__rtld_lock_lock_recursive (GL(dl_load_tls_lock));
struct dl_exception ex;
int err = _dl_catch_exception (&ex, dl_open_worker_begin, args);
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
if (__glibc_unlikely (ex.errstring != NULL))
/* Reraise the error. */
_dl_signal_exception (err, &ex, NULL);
}
if (!args->worker_continue)
return;
int mode = args->mode;
struct link_map *new = args->map;
/* Run the initializer functions of new objects. Temporarily
disable the exception handler, so that lazy binding failures are
fatal. */
@@ -901,7 +893,7 @@ no more namespaces available for dlmopen()"));
/* Avoid keeping around a dangling reference to the libc.so link
map in case it has been cached in libc_map. */
if (!args.libc_already_loaded)
GL(dl_ns)[args.nsid].libc_map = NULL;
GL(dl_ns)[nsid].libc_map = NULL;
/* Remove the object from memory. It may be in an inconsistent
state if relocation failed, for example. */
@@ -914,6 +906,8 @@ no more namespaces available for dlmopen()"));
the flag here. */
}
assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
/* Release the lock. */
__rtld_lock_unlock_recursive (GL(dl_load_lock));
+8 -20
View File
@@ -19,16 +19,9 @@
#if ENABLE_STATIC_PIE
/* Mark symbols hidden in static PIE for early self relocation to work. */
# pragma GCC visibility push(hidden)
#include <assert.h>
#include <unistd.h>
#include <ldsodefs.h>
#include <dl-machine.h>
#define STATIC_PIE_BOOTSTRAP
#define RESOLVE_MAP(map, scope, sym, version, flags) map
#include "dynamic-link.h"
#include "get-dynamic-info.h"
/* Relocate static executable with PIE. */
@@ -37,30 +30,25 @@ _dl_relocate_static_pie (void)
{
struct link_map *main_map = _dl_get_dl_main_map ();
# define STATIC_PIE_BOOTSTRAP
# define BOOTSTRAP_MAP (main_map)
# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
# include "dynamic-link.h"
/* Figure out the run-time load address of static PIE. */
main_map->l_addr = elf_machine_load_address ();
/* Read our own dynamic section and fill in the info array. */
main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
const ElfW(Phdr) *ph, *phdr = GL(dl_phdr);
size_t phnum = GL(dl_phnum);
for (ph = phdr; ph < &phdr[phnum]; ++ph)
if (ph->p_type == PT_DYNAMIC)
{
main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
break;
}
elf_get_dynamic_info (main_map);
elf_get_dynamic_info (main_map, NULL);
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, main_map->l_info);
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info);
# endif
/* Relocate ourselves so we can do normal function calls and
data access using the global offset table. */
ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
main_map->l_relocated = 1;
/* Initialize _r_debug. */
+32 -45
View File
@@ -162,32 +162,6 @@ _dl_nothread_init_static_tls (struct link_map *map)
}
#endif /* !THREAD_GSCOPE_IN_TCB */
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(l, scope, ref, version, r_type) \
((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
&& __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \
? ((__glibc_unlikely ((*ref) == l->l_lookup_cache.sym) \
&& elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \
? (bump_num_cache_relocations (), \
(*ref) = l->l_lookup_cache.ret, \
l->l_lookup_cache.value) \
: ({ lookup_t _lr; \
int _tc = elf_machine_type_class (r_type); \
l->l_lookup_cache.type_class = _tc; \
l->l_lookup_cache.sym = (*ref); \
const struct r_found_version *v = NULL; \
if ((version) != NULL && (version)->hash != 0) \
v = (version); \
_lr = _dl_lookup_symbol_x ((const char *) D_PTR (l, l_info[DT_STRTAB]) + (*ref)->st_name, \
l, (ref), scope, v, _tc, \
DL_LOOKUP_ADD_DEPENDENCY \
| DL_LOOKUP_FOR_RELOCATE, NULL); \
l->l_lookup_cache.ret = (*ref); \
l->l_lookup_cache.value = _lr; })) \
: l)
#include "dynamic-link.h"
void
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
int reloc_mode, int consider_profiling)
@@ -205,28 +179,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
int skip_ifunc = reloc_mode & __RTLD_NOIFUNC;
#ifdef SHARED
bool consider_symbind = false;
/* If we are auditing, install the same handlers we need for profiling. */
if ((reloc_mode & __RTLD_AUDIT) == 0)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
/* Profiling is needed only if PLT hooks are provided. */
if (afct->ARCH_LA_PLTENTER != NULL
|| afct->ARCH_LA_PLTEXIT != NULL)
consider_profiling = 1;
if (afct->symbind != NULL)
consider_symbind = true;
afct = afct->next;
}
}
consider_profiling |= GLRO(dl_audit) != NULL;
#elif defined PROF
/* Never use dynamic linker profiling for gprof profiling code. */
# define consider_profiling 0
#else
# define consider_symbind 0
#endif
if (l->l_relocated)
@@ -285,10 +243,39 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
{
/* Do the actual relocation of the object's GOT and other data. */
ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
/* String table object symbols. */
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, r_type) \
((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
&& __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \
? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \
&& elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \
? (bump_num_cache_relocations (), \
(*ref) = l->l_lookup_cache.ret, \
l->l_lookup_cache.value) \
: ({ lookup_t _lr; \
int _tc = elf_machine_type_class (r_type); \
l->l_lookup_cache.type_class = _tc; \
l->l_lookup_cache.sym = (*ref); \
const struct r_found_version *v = NULL; \
if ((version) != NULL && (version)->hash != 0) \
v = (version); \
_lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref), \
scope, v, _tc, \
DL_LOOKUP_ADD_DEPENDENCY \
| DL_LOOKUP_FOR_RELOCATE, NULL); \
l->l_lookup_cache.ret = (*ref); \
l->l_lookup_cache.value = _lr; })) \
: l)
#include "dynamic-link.h"
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
#ifndef PROF
if ((consider_profiling || consider_symbind)
if (__glibc_unlikely (consider_profiling)
&& l->l_info[DT_PLTRELSZ] != NULL)
{
/* Allocate the array which will contain the already found
+216 -37
View File
@@ -16,8 +16,9 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */
#include <alloca.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
@@ -29,6 +30,19 @@
#include <dl-runtime.h>
#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|| ELF_MACHINE_NO_REL
# define PLTREL ElfW(Rela)
#else
# define PLTREL ElfW(Rel)
#endif
/* The fixup functions might have need special attributes. If none
are provided define the macro as empty. */
#ifndef ARCH_FIXUP_ATTRIBUTE
# define ARCH_FIXUP_ATTRIBUTE
#endif
/* This function is called through a special trampoline from the PLT the
first time each PLT entry is called. We must perform the relocation
specified in the PLT of the given shared object, and return the resolved
@@ -37,7 +51,7 @@
function. */
DL_FIXUP_VALUE_TYPE
attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
_dl_fixup (
# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@@ -124,37 +138,6 @@ _dl_fixup (
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
#ifdef SHARED
/* Auditing checkpoint: we have a new binding. Provide the auditing
libraries the possibility to change the value and tell us whether further
auditing is wanted.
The l_reloc_result is only allocated if there is an audit module which
provides a la_symbind. */
if (l->l_reloc_result != NULL)
{
/* This is the address in the array where we store the result of previous
relocations. */
struct reloc_result *reloc_result
= &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
unsigned int init = atomic_load_acquire (&reloc_result->init);
if (init == 0)
{
_dl_audit_symbind (l, reloc_result, sym, &value, result);
/* Store the result for later runs. */
if (__glibc_likely (! GLRO(dl_bind_not)))
{
reloc_result->addr = value;
/* Guarantee all previous writes complete before init is
updated. See CONCURRENCY NOTES below. */
atomic_store_release (&reloc_result->init, 1);
}
}
else
value = reloc_result->addr;
}
#endif
/* Finally, fix up the plt itself. */
if (__glibc_unlikely (GLRO(dl_bind_not)))
return value;
@@ -164,8 +147,7 @@ _dl_fixup (
#ifndef PROF
DL_FIXUP_VALUE_TYPE
__attribute ((noinline))
DL_ARCH_FIXUP_ATTRIBUTE
__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
_dl_profile_fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@@ -314,7 +296,84 @@ _dl_profile_fixup (
auditing libraries the possibility to change the value and
tell us whether further auditing is wanted. */
if (defsym != NULL && GLRO(dl_naudit) > 0)
_dl_audit_symbind (l, reloc_result, defsym, &value, result);
{
reloc_result->bound = result;
/* Compute index of the symbol entry in the symbol table of
the DSO with the definition. */
reloc_result->boundndx = (defsym
- (ElfW(Sym) *) D_PTR (result,
l_info[DT_SYMTAB]));
/* Determine whether any of the two participating DSOs is
interested in auditing. */
if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0)
{
unsigned int flags = 0;
struct audit_ifaces *afct = GLRO(dl_audit);
/* Synthesize a symbol record where the st_value field is
the result. */
ElfW(Sym) sym = *defsym;
sym.st_value = DL_FIXUP_VALUE_ADDR (value);
/* Keep track whether there is any interest in tracing
the call in the lower two bits. */
assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
const char *strtab2 = (const void *) D_PTR (result,
l_info[DT_STRTAB]);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
/* XXX Check whether both DSOs must request action or
only one */
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *result_state
= link_map_audit_state (result, cnt);
if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
&& (result_state->bindflags & LA_FLG_BINDTO) != 0)
{
if (afct->symbind != NULL)
{
uintptr_t new_value
= afct->symbind (&sym, reloc_result->boundndx,
&l_state->cookie,
&result_state->cookie,
&flags,
strtab2 + defsym->st_name);
if (new_value != (uintptr_t) sym.st_value)
{
flags |= LA_SYMB_ALTVALUE;
sym.st_value = new_value;
}
}
/* Remember the results for every audit library and
store a summary in the first two bits. */
reloc_result->enterexit
&= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
reloc_result->enterexit
|= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
<< ((cnt + 1) * 2));
}
else
/* If the bind flags say this auditor is not interested,
set the bits manually. */
reloc_result->enterexit
|= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
<< ((cnt + 1) * 2));
afct = afct->next;
}
reloc_result->flags = flags;
value = DL_FIXUP_ADDR_VALUE (sym.st_value);
}
else
/* Set all bits since this symbol binding is not interesting. */
reloc_result->enterexit = (1u << DL_NNS) - 1;
}
#endif
/* Store the result for later runs. */
@@ -337,7 +396,78 @@ _dl_profile_fixup (
#ifdef SHARED
/* Auditing checkpoint: report the PLT entering and allow the
auditors to change the value. */
_dl_audit_pltenter (l, reloc_result, &value, regs, &framesize);
if (GLRO(dl_naudit) > 0
/* Don't do anything if no auditor wants to intercept this call. */
&& (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
{
/* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
initialized earlier in this function or in another thread. */
assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);
/* Set up the sym parameter. */
ElfW(Sym) sym = *defsym;
sym.st_value = DL_FIXUP_VALUE_ADDR (value);
/* Get the symbol name. */
const char *strtab = (const void *) D_PTR (reloc_result->bound,
l_info[DT_STRTAB]);
const char *symname = strtab + sym.st_name;
/* Keep track of overwritten addresses. */
unsigned int flags = reloc_result->flags;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->ARCH_LA_PLTENTER != NULL
&& (reloc_result->enterexit
& (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
{
long int new_framesize = -1;
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *bound_state
= link_map_audit_state (reloc_result->bound, cnt);
uintptr_t new_value
= afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
&l_state->cookie,
&bound_state->cookie,
regs, &flags, symname,
&new_framesize);
if (new_value != (uintptr_t) sym.st_value)
{
flags |= LA_SYMB_ALTVALUE;
sym.st_value = new_value;
}
/* Remember the results for every audit library and
store a summary in the first two bits. */
reloc_result->enterexit
|= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
<< (2 * (cnt + 1)));
if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
<< (2 * (cnt + 1))))
== 0 && new_framesize != -1 && framesize != -2)
{
/* If this is the first call providing information,
use it. */
if (framesize == -1)
framesize = new_framesize;
/* If two pltenter calls provide conflicting information,
use the larger value. */
else if (new_framesize != framesize)
framesize = MAX (new_framesize, framesize);
}
}
afct = afct->next;
}
value = DL_FIXUP_ADDR_VALUE (sym.st_value);
}
#endif
/* Store the frame size information. */
@@ -349,3 +479,52 @@ _dl_profile_fixup (
}
#endif /* PROF */
#include <stdio.h>
void
ARCH_FIXUP_ATTRIBUTE
_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
const void *inregs, void *outregs)
{
#ifdef SHARED
const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
/* This is the address in the array where we store the result of previous
relocations. */
// XXX Maybe the bound information must be stored on the stack since
// XXX with bind_not a new value could have been stored in the meantime.
struct reloc_result *reloc_result =
&l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);
/* Set up the sym parameter. */
ElfW(Sym) sym = *defsym;
sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
/* Get the symbol name. */
const char *strtab = (const void *) D_PTR (reloc_result->bound,
l_info[DT_STRTAB]);
const char *symname = strtab + sym.st_name;
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->ARCH_LA_PLTEXIT != NULL
&& (reloc_result->enterexit
& (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
{
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *bound_state
= link_map_audit_state (reloc_result->bound, cnt);
afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
&l_state->cookie, &bound_state->cookie,
inregs, outregs, symname);
}
afct = afct->next;
}
#endif
}
-51
View File
@@ -1,51 +0,0 @@
/* Inline functions for dynamic linking.
Copyright (C) 1995-2021 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
<https://www.gnu.org/licenses/>. */
#ifndef _DL_STATIC_TLS_H
#define _DL_STATIC_TLS_H
/* This macro is used as a callback from elf_machine_rel{a,} when a
static TLS reloc is about to be performed. Since (in dl-load.c) we
permit dynamic loading of objects that might use such relocs, we
have to check whether each use is actually doable. If the object
whose TLS segment the reference resolves to was allocated space in
the static TLS block at startup, then it's ok. Otherwise, we make
an attempt to allocate it in surplus space on the fly. If that
can't be done, we fall back to the error that DF_STATIC_TLS is
intended to produce. */
#define HAVE_STATIC_TLS(map, sym_map) \
(__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET \
&& ((sym_map)->l_tls_offset \
!= FORCED_DYNAMIC_TLS_OFFSET), 1))
#define CHECK_STATIC_TLS(map, sym_map) \
do { \
if (!HAVE_STATIC_TLS (map, sym_map)) \
_dl_allocate_static_tls (sym_map); \
} while (0)
#define TRY_STATIC_TLS(map, sym_map) \
(__builtin_expect ((sym_map)->l_tls_offset \
!= FORCED_DYNAMIC_TLS_OFFSET, 1) \
&& (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1) \
|| _dl_try_allocate_static_tls (sym_map, true) == 0))
int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
attribute_hidden;
#endif
-15
View File
@@ -229,13 +229,6 @@ __rtld_lock_define_initialized_recursive (, _dl_load_lock)
list of loaded objects while an object is added to or removed from
that list. */
__rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
/* This lock protects global and module specific TLS related data.
E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
accessed and when TLS related relocations are processed for a
module. It was introduced to keep pthread_create accessing TLS
state that is being set up. */
__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
#ifdef HAVE_AUX_VECTOR
@@ -435,11 +428,3 @@ _dl_get_dl_main_map (void)
return &_dl_main_map;
}
#endif
/* This is used by _dl_runtime_profile, not used on static code. */
void
DL_ARCH_FIXUP_ATTRIBUTE
_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
const void *inregs, void *outregs)
{
}
+46 -1
View File
@@ -52,9 +52,54 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value,
tell us whether further auditing is wanted. */
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
const char *strtab = (const char *) D_PTR (result,
l_info[DT_STRTAB]);
/* Compute index of the symbol entry in the symbol table of
the DSO with the definition. */
unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
l_info[DT_SYMTAB]));
if (match == NULL)
match = _dl_sym_find_caller_link_map (caller);
_dl_audit_symbind_alt (match, ref, &value, result);
if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
{
unsigned int altvalue = 0;
struct audit_ifaces *afct = GLRO(dl_audit);
/* Synthesize a symbol record where the st_value field is
the result. */
ElfW(Sym) sym = *ref;
sym.st_value = (ElfW(Addr)) value;
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
struct auditstate *match_audit
= link_map_audit_state (match, cnt);
struct auditstate *result_audit
= link_map_audit_state (result, cnt);
if (afct->symbind != NULL
&& ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|| ((result_audit->bindflags & LA_FLG_BINDTO)
!= 0)))
{
unsigned int flags = altvalue | LA_SYMB_DLSYM;
uintptr_t new_value
= afct->symbind (&sym, ndx,
&match_audit->cookie,
&result_audit->cookie,
&flags, strtab + ref->st_name);
if (new_value != (uintptr_t) sym.st_value)
{
altvalue = LA_SYMB_ALTVALUE;
sym.st_value = new_value;
}
}
afct = afct->next;
}
value = (void *) sym.st_value;
}
}
#endif
return value;
+1 -1
View File
@@ -317,7 +317,7 @@ _dl_show_auxv (void)
[AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex },
[AT_RANDOM - 2] = { "RANDOM: 0x", hex },
[AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex },
[AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec },
[AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ ", dec },
[AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec },
[AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex },
[AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec },
+11 -22
View File
@@ -519,12 +519,8 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
}
/* Allocate initial TLS. RESULT should be a non-NULL pointer to storage
for the TLS space. The DTV may be resized, and so this function may
call malloc to allocate that space. The loader's GL(dl_load_tls_lock)
is taken when manipulating global TLS-related data in the loader. */
void *
_dl_allocate_tls_init (void *result, bool init_tls)
_dl_allocate_tls_init (void *result)
{
if (result == NULL)
/* The memory allocation failed. */
@@ -536,7 +532,7 @@ _dl_allocate_tls_init (void *result, bool init_tls)
size_t maxgen = 0;
/* Protects global dynamic TLS related state. */
__rtld_lock_lock_recursive (GL(dl_load_tls_lock));
__rtld_lock_lock_recursive (GL(dl_load_lock));
/* Check if the current dtv is big enough. */
if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
@@ -597,14 +593,7 @@ _dl_allocate_tls_init (void *result, bool init_tls)
some platforms use in static programs requires it. */
dtv[map->l_tls_modid].pointer.val = dest;
/* Copy the initialization image and clear the BSS part. For
audit modules or dependencies with initial-exec TLS, we can not
set the initial TLS image on default loader initialization
because it would already be set by the audit setup. However,
subsequent thread creation would need to follow the default
behaviour. */
if (map->l_ns != LM_ID_BASE && !init_tls)
continue;
/* Copy the initialization image and clear the BSS part. */
memset (__mempcpy (dest, map->l_tls_initimage,
map->l_tls_initimage_size), '\0',
map->l_tls_blocksize - map->l_tls_initimage_size);
@@ -617,7 +606,7 @@ _dl_allocate_tls_init (void *result, bool init_tls)
listp = listp->next;
assert (listp != NULL);
}
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
__rtld_lock_unlock_recursive (GL(dl_load_lock));
/* The DTV version is up-to-date now. */
dtv[0].counter = maxgen;
@@ -631,7 +620,7 @@ _dl_allocate_tls (void *mem)
{
return _dl_allocate_tls_init (mem == NULL
? _dl_allocate_tls_storage ()
: allocate_dtv (mem), true);
: allocate_dtv (mem));
}
rtld_hidden_def (_dl_allocate_tls)
@@ -756,7 +745,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
Here the dtv needs to be updated to new_gen generation count.
This code may be called during TLS access when GL(dl_load_tls_lock)
This code may be called during TLS access when GL(dl_load_lock)
is not held. In that case the user code has to synchronize with
dlopen and dlclose calls of relevant modules. A module m is
relevant if the generation of m <= new_gen and dlclose of m is
@@ -878,11 +867,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
if (__glibc_unlikely (the_map->l_tls_offset
!= FORCED_DYNAMIC_TLS_OFFSET))
{
__rtld_lock_lock_recursive (GL(dl_load_tls_lock));
__rtld_lock_lock_recursive (GL(dl_load_lock));
if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
{
the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
__rtld_lock_unlock_recursive (GL(dl_load_lock));
}
else if (__glibc_likely (the_map->l_tls_offset
!= FORCED_DYNAMIC_TLS_OFFSET))
@@ -894,7 +883,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
__rtld_lock_unlock_recursive (GL(dl_load_lock));
dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
dtv[GET_ADDR_MODULE].pointer.val = p;
@@ -902,7 +891,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
return (char *) p + GET_ADDR_OFFSET;
}
else
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
__rtld_lock_unlock_recursive (GL(dl_load_lock));
}
struct dtv_pointer result = allocate_and_init (the_map);
dtv[GET_ADDR_MODULE].pointer = result;
@@ -973,7 +962,7 @@ _dl_tls_get_addr_soft (struct link_map *l)
return NULL;
dtv_t *dtv = THREAD_DTV ();
/* This may be called without holding the GL(dl_load_tls_lock). Reading
/* This may be called without holding the GL(dl_load_lock). Reading
arbitrary gen value is fine since this is best effort code. */
size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
if (__glibc_unlikely (dtv[0].counter != gen))
+19 -50
View File
@@ -16,8 +16,6 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <ldsodefs.h>
/* This file may be included twice, to define both
`elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */
@@ -39,8 +37,8 @@
relocations; they should be set up to call _dl_runtime_resolve, rather
than fully resolved now. */
static inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
auto inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map,
ElfW(Addr) reladdr, ElfW(Addr) relsize,
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
int lazy, int skip_ifunc)
@@ -70,13 +68,13 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
}
else
# endif
elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc);
elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
for (; r2 <= end2; ++r2)
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc);
elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc);
# endif
}
else
@@ -125,10 +123,6 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
for (; r < end; ++r)
{
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
void *const r_addr_arg = (void *) (l_addr + r->r_offset);
const struct r_found_version *rversion = &map->l_versions[ndx];
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
{
@@ -139,19 +133,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
}
#endif
elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg,
skip_ifunc);
#if defined SHARED && !defined RTLD_BOOTSTRAP
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
&& GLRO(dl_naudit) > 0)
{
struct link_map *sym_map
= RESOLVE_MAP (map, scope, &sym, rversion,
ELF_MACHINE_JMP_SLOT);
if (sym != NULL)
_dl_audit_symbind (map, NULL, sym, r_addr_arg, sym_map);
}
#endif
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r->r_offset), skip_ifunc);
}
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
@@ -161,7 +146,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
{
ElfW(Half) ndx
= version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
elf_machine_rel (map, scope, r2,
elf_machine_rel (map, r2,
&symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r2->r_offset),
@@ -173,39 +158,23 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
else
{
for (; r < end; ++r)
{
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
void *const r_addr_arg = (void *) (l_addr + r->r_offset);
# ifdef ELF_MACHINE_IRELATIVE
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
{
if (r2 == NULL)
r2 = r;
end2 = r;
continue;
}
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
{
if (r2 == NULL)
r2 = r;
end2 = r;
}
else
# endif
elf_machine_rel (map, scope, r, sym, NULL, r_addr_arg,
skip_ifunc);
# if defined SHARED && !defined RTLD_BOOTSTRAP
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_JMP_SLOT
&& GLRO(dl_naudit) > 0)
{
struct link_map *sym_map
= RESOLVE_MAP (map, scope, &sym,
(struct r_found_version *) NULL,
ELF_MACHINE_JMP_SLOT);
if (sym != NULL)
_dl_audit_symbind (map, NULL , sym,r_addr_arg, sym_map);
}
# endif
}
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
(void *) (l_addr + r->r_offset), skip_ifunc);
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
for (; r2 <= end2; ++r2)
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
NULL, (void *) (l_addr + r2->r_offset),
skip_ifunc);
# endif
+61 -31
View File
@@ -16,7 +16,35 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <dl-machine.h>
/* This macro is used as a callback from elf_machine_rel{a,} when a
static TLS reloc is about to be performed. Since (in dl-load.c) we
permit dynamic loading of objects that might use such relocs, we
have to check whether each use is actually doable. If the object
whose TLS segment the reference resolves to was allocated space in
the static TLS block at startup, then it's ok. Otherwise, we make
an attempt to allocate it in surplus space on the fly. If that
can't be done, we fall back to the error that DF_STATIC_TLS is
intended to produce. */
#define HAVE_STATIC_TLS(map, sym_map) \
(__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET \
&& ((sym_map)->l_tls_offset \
!= FORCED_DYNAMIC_TLS_OFFSET), 1))
#define CHECK_STATIC_TLS(map, sym_map) \
do { \
if (!HAVE_STATIC_TLS (map, sym_map)) \
_dl_allocate_static_tls (sym_map); \
} while (0)
#define TRY_STATIC_TLS(map, sym_map) \
(__builtin_expect ((sym_map)->l_tls_offset \
!= FORCED_DYNAMIC_TLS_OFFSET, 1) \
&& (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1) \
|| _dl_try_allocate_static_tls (sym_map, true) == 0))
int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
attribute_hidden;
#include <elf.h>
#ifdef RESOLVE_MAP
@@ -31,38 +59,40 @@
copying memory, breaking the very code written to handle the
unaligned cases. */
# if ! ELF_MACHINE_NO_REL
static inline void __attribute__((always_inline))
elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
const struct r_found_version *version,
auto inline void __attribute__((always_inline))
elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
void *const reloc_addr, int skip_ifunc);
static inline void __attribute__((always_inline))
auto inline void __attribute__((always_inline))
elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
void *const reloc_addr);
# endif
# if ! ELF_MACHINE_NO_RELA
static inline void __attribute__((always_inline))
elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
const struct r_found_version *version, void *const reloc_addr,
int skip_ifunc);
static inline void __attribute__((always_inline))
auto inline void __attribute__((always_inline))
elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
void *const reloc_addr, int skip_ifunc);
auto inline void __attribute__((always_inline))
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
void *const reloc_addr);
# endif
# if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
static inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
int skip_ifunc);
# else
static inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
int skip_ifunc);
# endif
#endif
#include <dl-machine.h>
#include "get-dynamic-info.h"
#ifdef RESOLVE_MAP
# if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
@@ -84,7 +114,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
are completely separate and there is a gap between them. */
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
@@ -122,18 +152,18 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
} \
\
if (ELF_DURING_STARTUP) \
elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size, \
ranges[0].nrelative, 0, skip_ifunc); \
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
ranges[0].nrelative, 0, skip_ifunc); \
else \
{ \
int ranges_index; \
for (ranges_index = 0; ranges_index < 2; ++ranges_index) \
elf_dynamic_do_##reloc ((map), scope, \
elf_dynamic_do_##reloc ((map), \
ranges[ranges_index].start, \
ranges[ranges_index].size, \
ranges[ranges_index].nrelative, \
ranges[ranges_index].lazy, \
skip_ifunc); \
skip_ifunc); \
} \
} while (0)
@@ -145,29 +175,29 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL)
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
# else
# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) /* Nothing to do. */
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */
# endif
# if ! ELF_MACHINE_NO_RELA
# define DO_RELA
# include "do-rel.h"
# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL)
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
# else
# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */
# endif
/* This can't just be an inline function because GCC is too dumb
to inline functions containing inlines themselves. */
# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \
do { \
int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \
int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
(consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
} while (0)
#endif
+38 -14
View File
@@ -16,17 +16,19 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* Populate dynamic tags in l_info. */
#ifndef _GET_DYNAMIC_INFO_H
#define _GET_DYNAMIC_INFO_H
/* This file is included multiple times and therefore lacks a header
file inclusion guard. */
#include <assert.h>
#include <dl-machine-rel.h>
#include <libc-diag.h>
static inline void __attribute__ ((unused, always_inline))
elf_get_dynamic_info (struct link_map *l)
#ifndef RESOLVE_MAP
static
#else
auto
#endif
inline void __attribute__ ((unused, always_inline))
elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
{
#if __ELF_NATIVE_CLASS == 32
typedef Elf32_Word d_tag_utype;
@@ -34,7 +36,7 @@ elf_get_dynamic_info (struct link_map *l)
typedef Elf64_Xword d_tag_utype;
#endif
#ifndef STATIC_PIE_BOOTSTRAP
#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP
if (l->l_ld == NULL)
return;
#endif
@@ -67,15 +69,28 @@ elf_get_dynamic_info (struct link_map *l)
info[i] = dyn;
}
#define DL_RO_DYN_TEMP_CNT 8
#ifndef DL_RO_DYN_SECTION
/* Don't adjust .dynamic unnecessarily. */
if (l->l_addr != 0 && dl_relocate_ld (l))
if (l->l_addr != 0)
{
ElfW(Addr) l_addr = l->l_addr;
int cnt = 0;
# define ADJUST_DYN_INFO(tag) \
do \
if (info[tag] != NULL) \
info[tag]->d_un.d_ptr += l_addr; \
{ \
if (temp) \
{ \
temp[cnt].d_tag = info[tag]->d_tag; \
temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
info[tag] = temp + cnt++; \
} \
else \
info[tag]->d_un.d_ptr += l_addr; \
} \
while (0)
ADJUST_DYN_INFO (DT_HASH);
@@ -92,7 +107,9 @@ elf_get_dynamic_info (struct link_map *l)
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
# undef ADJUST_DYN_INFO
assert (cnt <= DL_RO_DYN_TEMP_CNT);
}
#endif
if (info[DT_PLTREL] != NULL)
{
#if ELF_MACHINE_NO_RELA
@@ -112,10 +129,18 @@ elf_get_dynamic_info (struct link_map *l)
if (info[DT_REL] != NULL)
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
#endif
#ifdef STATIC_PIE_BOOTSTRAP
#ifdef RTLD_BOOTSTRAP
/* Only the bind now flags are allowed. */
assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
|| (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
/* Flags must not be set for ld.so. */
assert (info[DT_FLAGS] == NULL
|| (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
#endif
#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
assert (info[DT_RUNPATH] == NULL);
assert (info[DT_RPATH] == NULL);
#endif
#else
if (info[DT_FLAGS] != NULL)
{
/* Flags are used. Translate to the old form where available.
@@ -153,6 +178,5 @@ elf_get_dynamic_info (struct link_map *l)
if (info[DT_RUNPATH] != NULL)
/* If both RUNPATH and RPATH are given, the latter is ignored. */
info[DT_RPATH] = NULL;
}
#endif
}
+1 -5
View File
@@ -503,11 +503,7 @@ add_dir_1 (const char *line, const char *from_file, int from_line)
entry->path[--i] = '\0';
if (i == 0)
{
free (entry->path);
free (entry);
return;
}
return;
char *path = entry->path;
if (opt_chroot != NULL)
+1 -1
View File
@@ -96,7 +96,7 @@ struct link_map
#ifdef __USE_GNU
/* Version numbers for la_version handshake interface. */
#include <bits/link_lavcurrent.h>
#define LAV_CURRENT 1
/* Activity types signaled through la_activity. */
enum
+80 -38
View File
@@ -32,6 +32,7 @@
#include <fpu_control.h>
#include <hp-timing.h>
#include <libc-lock.h>
#include "dynamic-link.h"
#include <dl-librecon.h>
#include <unsecvars.h>
#include <dl-cache.h>
@@ -49,19 +50,9 @@
#include <dl-main.h>
#include <gnu/lib-names.h>
#include <dl-tunables.h>
#include <get-dynamic-info.h>
#include <dl-audit-check.h>
#include <assert.h>
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation.
Since ld.so must not have any undefined symbols the result
is trivial: always the map of ld.so itself. */
#define RTLD_BOOTSTRAP
#define RESOLVE_MAP(map, scope, sym, version, flags) map
#include "dynamic-link.h"
/* Only enables rtld profiling for architectures which provides non generic
hp-timing support. The generic support requires either syscall
(clock_gettime), which will incur in extra overhead on loading time.
@@ -331,7 +322,6 @@ struct rtld_global _rtld_global =
#ifdef _LIBC_REENTRANT
._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
._dl_load_tls_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
#endif
._dl_nns = 1,
._dl_ns =
@@ -473,7 +463,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
#ifndef DONT_USE_BOOTSTRAP_MAP
GL(dl_rtld_map).l_addr = info->l.l_addr;
GL(dl_rtld_map).l_ld = info->l.l_ld;
GL(dl_rtld_map).l_ld_readonly = info->l.l_ld_readonly;
memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
sizeof GL(dl_rtld_map).l_info);
GL(dl_rtld_map).l_mach = info->l.l_mach;
@@ -510,19 +499,28 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
return start_addr;
}
#ifdef DONT_USE_BOOTSTRAP_MAP
# define bootstrap_map GL(dl_rtld_map)
#else
# define bootstrap_map info.l
#endif
static ElfW(Addr) __attribute_used__
_dl_start (void *arg)
{
#ifdef DONT_USE_BOOTSTRAP_MAP
rtld_timer_start (&start_time);
# define bootstrap_map GL(dl_rtld_map)
#else
struct dl_start_final_info info;
# define bootstrap_map info.l
#endif
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation.
Since ld.so must not have any undefined symbols the result
is trivial: always the map of ld.so itself. */
#define RTLD_BOOTSTRAP
#define BOOTSTRAP_MAP (&bootstrap_map)
#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
#include "dynamic-link.h"
#ifdef DONT_USE_BOOTSTRAP_MAP
rtld_timer_start (&start_time);
#else
rtld_timer_start (&info.start_time);
#endif
@@ -548,15 +546,14 @@ _dl_start (void *arg)
/* Read our own dynamic section and fill in the info array. */
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
elf_get_dynamic_info (&bootstrap_map);
elf_get_dynamic_info (&bootstrap_map, NULL);
#if NO_TLS_OFFSET != 0
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
#endif
#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info);
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
#endif
if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)])
@@ -564,7 +561,7 @@ _dl_start (void *arg)
/* Relocate ourselves so we can do normal function calls and
data access using the global offset table. */
ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
}
bootstrap_map.l_relocated = 1;
@@ -991,7 +988,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
return;
}
if (!_dl_audit_check_version (lav))
if (lav > LAV_CURRENT)
{
_dl_debug_printf ("\
ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n",
@@ -1016,7 +1013,13 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
"la_objsearch\0"
"la_objopen\0"
"la_preinit\0"
LA_SYMBIND "\0"
#if __ELF_NATIVE_CLASS == 32
"la_symbind32\0"
#elif __ELF_NATIVE_CLASS == 64
"la_symbind64\0"
#else
# error "__ELF_NATIVE_CLASS must be defined"
#endif
#define STRING(s) __STRING (s)
"la_" STRING (ARCH_LA_PLTENTER) "\0"
"la_" STRING (ARCH_LA_PLTEXIT) "\0"
@@ -1058,6 +1061,25 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
dlmargs.map->l_auditing = 1;
}
/* Notify the the audit modules that the object MAP has already been
loaded. */
static void
notify_audit_modules_of_loaded_object (struct link_map *map)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objopen != NULL)
{
struct auditstate *state = link_map_audit_state (map, cnt);
state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
map->l_audit_any_plt |= state->bindflags != 0;
}
afct = afct->next;
}
}
/* Load all audit modules. */
static void
load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
@@ -1076,8 +1098,8 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
program and the dynamic linker itself). */
if (GLRO(dl_naudit) > 0)
{
_dl_audit_objopen (main_map, LM_ID_BASE);
_dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE);
notify_audit_modules_of_loaded_object (main_map);
notify_audit_modules_of_loaded_object (&GL(dl_rtld_map));
}
}
@@ -1446,7 +1468,6 @@ dl_main (const ElfW(Phdr) *phdr,
/* This tells us where to find the dynamic section,
which tells us everything we need to do. */
main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr;
main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
break;
case PT_INTERP:
/* This "interpreter segment" was used by the program loader to
@@ -1592,7 +1613,7 @@ dl_main (const ElfW(Phdr) *phdr,
if (! rtld_is_main)
{
/* Extract the contents of the dynamic section for easy access. */
elf_get_dynamic_info (main_map);
elf_get_dynamic_info (main_map, NULL);
/* If the main map is libc.so, update the base namespace to
refer to this map. If libc.so is loaded later, this happens
@@ -1762,7 +1783,18 @@ dl_main (const ElfW(Phdr) *phdr,
/* Auditing checkpoint: we are ready to signal that the initial map
is being constructed. */
_dl_audit_activity_map (main_map, LA_ACT_ADD);
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
LA_ACT_ADD);
afct = afct->next;
}
}
/* We have two ways to specify objects to preload: via environment
variable and via the file /etc/ld.so.preload. The latter can also
@@ -1886,12 +1918,6 @@ dl_main (const ElfW(Phdr) *phdr,
assert (i == npreloads);
}
#ifdef NEED_DL_SYSINFO_DSO
/* Now that the audit modules are opened, call la_objopen for the vDSO. */
if (GLRO(dl_sysinfo_map) != NULL)
_dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE);
#endif
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
specified some libraries to load, these are inserted before the actual
dependencies in the executable's searchlist for symbol resolution. */
@@ -2393,7 +2419,7 @@ dl_main (const ElfW(Phdr) *phdr,
into the main thread's TLS area, which we allocated above.
Note: thread-local variables must only be accessed after completing
the next step. */
_dl_allocate_tls_init (tcbp, false);
_dl_allocate_tls_init (tcbp);
/* And finally install it for the main thread. */
if (! tls_init_tp_called)
@@ -2449,7 +2475,23 @@ dl_main (const ElfW(Phdr) *phdr,
#ifdef SHARED
/* Auditing checkpoint: we have added all objects. */
_dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
/* Do not call the functions for any auditing object. */
if (head->l_auditing == 0)
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&link_map_audit_state (head, cnt)->cookie,
LA_ACT_CONSISTENT);
afct = afct->next;
}
}
}
#endif
/* Notify the debugger all new objects are now ready to go. We must re-get
+4 -3
View File
@@ -30,9 +30,11 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
We just want our data structures to describe it as if we had just
mapped and relocated it normally. */
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
__RTLD_VDSO, LM_ID_BASE);
0, LM_ID_BASE);
if (__glibc_likely (l != NULL))
{
static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
+ GLRO(dl_sysinfo_dso)->e_phoff);
l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
@@ -43,7 +45,6 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
{
l->l_ld = (void *) ph->p_vaddr;
l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
}
else if (ph->p_type == PT_LOAD)
{
@@ -64,7 +65,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
l->l_map_end += l->l_addr;
l->l_text_end += l->l_addr;
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
elf_get_dynamic_info (l);
elf_get_dynamic_info (l, dyn_temp);
_dl_setup_hash (l);
l->l_relocated = 1;
-7
View File
@@ -17,7 +17,6 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <err.h>
#include <error.h>
#include <fcntl.h>
#include <stdio.h>
@@ -233,12 +232,6 @@ uintptr_t
la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
{
if (*flags & LA_SYMB_NOPLTENTER)
warnx ("cannot trace PLT enter (bind-now enabled)");
if (do_exit && *flags & LA_SYMB_NOPLTEXIT)
warnx ("cannot trace PLT exit (bind-now enabled)");
if (!do_exit)
*flags = LA_SYMB_NOPLTEXIT;
-67
View File
@@ -1,67 +0,0 @@
/* DT_AUDIT with modules with TLSDESC.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xthread.h>
#include <support/xdlfcn.h>
static void *
thr_func (void *mod)
{
int* (*get_global1)(void) = xdlsym (mod, "get_global1");
int* (*get_global2)(void) = xdlsym (mod, "get_global2");
void (*set_global2)(int) = xdlsym (mod, "set_global2");
int* (*get_local1)(void) = xdlsym (mod, "get_local1");
int* (*get_local2)(void) = xdlsym (mod, "get_local2");
int *global1 = get_global1 ();
TEST_COMPARE (*global1, 0);
++*global1;
int *global2 = get_global2 ();
TEST_COMPARE (*global2, 0);
++*global2;
TEST_COMPARE (*global2, 1);
set_global2 (10);
TEST_COMPARE (*global2, 10);
int *local1 = get_local1 ();
TEST_COMPARE (*local1, 0);
++*local1;
int *local2 = get_local2 ();
TEST_COMPARE (*local2, 0);
++*local2;
return 0;
}
static int
do_test (void)
{
void *mod = xdlopen ("tst-audit-tlsdesc-mod1.so", RTLD_LAZY);
pthread_t thr = xpthread_create (NULL, thr_func, mod);
void *r = xpthread_join (thr);
TEST_VERIFY (r == NULL);
return 0;
}
#include <support/test-driver.c>
-41
View File
@@ -1,41 +0,0 @@
/* DT_AUDIT with modules with TLSDESC.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
__thread int global1;
int *
get_global1 (void)
{
return &global1;
}
static __thread int local1;
void *
get_local1 (void)
{
return &local1;
}
extern __thread int global2;
void
set_global2 (int v)
{
global2 = v;
}
-33
View File
@@ -1,33 +0,0 @@
/* DT_AUDIT with modules with TLSDESC.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
__thread int global2;
int *
get_global2 (void)
{
return &global2;
}
static __thread int local2;
void *
get_local2 (void)
{
return &local2;
}
-60
View File
@@ -1,60 +0,0 @@
/* DT_AUDIT with modules with TLSDESC.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/xthread.h>
extern __thread int global1;
extern __thread int global2;
void *get_local1 (void);
void set_global2 (int v);
void *get_local2 (void);
static void *
thr_func (void *clousure)
{
TEST_COMPARE (global1, 0);
++global1;
TEST_COMPARE (global2, 0);
++global2;
TEST_COMPARE (global2, 1);
set_global2 (10);
TEST_COMPARE (global2, 10);
int *local1 = get_local1 ();
TEST_COMPARE (*local1, 0);
++*local1;
int *local2 = get_local2 ();
TEST_COMPARE (*local2, 0);
++*local2;
return 0;
}
static int
do_test (void)
{
pthread_t thr = xpthread_create (NULL, thr_func, NULL);
void *r = xpthread_join (thr);
TEST_VERIFY (r == NULL);
return 0;
}
#include <support/test-driver.c>
-25
View File
@@ -1,25 +0,0 @@
/* Check DT_AUDIT with audit not linked against libc.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
static int
do_test (void)
{
return 0;
}
#include <support/test-driver.c>
-129
View File
@@ -1,129 +0,0 @@
/* Check DT_AUDIT with dlmopen.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <gnu/lib-names.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/xdlfcn.h>
#include <support/xstdio.h>
#include <support/support.h>
static int restart;
#define CMDLINE_OPTIONS \
{ "restart", no_argument, &restart, 1 },
static int
handle_restart (void)
{
{
void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
pid_t (*s) (void) = xdlsym (h, "getpid");
TEST_COMPARE (s (), getpid ());
xdlclose (h);
}
{
void *h = xdlmopen (LM_ID_NEWLM, "tst-audit18mod.so", RTLD_NOW);
int (*foo) (void) = xdlsym (h, "foo");
TEST_COMPARE (foo (), 10);
xdlclose (h);
}
return 0;
}
static int
do_test (int argc, char *argv[])
{
/* We must have either:
- One our fource parameters left if called initially:
+ path to ld.so optional
+ "--library-path" optional
+ the library path optional
+ the application name */
if (restart)
return handle_restart ();
char *spargv[9];
int i = 0;
for (; i < argc - 1; i++)
spargv[i] = argv[i + 1];
spargv[i++] = (char *) "--direct";
spargv[i++] = (char *) "--restart";
spargv[i] = NULL;
setenv ("LD_AUDIT", "tst-auditmod18.so", 0);
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit18", 0, sc_allow_stderr);
struct
{
const char *name;
bool found;
} audit_iface[] =
{
{ "la_version", false },
{ "la_objsearch", false },
{ "la_activity", false },
{ "la_objopen", false },
{ "la_objclose", false },
{ "la_preinit", false },
#if __WORDSIZE == 32
{ "la_symbind32", false },
#elif __WORDSIZE == 64
{ "la_symbind64", false },
#endif
};
/* Some hooks are called more than once but the test only check if any
is called at least once. */
FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
TEST_VERIFY (out != NULL);
char *buffer = NULL;
size_t buffer_length = 0;
while (xgetline (&buffer, &buffer_length, out))
{
for (int i = 0; i < array_length (audit_iface); i++)
if (strncmp (buffer, audit_iface[i].name,
strlen (audit_iface[i].name)) == 0)
audit_iface[i].found = true;
}
free (buffer);
xfclose (out);
for (int i = 0; i < array_length (audit_iface); i++)
TEST_COMPARE (audit_iface[i].found, true);
support_capture_subprocess_free (&result);
return 0;
}
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>
-23
View File
@@ -1,23 +0,0 @@
/* Check DT_AUDIT with dlmopen.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
int
foo (void)
{
return 10;
}
-38
View File
@@ -1,38 +0,0 @@
/* Check if DT_AUDIT a module without la_plt{enter,exit} symbols does not incur
in profiling (BZ#15533).
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <support/xdlfcn.h>
#include <support/check.h>
static int
do_test (void)
{
void *h = xdlopen ("tst-auditmod19a.so", RTLD_NOW);
struct link_map *lmap;
TEST_VERIFY_EXIT (dlinfo (h, RTLD_DI_LINKMAP, &lmap) == 0);
/* The internal array is only allocated if profiling is enabled. */
TEST_VERIFY (lmap->l_reloc_result == NULL);
return 0;
}
#include <support/test-driver.c>
-94
View File
@@ -1,94 +0,0 @@
/* Check if DT_AUDIT a module with la_plt{enter,exit} call la_symbind
for lazy resolution.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <getopt.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/xstdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
static int restart;
#define CMDLINE_OPTIONS \
{ "restart", no_argument, &restart, 1 },
int tst_audit18bmod1_func (void);
static int
handle_restart (void)
{
TEST_COMPARE (tst_audit18bmod1_func (), 10);
return 0;
}
static inline bool
startswith (const char *str, const char *pre)
{
size_t lenpre = strlen (pre);
size_t lenstr = strlen (str);
return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
}
static int
do_test (int argc, char *argv[])
{
/* We must have either:
- One our fource parameters left if called initially:
+ path to ld.so optional
+ "--library-path" optional
+ the library path optional
+ the application name */
if (restart)
return handle_restart ();
char *spargv[9];
int i = 0;
for (; i < argc - 1; i++)
spargv[i] = argv[i + 1];
spargv[i++] = (char *) "--direct";
spargv[i++] = (char *) "--restart";
spargv[i] = NULL;
setenv ("LD_AUDIT", "tst-auditmod18b.so", 0);
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit18b", 0, sc_allow_stderr);
bool find_symbind = false;
FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
TEST_VERIFY (out != NULL);
char *buffer = NULL;
size_t buffer_length = 0;
while (xgetline (&buffer, &buffer_length, out))
if (startswith (buffer, "la_symbind: tst_audit18bmod1_func") == 0)
find_symbind = true;
TEST_COMPARE (find_symbind, true);
free (buffer);
xfclose (out);
return 0;
}
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>
-23
View File
@@ -1,23 +0,0 @@
/* Extra module for tst-audit18b.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
int
tst_audit18bmod1_func (void)
{
return 10;
}
-25
View File
@@ -1,25 +0,0 @@
/* Check dlopen failure on audit modules.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
static int
do_test (void)
{
return 0;
}
#include <support/test-driver.c>
-42
View File
@@ -1,42 +0,0 @@
/* Check LD_AUDIT with static TLS.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <ctype.h>
#include <support/xthread.h>
#include <support/check.h>
static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));
static void *
tf (void *arg)
{
TEST_COMPARE (out, 0);
out = isspace (' ');
return NULL;
}
int main (int argc, char *argv[])
{
TEST_COMPARE (out, 0);
out = isspace (' ');
pthread_t t = xpthread_create (NULL, tf, NULL);
xpthread_join (t);
return 0;
}
-124
View File
@@ -1,124 +0,0 @@
/* Check DTAUDIT and vDSO interaction.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/xstdio.h>
#include <support/support.h>
#include <sys/auxv.h>
static int restart;
#define CMDLINE_OPTIONS \
{ "restart", no_argument, &restart, 1 },
static uintptr_t vdso_addr;
static int
handle_restart (void)
{
fprintf (stderr, "vdso: %p\n", (void*) vdso_addr);
return 0;
}
static uintptr_t
parse_address (const char *str)
{
void *r;
TEST_COMPARE (sscanf (str, "%p\n", &r), 1);
return (uintptr_t) r;
}
static inline bool
startswith (const char *str, const char *pre)
{
size_t lenpre = strlen (pre);
size_t lenstr = strlen (str);
return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
}
static int
do_test (int argc, char *argv[])
{
vdso_addr = getauxval (AT_SYSINFO_EHDR);
if (vdso_addr == 0)
FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0");
/* We must have either:
- One our fource parameters left if called initially:
+ path to ld.so optional
+ "--library-path" optional
+ the library path optional
+ the application name */
if (restart)
return handle_restart ();
char *spargv[9];
int i = 0;
for (; i < argc - 1; i++)
spargv[i] = argv[i + 1];
spargv[i++] = (char *) "--direct";
spargv[i++] = (char *) "--restart";
spargv[i] = NULL;
setenv ("LD_AUDIT", "tst-auditmod22.so", 0);
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
/* The respawned process should always print the vDSO address (otherwise it
will fails as unsupported). However, on some architectures the audit
module might see the vDSO with l_addr being 0, meaning a fixed mapping
(linux-gate.so). In this case we don't check its value against
AT_SYSINFO_EHDR one. */
uintptr_t vdso_process = 0;
bool vdso_audit_found = false;
uintptr_t vdso_audit = 0;
FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
TEST_VERIFY (out != NULL);
char *buffer = NULL;
size_t buffer_length = 0;
while (xgetline (&buffer, &buffer_length, out))
{
if (startswith (buffer, "vdso: "))
vdso_process = parse_address (buffer + strlen ("vdso: "));
else if (startswith (buffer, "vdso found: "))
{
vdso_audit = parse_address (buffer + strlen ("vdso found: "));
vdso_audit_found = true;
}
}
TEST_COMPARE (vdso_audit_found, true);
if (vdso_audit != 0)
TEST_COMPARE (vdso_process, vdso_audit);
free (buffer);
xfclose (out);
return 0;
}
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>
-239
View File
@@ -1,239 +0,0 @@
/* Check for expected la_objopen and la_objeclose for all objects.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
#include <errno.h>
#include <getopt.h>
#include <link.h>
#include <limits.h>
#include <inttypes.h>
#include <gnu/lib-names.h>
#include <string.h>
#include <stdlib.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/xstdio.h>
#include <support/xdlfcn.h>
#include <support/support.h>
static int restart;
#define CMDLINE_OPTIONS \
{ "restart", no_argument, &restart, 1 },
static int
handle_restart (void)
{
xdlopen ("tst-audit23mod.so", RTLD_NOW);
xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
return 0;
}
static inline bool
startswith (const char *str, const char *pre)
{
size_t lenpre = strlen (pre);
size_t lenstr = strlen (str);
return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
}
static inline bool
is_vdso (const char *str)
{
return startswith (str, "linux-gate")
|| startswith (str, "linux-vdso");
}
static int
do_test (int argc, char *argv[])
{
/* We must have either:
- One or four parameters left if called initially:
+ path to ld.so optional
+ "--library-path" optional
+ the library path optional
+ the application name */
if (restart)
return handle_restart ();
char *spargv[9];
TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
int i = 0;
for (; i < argc - 1; i++)
spargv[i] = argv[i + 1];
spargv[i++] = (char *) "--direct";
spargv[i++] = (char *) "--restart";
spargv[i] = NULL;
setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
/* The expected la_objopen/la_objclose:
1. executable
2. loader
3. libc.so
4. tst-audit23mod.so
5. libc.so (LM_ID_NEWLM).
6. vdso (optional and ignored). */
enum { max_objs = 6 };
struct la_obj_t
{
char *lname;
uintptr_t laddr;
Lmid_t lmid;
bool closed;
} objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
size_t nobjs = 0;
/* The expected namespaces are one for the audit module, one for the
application, and another for the dlmopen on handle_restart. */
enum { max_ns = 3 };
uintptr_t acts[max_ns] = { 0 };
size_t nacts = 0;
int last_act = -1;
uintptr_t last_act_cookie = -1;
bool seen_first_objclose = false;
FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
TEST_VERIFY (out != NULL);
char *buffer = NULL;
size_t buffer_length = 0;
while (xgetline (&buffer, &buffer_length, out))
{
if (startswith (buffer, "la_activity: "))
{
uintptr_t cookie;
int this_act;
int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
&cookie);
TEST_COMPARE (r, 2);
/* The cookie identifies the object at the head of the link map,
so we only add a new namespace if it changes from the previous
one. This works since dlmopen is the last in the test body. */
if (cookie != last_act_cookie && last_act_cookie != -1)
TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
{
acts[nacts++] = cookie;
last_act_cookie = cookie;
}
/* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
at program termination (if the tests adds a dlclose or a library
with extra dependencies this will need to be adapted). */
else if (this_act == LA_ACT_DELETE)
{
last_act_cookie = acts[--nacts];
TEST_COMPARE (acts[nacts], cookie);
acts[nacts] = 0;
}
else if (this_act == LA_ACT_CONSISTENT)
{
TEST_COMPARE (cookie, last_act_cookie);
/* LA_ACT_DELETE must always be followed by an la_objclose. */
if (last_act == LA_ACT_DELETE)
TEST_COMPARE (seen_first_objclose, true);
else
TEST_COMPARE (last_act, LA_ACT_ADD);
}
last_act = this_act;
seen_first_objclose = false;
}
else if (startswith (buffer, "la_objopen: "))
{
char *lname;
uintptr_t laddr;
Lmid_t lmid;
uintptr_t cookie;
int r = sscanf (buffer, "la_objopen: %"SCNxPTR" %ms %"SCNxPTR" %ld",
&cookie, &lname, &laddr, &lmid);
TEST_COMPARE (r, 4);
/* la_objclose is not triggered by vDSO because glibc does not
unload it. */
if (is_vdso (lname))
continue;
if (nobjs == max_objs)
FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
lname, laddr, lmid);
objs[nobjs].lname = lname;
objs[nobjs].laddr = laddr;
objs[nobjs].lmid = lmid;
objs[nobjs].closed = false;
nobjs++;
/* This indirectly checks that la_objopen always comes before
la_objclose btween la_activity calls. */
seen_first_objclose = false;
}
else if (startswith (buffer, "la_objclose: "))
{
char *lname;
uintptr_t laddr;
Lmid_t lmid;
uintptr_t cookie;
int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
&cookie, &lname, &laddr, &lmid);
TEST_COMPARE (r, 4);
for (size_t i = 0; i < nobjs; i++)
{
if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
{
TEST_COMPARE (objs[i].closed, false);
objs[i].closed = true;
break;
}
}
/* la_objclose should be called after la_activity(LA_ACT_DELETE) for
the closed object's namespace. */
TEST_COMPARE (last_act, LA_ACT_DELETE);
if (!seen_first_objclose)
{
TEST_COMPARE (last_act_cookie, cookie);
seen_first_objclose = true;
}
}
}
for (size_t i = 0; i < nobjs; i++)
{
TEST_COMPARE (objs[i].closed, true);
free (objs[i].lname);
}
/* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
Since only one link map may be not-CONSISTENT at a time, this also
ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
for every namespace. */
TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
free (buffer);
xfclose (out);
return 0;
}
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>
-23
View File
@@ -1,23 +0,0 @@
/* Extra module for tst-audit23
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
int
foo (void)
{
return 0;
}
-36
View File
@@ -1,36 +0,0 @@
/* LD_AUDIT test for la_symbind and bind-now.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/support.h>
int tst_audit24amod1_func1 (void);
int tst_audit24amod1_func2 (void);
int tst_audit24amod2_func1 (void);
int
do_test (void)
{
TEST_COMPARE (tst_audit24amod1_func1 (), 1);
TEST_COMPARE (tst_audit24amod1_func2 (), 2);
TEST_COMPARE (tst_audit24amod2_func1 (), 10);
return 0;
}
#include <support/test-driver.c>
-31
View File
@@ -1,31 +0,0 @@
/* Module used by tst-audit24a.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
_Noreturn int
tst_audit24amod1_func1 (void)
{
abort ();
}
int
tst_audit24amod1_func2 (void)
{
return 2;
}
-25
View File
@@ -1,25 +0,0 @@
/* Module used by tst-audit24a.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
_Noreturn int
tst_audit24amod2_func1 (void)
{
abort ();
}
-37
View File
@@ -1,37 +0,0 @@
/* LD_AUDIT test for la_symbind and bind-now.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
/* This is similar to tst-audit24a, with the difference this modules
does not have the .gnu.version section header. */
#include <support/check.h>
#include <support/support.h>
int tst_audit24bmod1_func1 (void);
int tst_audit24bmod1_func2 (void);
int
do_test (void)
{
TEST_COMPARE (tst_audit24bmod1_func1 (), 1);
TEST_COMPARE (tst_audit24bmod1_func2 (), 2);
return 0;
}
#include <support/test-driver.c>
-31
View File
@@ -1,31 +0,0 @@
/* Module used by tst-audit24c.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
int tst_audit24bmod2_func1 (void);
int
tst_audit24bmod1_func1 (void)
{
return -1;
}
int
tst_audit24bmod1_func2 (void)
{
return tst_audit24bmod2_func1 ();
}
-23
View File
@@ -1,23 +0,0 @@
/* Module used by tst-audit24b.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
int
tst_audit24bmod2_func1 (void)
{
return -1;
}
-2
View File
@@ -1,2 +0,0 @@
/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now */
#include "tst-audit24a.c"
-36
View File
@@ -1,36 +0,0 @@
/* LD_AUDIT test for la_symbind and bind-now.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <support/check.h>
#include <support/support.h>
int tst_audit24dmod1_func1 (void);
int tst_audit24dmod1_func2 (void);
int tst_audit24dmod2_func1 (void);
int
do_test (void)
{
TEST_COMPARE (tst_audit24dmod1_func1 (), 1);
TEST_COMPARE (tst_audit24dmod1_func2 (), 32);
TEST_COMPARE (tst_audit24dmod2_func1 (), 10);
return 0;
}
#include <support/test-driver.c>
-33
View File
@@ -1,33 +0,0 @@
/* Module used by tst-audit24d.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
int tst_audit24dmod3_func1 (void);
_Noreturn int
tst_audit24dmod1_func1 (void)
{
abort ();
}
int
tst_audit24dmod1_func2 (void)
{
return 2 + tst_audit24dmod3_func1 ();;
}
-28
View File
@@ -1,28 +0,0 @@
/* Module for tst-audit24d.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
int tst_audit24dmod4_func1 (void);
_Noreturn int
tst_audit24dmod2_func1 (void)
{
tst_audit24dmod4_func1 ();
abort ();
}
-31
View File
@@ -1,31 +0,0 @@
/* Module for tst-audit24d.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
_Noreturn int
tst_audit24dmod3_func1 (void)
{
abort ();
}
int
tst_audit24dmod3_func2 (void)
{
return 4;
}
-25
View File
@@ -1,25 +0,0 @@
/* Module for tst-audit24d.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
_Noreturn int
tst_audit24dmod4_func1 (void)
{
abort ();
}
-129
View File
@@ -1,129 +0,0 @@
/* Check LD_AUDIT and LD_BIND_NOW.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/xstdio.h>
#include <support/support.h>
#include <sys/auxv.h>
static int restart;
#define CMDLINE_OPTIONS \
{ "restart", no_argument, &restart, 1 },
void tst_audit25mod1_func1 (void);
void tst_audit25mod1_func2 (void);
void tst_audit25mod2_func1 (void);
void tst_audit25mod2_func2 (void);
static int
handle_restart (void)
{
tst_audit25mod1_func1 ();
tst_audit25mod1_func2 ();
tst_audit25mod2_func1 ();
tst_audit25mod2_func2 ();
return 0;
}
static inline bool
startswith (const char *str, const char *pre)
{
size_t lenpre = strlen (pre);
size_t lenstr = strlen (str);
return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
}
static int
do_test (int argc, char *argv[])
{
/* We must have either:
- One or four parameters left if called initially:
+ path to ld.so optional
+ "--library-path" optional
+ the library path optional
+ the application name */
if (restart)
return handle_restart ();
setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
char *spargv[9];
int i = 0;
for (; i < argc - 1; i++)
spargv[i] = argv[i + 1];
spargv[i++] = (char *) "--direct";
spargv[i++] = (char *) "--restart";
spargv[i] = NULL;
TEST_VERIFY_EXIT (i < array_length (spargv));
{
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit25a", 0,
sc_allow_stderr);
/* tst-audit25a is build with -Wl,-z,lazy and tst-audit25mod1 with
-Wl,-z,now; so only tst_audit25mod3_func1 should be expected to
have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */
TEST_COMPARE_STRING (result.err.buffer,
"la_symbind: tst_audit25mod3_func1 1\n"
"la_symbind: tst_audit25mod1_func1 0\n"
"la_symbind: tst_audit25mod1_func2 0\n"
"la_symbind: tst_audit25mod2_func1 0\n"
"la_symbind: tst_audit25mod4_func1 0\n"
"la_symbind: tst_audit25mod2_func2 0\n");
support_capture_subprocess_free (&result);
}
{
setenv ("LD_BIND_NOW", "1", 0);
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit25a", 0,
sc_allow_stderr);
/* With LD_BIND_NOW all symbols are expected to have
LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution
order is done in breadth-first order. */
TEST_COMPARE_STRING (result.err.buffer,
"la_symbind: tst_audit25mod4_func1 1\n"
"la_symbind: tst_audit25mod3_func1 1\n"
"la_symbind: tst_audit25mod1_func1 1\n"
"la_symbind: tst_audit25mod2_func1 1\n"
"la_symbind: tst_audit25mod1_func2 1\n"
"la_symbind: tst_audit25mod2_func2 1\n");
support_capture_subprocess_free (&result);
}
return 0;
}
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>
-128
View File
@@ -1,128 +0,0 @@
/* Check LD_AUDIT and LD_BIND_NOW.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
#include <support/xstdio.h>
#include <support/support.h>
#include <sys/auxv.h>
static int restart;
#define CMDLINE_OPTIONS \
{ "restart", no_argument, &restart, 1 },
void tst_audit25mod1_func1 (void);
void tst_audit25mod1_func2 (void);
void tst_audit25mod2_func1 (void);
void tst_audit25mod2_func2 (void);
static int
handle_restart (void)
{
tst_audit25mod1_func1 ();
tst_audit25mod1_func2 ();
tst_audit25mod2_func1 ();
tst_audit25mod2_func2 ();
return 0;
}
static inline bool
startswith (const char *str, const char *pre)
{
size_t lenpre = strlen (pre);
size_t lenstr = strlen (str);
return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
}
static int
do_test (int argc, char *argv[])
{
/* We must have either:
- One or four parameters left if called initially:
+ path to ld.so optional
+ "--library-path" optional
+ the library path optional
+ the application name */
if (restart)
return handle_restart ();
setenv ("LD_AUDIT", "tst-auditmod25.so", 0);
char *spargv[9];
int i = 0;
for (; i < argc - 1; i++)
spargv[i] = argv[i + 1];
spargv[i++] = (char *) "--direct";
spargv[i++] = (char *) "--restart";
spargv[i] = NULL;
{
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit25a", 0,
sc_allow_stderr);
/* tst-audit25a and tst-audit25mod1 are built with -Wl,-z,now, but
tst-audit25mod2 is built with -Wl,-z,lazy. So only
tst_audit25mod4_func1 (called by tst_audit25mod2_func1) should not
have LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. */
TEST_COMPARE_STRING (result.err.buffer,
"la_symbind: tst_audit25mod3_func1 1\n"
"la_symbind: tst_audit25mod1_func1 1\n"
"la_symbind: tst_audit25mod2_func1 1\n"
"la_symbind: tst_audit25mod1_func2 1\n"
"la_symbind: tst_audit25mod2_func2 1\n"
"la_symbind: tst_audit25mod4_func1 0\n");
support_capture_subprocess_free (&result);
}
{
setenv ("LD_BIND_NOW", "1", 0);
struct support_capture_subprocess result
= support_capture_subprogram (spargv[0], spargv);
support_capture_subprocess_check (&result, "tst-audit25a", 0,
sc_allow_stderr);
/* With LD_BIND_NOW all symbols are expected to have
LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT. Also the resolution
order is done in breadth-first order. */
TEST_COMPARE_STRING (result.err.buffer,
"la_symbind: tst_audit25mod4_func1 1\n"
"la_symbind: tst_audit25mod3_func1 1\n"
"la_symbind: tst_audit25mod1_func1 1\n"
"la_symbind: tst_audit25mod2_func1 1\n"
"la_symbind: tst_audit25mod1_func2 1\n"
"la_symbind: tst_audit25mod2_func2 1\n");
support_capture_subprocess_free (&result);
}
return 0;
}
#define TEST_FUNCTION_ARGV do_test
#include <support/test-driver.c>
-30
View File
@@ -1,30 +0,0 @@
/* Module used by tst-audit25.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
void tst_audit25mod3_func1 (void);
void
tst_audit25mod1_func1 (void)
{
tst_audit25mod3_func1 ();
}
void
tst_audit25mod1_func2 (void)
{
}
-30
View File
@@ -1,30 +0,0 @@
/* Module used by tst-audit25.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
void tst_audit25mod4_func1 (void);
void
tst_audit25mod2_func1 (void)
{
tst_audit25mod4_func1 ();
}
void
tst_audit25mod2_func2 (void)
{
}
-22
View File
@@ -1,22 +0,0 @@
/* Module used by tst-audit25.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
void
tst_audit25mod3_func1 (void)
{
}
-22
View File
@@ -1,22 +0,0 @@
/* Module used by tst-audit25.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
void
tst_audit25mod4_func1 (void)
{
}
-25
View File
@@ -1,25 +0,0 @@
/* DT_AUDIT with modules with TLSDESC.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
-23
View File
@@ -1,23 +0,0 @@
/* Check DT_AUDIT with audit not linked against libc.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
unsigned int
la_version (unsigned int version)
{
return version;
}
-73
View File
@@ -1,73 +0,0 @@
/* Check DT_AUDIT with dlmopen.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <link.h>
unsigned int
la_version (unsigned int version)
{
fprintf (stderr, "%s\n", __func__);
return LAV_CURRENT;
}
char *
la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
{
fprintf (stderr, "%s\n", __func__);
return (char *) name;
}
void
la_activity (uintptr_t *cookie, unsigned int flag)
{
fprintf (stderr, "%s\n", __func__);
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
fprintf (stderr, "%s\n", __func__);
return LA_FLG_BINDTO | LA_FLG_BINDFROM;
}
unsigned int
la_objclose (uintptr_t *cookie)
{
fprintf (stderr, "%s\n", __func__);
return 0;
}
void
la_preinit (uintptr_t *cookie)
{
fprintf (stderr, "%s\n", __func__);
}
uintptr_t
#if __ELF_NATIVE_CLASS == 32
la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
#else
la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
#endif
{
fprintf (stderr, "%s\n", __func__);
return sym->st_value;
}
-25
View File
@@ -1,25 +0,0 @@
/* Audit module for tst-audit18a.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
-46
View File
@@ -1,46 +0,0 @@
/* Audit module for tst-audit18b.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <string.h>
#include <stdio.h>
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
return LA_FLG_BINDTO | LA_FLG_BINDFROM;
}
uintptr_t
#if __ELF_NATIVE_CLASS == 32
la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
#else
la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
uintptr_t *defcook, unsigned int *flags, const char *symname)
#endif
{
fprintf (stderr, "la_symbind: %s\n", symname);
return sym->st_value;
}
-57
View File
@@ -1,57 +0,0 @@
/* Check dlopen failure on audit modules.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <dlfcn.h>
#include <link.h>
#include <stdlib.h>
unsigned int
la_version (unsigned int v)
{
return LAV_CURRENT;
}
static void
check (void)
{
{
void *mod = dlopen ("nonexistent.so", RTLD_NOW);
if (mod != NULL)
abort ();
}
{
void *mod = dlmopen (LM_ID_BASE, "nonexistent.so", RTLD_NOW);
if (mod != NULL)
abort ();
}
}
void
la_activity (uintptr_t *cookie, unsigned int flag)
{
if (flag != LA_ACT_CONSISTENT)
return;
check ();
}
void
la_preinit (uintptr_t *cookie)
{
check ();
}
-80
View File
@@ -1,80 +0,0 @@
/* Check LD_AUDIT with static TLS.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <ctype.h>
#include <stdlib.h>
#include <link.h>
#define tls_ie __attribute__ ((tls_model ("initial-exec")))
__thread int tls_var0 tls_ie;
__thread int tls_var1 tls_ie = 0x10;
/* Defined at tst-auditmod21b.so */
extern __thread int tls_var2;
extern __thread int tls_var3;
static volatile int out;
static void
call_libc (void)
{
/* isspace accesses the initial-exec glibc TLS variables, which are
setup in glibc initialization. */
out = isspace (' ');
}
unsigned int
la_version (unsigned int v)
{
tls_var0 = 0x1;
if (tls_var1 != 0x10)
abort ();
tls_var1 = 0x20;
tls_var2 = 0x2;
if (tls_var3 != 0x20)
abort ();
tls_var3 = 0x40;
call_libc ();
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
{
call_libc ();
*cookie = (uintptr_t) map;
return 0;
}
void
la_activity (uintptr_t* cookie, unsigned int flag)
{
if (tls_var0 != 0x1 || tls_var1 != 0x20)
abort ();
call_libc ();
}
void
la_preinit (uintptr_t* cookie)
{
call_libc ();
}
-22
View File
@@ -1,22 +0,0 @@
/* Check LD_AUDIT with static TLS.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#define tls_ie __attribute__ ((tls_model ("initial-exec")))
__thread int tls_var2 tls_ie;
__thread int tls_var3 tls_ie = 0x20;
-51
View File
@@ -1,51 +0,0 @@
/* Check DTAUDIT and vDSO interaction.
Copyright (C) 2021 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <sys/auxv.h>
static inline bool
startswith (const char *str, const char *pre)
{
size_t lenpre = strlen (pre);
size_t lenstr = strlen (str);
return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
}
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
/* The linux-gate.so is placed at a fixed address, thus l_addr being 0,
and it might be the value reported as the AT_SYSINFO_EHDR. */
if (map->l_addr == 0 && startswith (map->l_name, "linux-gate.so"))
fprintf (stderr, "vdso found: %p\n", NULL);
else if (map->l_addr == getauxval (AT_SYSINFO_EHDR))
fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr);
return 0;
}
-74
View File
@@ -1,74 +0,0 @@
/* Audit module loaded by tst-audit23.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/auxv.h>
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
struct map_desc_t
{
char *lname;
uintptr_t laddr;
Lmid_t lmid;
};
void
la_activity (uintptr_t *cookie, unsigned int flag)
{
fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
(uintptr_t) cookie, l_name, map->l_addr, lmid);
struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
if (map_desc == NULL)
abort ();
map_desc->lname = strdup (l_name);
map_desc->laddr = map->l_addr;
map_desc->lmid = lmid;
*cookie = (uintptr_t) map_desc;
return 0;
}
unsigned int
la_objclose (uintptr_t *cookie)
{
struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
(uintptr_t) cookie, map_desc->lname, map_desc->laddr,
map_desc->lmid);
return 0;
}
-29
View File
@@ -1,29 +0,0 @@
/* Auxiliary functions for tst-audit24x.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#ifndef _TST_AUDITMOD24_H
#define _TST_AUDITMOD24_H
static void
test_symbind_flags (unsigned int flags)
{
if ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 0)
abort ();
}
#endif
-114
View File
@@ -1,114 +0,0 @@
/* Audit modules for tst-audit24a.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <tst-auditmod24.h>
#define AUDIT24_COOKIE 0x1
#define AUDIT24MOD1_COOKIE 0x2
#define AUDIT24MOD2_COOKIE 0x3
#ifndef TEST_NAME
# define TEST_NAME "tst-audit24a"
#endif
#ifndef TEST_MOD
# define TEST_MOD TEST_NAME
#endif
#ifndef TEST_FUNC
# define TEST_FUNC "tst_audit24a"
#endif
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
const char *p = strrchr (map->l_name, '/');
const char *l_name = p == NULL ? TEST_NAME : p + 1;
uintptr_t ck = -1;
if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
ck = AUDIT24MOD1_COOKIE;
else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
ck = AUDIT24MOD2_COOKIE;
else if (strcmp (l_name, TEST_NAME) == 0)
ck = AUDIT24_COOKIE;
*cookie = ck;
return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
}
static int
tst_func1 (void)
{
return 1;
}
static int
tst_func2 (void)
{
return 10;
}
#if __ELF_NATIVE_CLASS == 64
uintptr_t
la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#else
uintptr_t
la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#endif
{
if (*refcook == AUDIT24_COOKIE)
{
if (*defcook == AUDIT24MOD1_COOKIE)
{
/* Check if bind-now symbols are advertised to not call the PLT
hooks. */
test_symbind_flags (*flags);
if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
return (uintptr_t) tst_func1;
else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
return sym->st_value;
abort ();
}
if (*defcook == AUDIT24MOD2_COOKIE
&& (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
{
test_symbind_flags (*flags);
return (uintptr_t) tst_func2;
}
/* malloc functions. */
return sym->st_value;
}
abort ();
}
-104
View File
@@ -1,104 +0,0 @@
/* Audit modules for tst-audit24b.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <tst-auditmod24.h>
#define TEST_NAME "tst-audit24b"
#define TEST_FUNC "tst_audit24b"
#define AUDIT24_COOKIE 0x1
#define AUDIT24MOD1_COOKIE 0x2
#define AUDIT24MOD2_COOKIE 0x3
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
const char *p = strrchr (map->l_name, '/');
const char *l_name = p == NULL ? TEST_NAME : p + 1;
uintptr_t ck = -1;
if (strcmp (l_name, TEST_NAME "mod1.so") == 0)
ck = AUDIT24MOD1_COOKIE;
else if (strcmp (l_name, TEST_NAME "mod2.so") == 0)
ck = AUDIT24MOD2_COOKIE;
else if (strcmp (l_name, TEST_NAME) == 0)
ck = AUDIT24_COOKIE;
*cookie = ck;
return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
}
static int
tst_func1 (void)
{
return 1;
}
static int
tst_func2 (void)
{
return 2;
}
#if __ELF_NATIVE_CLASS == 64
uintptr_t
la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#else
uintptr_t
la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#endif
{
if (*refcook == AUDIT24_COOKIE)
{
if (*defcook == AUDIT24MOD1_COOKIE)
{
if (strcmp (symname, TEST_FUNC "mod1_func1") == 0)
return (uintptr_t) tst_func1;
else if (strcmp (symname, TEST_FUNC "mod1_func2") == 0)
return sym->st_value;
abort ();
}
/* malloc functions. */
return sym->st_value;
}
else if (*refcook == AUDIT24MOD1_COOKIE)
{
if (*defcook == AUDIT24MOD2_COOKIE
&& (strcmp (symname, TEST_FUNC "mod2_func1") == 0))
{
test_symbind_flags (*flags);
return (uintptr_t) tst_func2;
}
}
abort ();
}
-3
View File
@@ -1,3 +0,0 @@
#define TEST_NAME "tst-audit24c"
#define TEST_MOD "tst-audit24a"
#include "tst-auditmod24a.c"
-120
View File
@@ -1,120 +0,0 @@
/* Audit module for tst-audit24d.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <tst-auditmod24.h>
#define AUDIT24_COOKIE 0x0
#define AUDIT24MOD1_COOKIE 0x1
#define AUDIT24MOD2_COOKIE 0x2
#define AUDIT24MOD3_COOKIE 0x3
#define AUDIT24MOD4_COOKIE 0x4
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
const char *p = strrchr (map->l_name, '/');
const char *l_name = p == NULL ? "tst-audit24d" : p + 1;
uintptr_t ck = -1;
if (strcmp (l_name, "tst-audit24dmod1.so") == 0)
ck = AUDIT24MOD1_COOKIE;
else if (strcmp (l_name, "tst-audit24dmod2.so") == 0)
ck = AUDIT24MOD2_COOKIE;
else if (strcmp (l_name, "tst-audit24dmod3.so") == 0)
ck = AUDIT24MOD3_COOKIE;
else if (strcmp (l_name, "tst-audit24dmod.so") == 0)
ck = AUDIT24MOD4_COOKIE;
else if (strcmp (l_name, "tst-audit24d") == 0)
ck = AUDIT24_COOKIE;
*cookie = ck;
return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
}
static int
tst_audit24dmod1_func1 (void)
{
return 1;
}
static int
tst_audit24dmod2_func1 (void)
{
return 10;
}
static int
tst_audit24dmod3_func1 (void)
{
return 30;
}
#include <stdio.h>
#if __ELF_NATIVE_CLASS == 64
uintptr_t
la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#else
uintptr_t
la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#endif
{
if (*refcook == AUDIT24_COOKIE)
{
if (*defcook == AUDIT24MOD1_COOKIE)
{
if (strcmp (symname, "tst_audit24dmod1_func1") == 0)
return (uintptr_t) tst_audit24dmod1_func1;
else if (strcmp (symname, "tst_audit24dmod1_func2") == 0)
return sym->st_value;
abort ();
}
if (*defcook == AUDIT24MOD2_COOKIE
&& (strcmp (symname, "tst_audit24dmod2_func1") == 0))
return (uintptr_t) tst_audit24dmod2_func1;
/* malloc functions. */
return sym->st_value;
}
else if (*refcook == AUDIT24MOD1_COOKIE)
{
if (*defcook == AUDIT24MOD3_COOKIE
&& strcmp (symname, "tst_audit24dmod3_func1") == 0)
{
test_symbind_flags (*flags);
return (uintptr_t) tst_audit24dmod3_func1;
}
}
abort ();
}
-79
View File
@@ -1,79 +0,0 @@
/* Audit modules for tst-audit25a.
Copyright (C) 2022 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
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define AUDIT25_COOKIE 0x1
#define AUDIT25MOD1_COOKIE 0x2
#define AUDIT25MOD2_COOKIE 0x3
#define AUDIT25MOD3_COOKIE 0x2
#define AUDIT25MOD4_COOKIE 0x3
#define TEST_NAME "tst-audit25"
#define TEST_MOD "tst-audit25"
#define TEST_FUNC "tst_audit25"
unsigned int
la_version (unsigned int version)
{
return LAV_CURRENT;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
{
const char *p = strrchr (map->l_name, '/');
const char *l_name = p == NULL ? TEST_NAME : p + 1;
uintptr_t ck = -1;
if (strcmp (l_name, TEST_MOD "mod1.so") == 0)
ck = AUDIT25MOD1_COOKIE;
else if (strcmp (l_name, TEST_MOD "mod2.so") == 0)
ck = AUDIT25MOD2_COOKIE;
else if (strcmp (l_name, TEST_MOD "mod3.so") == 0)
ck = AUDIT25MOD3_COOKIE;
else if (strcmp (l_name, TEST_MOD "mod4.so") == 0)
ck = AUDIT25MOD4_COOKIE;
else if (strncmp (l_name, TEST_NAME, strlen (TEST_NAME)) == 0)
ck = AUDIT25_COOKIE;
*cookie = ck;
return ck == -1 ? 0 : LA_FLG_BINDFROM | LA_FLG_BINDTO;
}
#if __ELF_NATIVE_CLASS == 64
uintptr_t
la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#else
uintptr_t
la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
uintptr_t *refcook, uintptr_t *defcook,
unsigned int *flags, const char *symname)
#endif
{
if (*refcook != -1 && *defcook != -1)
fprintf (stderr, "la_symbind: %s %u\n", symname,
*flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
return sym->st_value;
}

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