Compare commits

...
Author SHA1 Message Date
Szabolcs Nagy 529cfa039a Fix elf/tst-audit25a with default bind now toolchains
This test relies on lazy binding for the executable so request that
explicitly in case the toolchain defaults to bind now.

(cherry picked from commit 80a08d0faa)
2022-03-29 17:02:51 -04:00
Ben Woodard b7f913c052 elf: Fix runtime linker auditing on aarch64 (BZ #26643)
The rtld audit support show two problems on aarch64:

  1. _dl_runtime_resolve does not preserve x8, the indirect result
      location register, which might generate wrong result calls
      depending of the function signature.

  2. The NEON Q registers pushed onto the stack by _dl_runtime_resolve
     were twice the size of D registers extracted from the stack frame by
     _dl_runtime_profile.

While 2. might result in wrong information passed on the PLT tracing,
1. generates wrong runtime behaviour.

The aarch64 rtld audit support is changed to:

  * Both La_aarch64_regs and La_aarch64_retval are expanded to include
    both x8 and the full sized NEON V registers, as defined by the
    ABI.

  * dl_runtime_profile needed to extract registers saved by
    _dl_runtime_resolve and put them into the new correctly sized
    La_aarch64_regs structure.

  * The LAV_CURRENT check is change to only accept new audit modules
    to avoid the undefined behavior of not save/restore x8.

  * Different than other architectures, audit modules older than
    LAV_CURRENT are rejected (both La_aarch64_regs and La_aarch64_retval
    changed their layout and there are no requirements to support multiple
    audit interface with the inherent aarch64 issues).

  * A new field is also reserved on both La_aarch64_regs and
    La_aarch64_retval to support variant pcs symbols.

Similar to x86, a new La_aarch64_vector type to represent the NEON
register is added on the La_aarch64_regs (so each type can be accessed
directly).

Since LAV_CURRENT was already bumped to support bind-now, there is
no need to increase it again.

Checked on aarch64-linux-gnu.

Co-authored-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit ce9a68c57c)

Resolved conflicts:
	NEWS
	elf/rtld.c
2022-03-29 17:02:36 -04:00
Adhemerval Zanella 1d1466e7c4 elf: Issue la_symbind for bind-now (BZ #23734)
The audit symbind callback is not called for binaries built with
-Wl,-z,now or when LD_BIND_NOW=1 is used, nor the PLT tracking callbacks
(plt_enter and plt_exit) since this would change the expected
program semantics (where no PLT is expected) and would have performance
implications (such as for BZ#15533).

LAV_CURRENT is also bumped to indicate the audit ABI change (where
la_symbind flags are set by the loader to indicate no possible PLT
trace).

To handle powerpc64 ELFv1 function descriptor, _dl_audit_symbind
requires to know whether bind-now is used so the symbol value is
updated to function text segment instead of the OPD (for lazy binding
this is done by PPC64_LOAD_FUNCPTR on _dl_runtime_resolve).

Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
powerpc64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 32612615c5)

Resolved conflicts:
	NEWS
2022-03-29 17:02:31 -04:00
Adhemerval Zanella e798a21fef elf: Move LAV_CURRENT to link_lavcurrent.h
No functional change.

(cherry picked from commit 54816ae98d)

Resolved conflicts:
	elf/Makefile
2022-03-29 17:02:26 -04:00
Adhemerval Zanella faedaa0f9a elf: Fix initial-exec TLS access on audit modules (BZ #28096)
For audit modules and 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.

This patch fixes it by setting l_auditing link_map field not only
for the audit modules, but also for all its dependencies.  This is
used on _dl_allocate_tls_init to avoid the static TLS initialization
at load time.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 254d3d5aef)
2022-03-29 17:02:24 -04:00
Adhemerval Zanella b8d11f9551 elf: Do not fail for failed dlmopen on audit modules (BZ #28061)
The dl_main sets the LM_ID_BASE to RT_ADD just before starting to
add load new shared objects.  The state is set to RT_CONSISTENT just
after all objects are loaded.

However if a audit modules tries to dlmopen an inexistent module,
the _dl_open will assert that the namespace is in an inconsistent
state.

This is different than dlopen, since first it will not use
LM_ID_BASE and second _dl_map_object_from_fd is the sole responsible
to set and reset the r_state value.

So the assert on _dl_open can not really be seen if the state is
consistent, since _dt_main resets it.  This patch removes the assert.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 484e672dda)

Resolved conflicts:
	elf/Makefile
	elf/dl-open.c
2022-03-29 17:02:19 -04:00
Adhemerval Zanella 6c5ae75031 elf: Add la_activity during application exit
la_activity is not called during application exit, even though
la_objclose is.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 5fa11a2bc9)
2022-03-29 17:02:17 -04:00
Adhemerval Zanella e206033c27 elf: Issue audit la_objopen for vDSO
The vDSO is is listed in the link_map chain, but is never the subject of
an la_objopen call.  A new internal flag __RTLD_VDSO is added that
acts as __RTLD_OPENEXEC to allocate the required 'struct auditstate'
extra space for the 'struct link_map'.

The return value from the callback is currently ignored, since there
is no PLT call involved by glibc when using the vDSO, neither the vDSO
are exported directly.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit f0e23d34a7)

Resolved conflicts:
	elf/Makefile
2022-03-29 17:02:12 -04:00
Adhemerval Zanella 3723319805 elf: Add audit tests for modules with TLSDESC
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit d1b38173c9)
2022-03-29 17:02:08 -04:00
Adhemerval Zanella 09c5dcf73b elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533)
The rtld-audit interfaces introduces a slowdown due to enabling
profiling instrumentation (as if LD_AUDIT implied LD_PROFILE).
However, instrumenting is only necessary if one of audit libraries
provides PLT callbacks (la_pltenter or la_pltexit symbols).  Otherwise,
the slowdown can be avoided.

The following patch adjusts the logic that enables profiling to iterate
over all audit modules and check if any of those provides a PLT hook.
To keep la_symbind to work even without PLT callbacks, _dl_fixup now
calls the audit callback if the modules implements it.

Co-authored-by: Alexander Monakov <amonakov@ispras.ru>

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 063f9ba220)

Resolved conflicts:
	NEWS
	elf/Makefile
2022-03-29 17:02:03 -04:00
Adhemerval Zanella 696f66660b elf: Add _dl_audit_pltexit
It consolidates the code required to call la_pltexit audit
callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 8c0664e2b8)

Resolved conflicts:
	sysdeps/hppa/dl-runtime.c
2022-03-29 17:01:54 -04:00
Adhemerval Zanella d04bba58a2 elf: Add _dl_audit_pltenter
It consolidates the code required to call la_pltenter audit
callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit eff687e846)
2022-03-29 17:01:52 -04:00
Adhemerval Zanella e6e3d4cd26 elf: Add _dl_audit_preinit
It consolidates the code required to call la_preinit audit
callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 0b98a87487)
2022-03-29 17:01:50 -04:00
Adhemerval Zanella 416fbda1c1 elf: Add _dl_audit_symbind_alt and _dl_audit_symbind
It consolidates the code required to call la_symbind{32,64} audit
callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit cda4f265c6)
2022-03-29 17:01:48 -04:00
Adhemerval Zanella 5e7f59255b elf: Add _dl_audit_objclose
It consolidates the code required to call la_objclose audit
callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 311c9ee54e)
2022-03-29 17:01:45 -04:00
Adhemerval Zanella 2e1f6346b6 elf: Add _dl_audit_objsearch
It consolidates the code required to call la_objsearch audit
callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit c91008d349)
2022-03-29 17:01:43 -04:00
Adhemerval Zanella 59da7f4ccb elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
It consolidates the code required to call la_activity audit
callback.

Also for a new Lmid_t the namespace link_map list are empty, so it
requires to check if before using it.  This can happen for when audit
module is used along with dlmopen.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 3dac3959a5)
2022-03-29 17:01:40 -04:00
Adhemerval Zanella 737eb83549 elf: Add _dl_audit_objopen
It consolidates the code required to call la_objopen audit callback.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit aee6e90f93)

Resolved conflicts:
	elf/Makefile
2022-03-29 17:01:36 -04:00
Adhemerval Zanella e135c4a918 elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062)
It ensures that the the namespace is guaranteed to not be empty.

Checked on x86_64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit ed3ce71f5c)

Resolved conflicts:
	elf/Makefile
2022-03-29 17:01:29 -04:00
Adhemerval Zanella 41348211d4 elf: Fix dynamic-link.h usage on rtld.c
The 4af6982e4c fix does not fully handle RTLD_BOOTSTRAP usage on
rtld.c due two issues:

  1. RTLD_BOOTSTRAP is also used on dl-machine.h on various
     architectures and it changes the semantics of various machine
     relocation functions.

  2. The elf_get_dynamic_info() change was done sideways, previously
     to 490e6c62aa get-dynamic-info.h was included by the first
     dynamic-link.h include *without* RTLD_BOOTSTRAP being defined.
     It means that the code within elf_get_dynamic_info() that uses
     RTLD_BOOTSTRAP is in fact unused.

To fix 1. this patch now includes dynamic-link.h only once with
RTLD_BOOTSTRAP defined.  The ELF_DYNAMIC_RELOCATE call will now have
the relocation fnctions with the expected semantics for the loader.

And to fix 2. part of 4af6982e4c is reverted (the check argument
elf_get_dynamic_info() is not required) and the RTLD_BOOTSTRAP
pieces are removed.

To reorganize the includes the static TLS definition is moved to
its own header to avoid a circular dependency (it is defined on
dynamic-link.h and dl-machine.h requires it at same time other
dynamic-link.h definition requires dl-machine.h defitions).

Also ELF_MACHINE_NO_REL, ELF_MACHINE_NO_RELA, and ELF_MACHINE_PLT_REL
are moved to its own header.  Only ancient ABIs need special values
(arm, i386, and mips), so a generic one is used as default.

The powerpc Elf64_FuncDesc is also moved to its own header, since
csu code required its definition (which would require either include
elf/ folder or add a full path with elf/).

Checked on x86_64, i686, aarch64, armhf, powerpc64, powerpc32,
and powerpc64le.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit d6d89608ac)

Resolved conflicts:
	elf/rtld.c
2022-03-29 17:01:07 -04:00
Adhemerval Zanella ef2c249cbd elf: Fix elf_get_dynamic_info definition
Before to 490e6c62aa ('elf: Avoid nested functions in the loader
[BZ #27220]'), elf_get_dynamic_info() was defined twice on rtld.c: on
the first dynamic-link.h include and later within _dl_start().  The
former definition did not define DONT_USE_BOOTSTRAP_MAP and it is used
on setup_vdso() (since it is a global definition), while the former does
define DONT_USE_BOOTSTRAP_MAP and it is used on loader self-relocation.

With the commit change, the function is now included and defined once
instead of defined as a nested function.  So rtld.c defines without
defining RTLD_BOOTSTRAP and it brokes at least powerpc32.

This patch fixes by moving the get-dynamic-info.h include out of
dynamic-link.h, which then the caller can corirectly set the expected
semantic by defining STATIC_PIE_BOOTSTRAP, RTLD_BOOTSTRAP, and/or
RESOLVE_MAP.

It also required to enable some asserts only for the loader bootstrap
to avoid issues when called from setup_vdso().

As a side note, this is another issues with nested functions: it is
not clear from pre-processed output (-E -dD) how the function will
be build and its semantic (since nested function will be local and
extra C defines may change it).

I checked on x86_64-linux-gnu (w/o --enable-static-pie),
i686-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu-power4,
aarch64-linux-gnu, arm-linux-gnu, sparc64-linux-gnu, and
s390x-linux-gnu.

Reviewed-by: Fangrui Song <maskray@google.com>
(cherry picked from commit 4af6982e4c)

Resolved conflicts:
	elf/rtld.c
2022-03-29 17:00:07 -04:00
Fangrui Song 87bb97efa2 elf: Avoid nested functions in the loader [BZ #27220]
dynamic-link.h is included more than once in some elf/ files (rtld.c,
dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested
functions. This harms readability and the nested functions usage
is the biggest obstacle prevents Clang build (Clang doesn't support GCC
nested functions).

The key idea for unnesting is to add extra parameters (struct link_map
*and struct r_scope_elm *[]) to RESOLVE_MAP,
ELF_MACHINE_BEFORE_RTLD_RELOC, ELF_DYNAMIC_RELOCATE, elf_machine_rel[a],
elf_machine_lazy_rel, and elf_machine_runtime_setup. (This is inspired
by Stan Shebs' ppc64/x86-64 implementation in the
google/grte/v5-2.27/master which uses mixed extra parameters and static
variables.)

Future simplification:
* If mips elf_machine_runtime_setup no longer needs RESOLVE_GOTSYM,
  elf_machine_runtime_setup can drop the `scope` parameter.
* If TLSDESC no longer need to be in elf_machine_lazy_rel,
  elf_machine_lazy_rel can drop the `scope` parameter.

Tested on aarch64, i386, x86-64, powerpc64le, powerpc64, powerpc32,
sparc64, sparcv9, s390x, s390, hppa, ia64, armhf, alpha, and mips64.
In addition, tested build-many-glibcs.py with {arc,csky,microblaze,nios2}-linux-gnu
and riscv64-linux-gnu-rv64imafdc-lp64d.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 490e6c62aa)
2022-03-29 16:58:38 -04:00
John David Anglin d53b9cc391 hppa: Use END instead of PSEUDO_END in swapcontext.S
(cherry picked from commit 7a5c440102)
2022-03-15 23:14:37 +00:00
John David Anglin 738ee53f0c hppa: Implement swapcontext in assembler (bug 28960)
When swapcontext.c is compiled without -g, the following error occurs:
Error: CFI instruction used without previous .cfi_startproc

Fix by converting swapcontext routine to assembler.
2022-03-15 23:12:37 +00:00
Siddhesh Poyarekar 224d8c1890 debug: Synchronize feature guards in fortified functions [BZ #28746]
Some functions (e.g. stpcpy, pread64, etc.) had moved to POSIX in the
main headers as they got incorporated into the standard, but their
fortified variants remained under __USE_GNU.  As a result, these
functions did not get fortified when _GNU_SOURCE was not defined.

Add test wrappers that check all functions tested in tst-chk0 at all
levels with _GNU_SOURCE undefined and then use the failures to (1)
exclude checks for _GNU_SOURCE functions in these tests and (2) Fix
feature macro guards in the fortified function headers so that they're
the same as the ones in the main headers.

This fixes BZ #28746.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit fcfc908681)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar f8c2f620f1 debug: Autogenerate _FORTIFY_SOURCE tests
Rename debug/tst-chk1.c to debug/tst-fortify.c and add make hackery to
autogenerate tests with different macros enabled to build and run the
same test with different configurations as well as different
fortification levels.

The change also ends up expanding the -lfs tests to include
_FORTIFY_SOURCE=3.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit db27f1251b)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar d6a58bd81d Enable _FORTIFY_SOURCE=3 for gcc 12 and above
gcc 12 now has support for the __builtin_dynamic_object_size builtin.
Adapt the macro checks to enable _FORTIFY_SOURCE=3 on gcc 12 and above.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 86bf0feb0e)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar 10f7bdebe5 fortify: Fix spurious warning with realpath
The length and object size arguments were swapped around for realpath.
Also add a smoke test so that any changes in this area get caught in
future.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 2bbd07c715)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar 98ea9372cc __glibc_unsafe_len: Fix comment
We know that the length is *unsafe*.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit ae23fa3e5f)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar 536910724d debug: Add tests for _FORTIFY_SOURCE=3
Add some testing coverage for _FORTIFY_SOURCE=3.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit ad6f2a010c)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar 0e6ebf06e4 Make sure that the fortified function conditionals are constant
In _FORTIFY_SOURCE=3, the size expression may be non-constant,
resulting in branches in the inline functions remaining intact and
causing a tiny overhead.  Clang (and in future, gcc) make sure that
the -1 case is always safe, i.e. any comparison of the generated
expression with (size_t)-1 is always false so that bit is taken care
of.  The rest is avoidable since we want the _chk variant whenever we
have a size expression and it's not -1.

Rework the conditionals in a uniform way to clearly indicate two
conditions at compile time:

- Either the size is unknown (-1) or we know at compile time that the
  operation length is less than the object size.  We can call the
  original function in this case.  It could be that either the length,
  object size or both are non-constant, but the compiler, through
  range analysis, is able to fold the *comparison* to a constant.

- The size and length are known and the compiler can see at compile
  time that operation length > object size.  This is valid grounds for
  a warning at compile time, followed by emitting the _chk variant.

For everything else, emit the _chk variant.

This simplifies most of the fortified function implementations and at
the same time, ensures that only one call from _chk or the regular
function is emitted.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit a643f60c53)
2022-03-11 20:36:24 +05:30
Siddhesh Poyarekar c82bdf033f Don't add access size hints to fortifiable functions
In the context of a function definition, the size hints imply that the
size of an object pointed to by one parameter is another parameter.
This doesn't make sense for the fortified versions of the functions
since that's the bit it's trying to validate.

This is harmless with __builtin_object_size since it has fairly simple
semantics when it comes to objects passed as function parameters.
With __builtin_dynamic_object_size we could (as my patchset for gcc[1]
already does) use the access attribute to determine the object size in
the general case but it misleads the fortified functions.

Basically the problem occurs when access attributes are present on
regular functions that have inline fortified definitions to generate
_chk variants; the attributes get inherited by these definitions,
causing problems when analyzing them.  For example with poll(fds, nfds,
timeout), nfds is hinted using the __attr_access as being the size of
fds.

Now, when analyzing the inline function definition in bits/poll2.h, the
compiler sees that nfds is the size of fds and tries to use that
information in the function body.  In _FORTIFY_SOURCE=3 case, where the
object size could be a non-constant expression, this information results
in the conclusion that nfds is the size of fds, which defeats the
purpose of the implementation because we're trying to check here if nfds
does indeed represent the size of fds.  Hence for this case, it is best
to not have the access attribute.

With the attributes gone, the expression evaluation should get delayed
until the function is actually inlined into its destinations.

Disable the access attribute for fortified function inline functions
when building at _FORTIFY_SOURCE=3 to make this work better.  The
access attributes remain for the _chk variants since they can be used
by the compiler to warn when the caller is passing invalid arguments.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581125.html

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit e938c02748)
2022-03-11 20:36:24 +05:30
Florian Weimer 54b1273395 nss: Protect against errno changes in function lookup (bug 28953)
dlopen may clobber errno.  The nss_test_errno module uses an ELF
constructor to achieve that, but there could be internal errors
during dlopen that cause this, too.  Therefore, the NSS framework
has to guard against such errno clobbers.

__nss_module_get_function is currently the only function that calls
__nss_module_load, so it is sufficient to save and restore errno
around this call.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 9bdf92c79d)
2022-03-11 11:14:24 +01:00
Florian Weimer b53f0c11de nss: Do not mention NSS test modules in <gnu/lib-names.h>
They are not actually installed.  Use the nss_files version instead
in nss/Makefile, similar to how __nss_shlib_revision is derived
from LIBNSS_FILES_SO.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit aefc79ab5a)
2022-03-11 11:13:34 +01:00
Florian Weimer b5032c3d37 io: Add fsync call in tst-stat
io/tst-stat and io/tst-stat-lfs fail sporadically on the Fedora
builders, and this change hopefully helps to avoid the issue.

(cherry picked from commit ae13228409)
2022-03-11 11:13:33 +01:00
John David Anglin 6c9c230765 hppa: Fix warnings from _dl_lookup_address
This change fixes two warnings from _dl_lookup_address.

The first warning comes from dropping the volatile keyword from
desc in the call to _dl_read_access_allowed.  We now have a full
atomic barrier between loading desc[0] and the access check, so
desc no longer needs to be declared as volatile.

The second warning comes from the implicit declaration of
_dl_fix_reloc_arg.  This is fixed by including dl-runtime.h and
declaring _dl_fix_reloc_arg in dl-runtime.h.
2022-03-06 16:04:32 +00:00
John David Anglin 40fc6a74ee nptl: Fix cleanups for stack grows up [BZ# 28899]
_STACK_GROWS_DOWN is defined to 0 when the stack grows up.  The
code in unwind.c used `#ifdef _STACK_GROWS_DOWN' to selct the
stack grows down define for FRAME_LEFT.  As a result, the
_STACK_GROWS_DOWN define was always selected and cleanups were
incorrectly sequenced when the stack grows up.

(cherry picked from commit 2bbc694df2)
2022-03-06 16:00:52 +00:00
John David Anglin f610d2935f hppa: Revise gettext trampoline design
The current getcontext return trampoline is overly complex and it
unnecessarily clobbers several registers.  By saving the context
pointer (r26) in the context, __getcontext_ret can restore any
registers not restored by setcontext.  This allows getcontext to
save and restore the entire register context present when getcontext
is entered.  We use the unused oR0 context slot for the return
from __getcontext_ret.

While this is not directly useful in C, it can be exploited in
assembly code.  Registers r20, r23, r24 and r25 are not clobbered
in the call path to getcontext.  This allows a small simplification
of swapcontext.

It also allows saving and restoring the 6-bit SAR register in the
LSB of the oSAR context slot.  The getcontext flag value can be
stored in the MSB of the oSAR slot.

(cherry picked from commit 9e7e5fda38)
2022-03-06 16:00:52 +00:00
John David Anglin c6f9085ee4 hppa: Fix swapcontext
This change fixes the failure of stdlib/tst-setcontext2 and
stdlib/tst-setcontext7 on hppa.  The implementation of swapcontext
in C is broken.  C saves the return pointer (rp) and any non
call-clobbered registers (in this case r3, r4 and r5) on the
stack.  However, the setcontext call in swapcontext pops the
stack and subsequent calls clobber the saved registers.  When
the context in oucp is restored, both tests fault.

Here we rewrite swapcontext in assembly code to avoid using
the stack for register values that need to be used after
restoration.  The getcontext and setcontext routines are
revised to save and restore register ret1 for normal returns.
We copy the oucp pointer to ret1.  This allows access to
the old context after calling getcontext and setcontext.

(cherry picked from commit 71b108d7eb)
2022-03-06 16:00:52 +00:00
John David Anglin 3be79b72d5 Fix elf/tst-audit2 on hppa
The test elf/tst-audit2 fails on hppa with a segmentation fault in the
long branch stub used to call malloc from calloc.  This occurs because
the test is not a PIC executable and calloc is called from the dynamic
linker before the dp register is initialized in _dl_start_user.

The fix is to move the dp register initialization into
elf_machine_runtime_setup.  Since the address of $global$ can't be
loaded directly, we continue to use the DT_PLTGOT value from the
the main_map to initialize dp.  Since l_main_map is not available
in v2.34 and earlier, we use a new function, elf_machine_main_map,
to find the main map.
2022-03-06 15:56:57 +00:00
Arjun Shankar 852361b5a3 localedef: Handle symbolic links when generating locale-archive
Whenever locale data for any locale included symbolic links, localedef
would throw the error "incomplete set of locale files" and exclude it
from the generated locale archive.  This commit fixes that.

Co-authored-by: Florian Weimer <fweimer@redhat.com>

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit ea89d5bbd9)
2022-03-03 11:58:03 +01:00
H.J. Lu d5d1c95aaf NEWS: Add a bug fix entry for BZ #28896 2022-02-18 19:09:03 -08:00
Noah Goldstein 15b00d2af0 x86: Fix TEST_NAME to make it a string in tst-strncmp-rtm.c
Previously TEST_NAME was passing a function pointer. This didn't fail
because of the -Wno-error flag (to allow for overflow sizes passed
to strncmp/wcsncmp)

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit b98d0bbf74)
2022-02-18 15:34:40 -08:00
Noah Goldstein d093b677c3 x86: Test wcscmp RTM in the wcsncmp overflow case [BZ #28896]
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
not checks around vzeroupper and would trigger spurious
aborts. This commit fixes that.

test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
AVX2 machines with and without RTM.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

(cherry picked from commit 7835d611af)
2022-02-18 14:59:54 -08:00
Noah GoldsteinandH.J. Lu 38e0d24794 x86: Fallback {str|wcs}cmp RTM in the ncmp overflow case [BZ #28896]
In the overflow fallback strncmp-avx2-rtm and wcsncmp-avx2-rtm would
call strcmp-avx2 and wcscmp-avx2 respectively. This would have
not checks around vzeroupper and would trigger spurious
aborts. This commit fixes that.

test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass on
AVX2 machines with and without RTM.

Co-authored-by: H.J. Lu <hjl.tools@gmail.com>

(cherry picked from commit c627209832)
2022-02-18 14:59:47 -08:00
H.J. Lu 04d60ce0f2 string: Add a testcase for wcsncmp with SIZE_MAX [BZ #28755]
Verify that wcsncmp (L("abc"), L("abd"), SIZE_MAX) == 0.  The new test
fails without

commit ddf0992cf5
Author: Noah Goldstein <goldstein.w.n@gmail.com>
Date:   Sun Jan 9 16:02:21 2022 -0600

    x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755]

and

commit 7e08db3359
Author: Noah Goldstein <goldstein.w.n@gmail.com>
Date:   Sun Jan 9 16:02:28 2022 -0600

    x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755]

This is for BZ #28755.

Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>

(cherry picked from commit aa5a720056)
2022-02-17 11:14:42 -08:00
Dmitry V. Levin 007e054d78 linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ #28865]
get_nprocs() and get_nprocs_conf() use various methods to obtain an
accurate number of processors.  Re-introduce __get_nprocs_sched() as
a source of information, and fix the order in which these methods are
used to return the most accurate information.  The primary source of
information used in both functions remains unchanged.

This also changes __get_nprocs_sched() error return value from 2 to 0,
but all its users are already prepared to handle that.

Old fallback order:
  get_nprocs:
    /sys/devices/system/cpu/online -> /proc/stat -> 2
  get_nprocs_conf:
    /sys/devices/system/cpu/ -> /proc/stat -> 2

New fallback order:
  get_nprocs:
    /sys/devices/system/cpu/online -> /proc/stat -> sched_getaffinity -> 2
  get_nprocs_conf:
    /sys/devices/system/cpu/ -> /proc/stat -> sched_getaffinity -> 2

Fixes: 342298278e ("linux: Revert the use of sched_getaffinity on get_nproc")
Closes: BZ #28865
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

(cherry picked from commit e1d32b8364)
2022-02-07 20:18:29 +00:00
Adhemerval Zanella d64b08d5ba Add reference to BZ#28860 on NEWS 2022-02-03 17:48:46 -03:00
Adhemerval Zanella 0351c75c5f linux: Fix missing __convert_scm_timestamps (BZ #28860)
Commit 948ce73b31 made recvmsg/recvmmsg to always call
__convert_scm_timestamps for 64 bit time_t symbol, so adjust it to
always build it for __TIMESIZE != 64.

It fixes build for architecture with 32 bit time_t support when
configured with minimum kernel of 5.1.

(cherry-picked from 798d716df7)
2022-02-03 17:20:36 -03:00
Florian Weimer 6eaf10cbb7 socket: Do not use AF_NETLINK in __opensock
It is not possible to use interface ioctls with netlink sockets
on all Linux kernels.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 3d981795cd)
2022-02-03 16:22:10 +01:00
Samuel Thibault d8302ba2da hurd if_index: Explicitly use AF_INET for if index discovery
5bf07e1b3a ("Linux: Simplify __opensock and fix race condition [BZ #28353]")
made __opensock try NETLINK then UNIX then INET. On the Hurd, only INET
knows about network interfaces, so better actually specify that in
if_index.

(cherry picked from commit 1d3decee99)
2022-02-03 16:22:04 +01:00
Florian Weimer ad615b59c7 Linux: Simplify __opensock and fix race condition [BZ #28353]
AF_NETLINK support is not quite optional on modern Linux systems
anymore, so it is likely that the first attempt will always succeed.
Consequently, there is no need to cache the result.  Keep AF_UNIX
and the Internet address families as a fallback, for the rare case
that AF_NETLINK is missing.  The other address families previously
probed are totally obsolete be now, so remove them.

Use this simplified version as the generic implementation, disabling
Netlink support as needed.

(cherry picked from commit 5bf07e1b3a)
2022-02-03 16:21:50 +01:00
Gleb Fotengauer-Malinovskiy 05c83ccaf5 linux: __get_nprocs_sched: do not feed CPU_COUNT_S with garbage [BZ #28850]
Pass the actual number of bytes returned by the kernel.

Fixes: 33099d72e4 ("linux: Simplify get_nprocs")
Reviewed-by: Dmitry V. Levin <ldv@altlinux.org>

(cherry picked from commit 97ba273b50)
2022-02-03 11:04:08 +00:00
H.J. Lu 008003dc6e tst-socket-timestamp-compat.c: Check __TIMESIZE [BZ #28837]
time_t size is defined by __TIMESIZE, not __WORDSIZE.  Check __TIMESIZE,
instead of __WORDSIZE, for time_t size.  This fixes BZ #28837.

(cherry pick from commit 77a602ebb0)
2022-02-01 15:52:46 -03:00
Adhemerval Zanella 489d0b8b32 Linux: Only generate 64 bit timestamps for 64 bit time_t recvmsg/recvmmsg
The timestamps created by __convert_scm_timestamps only make sense for
64 bit time_t programs, 32 bit time_t programs will ignore 64 bit time_t
timestamps since SO_TIMESTAMP will be defined to old values (either by
glibc or kernel headers).

Worse, if the buffer is not suffice MSG_CTRUNC is set to indicate it
(which breaks some programs [1]).

This patch makes only 64 bit time_t recvmsg and recvmmsg to call
__convert_scm_timestamps.  Also, the assumption to called it is changed
from __ASSUME_TIME64_SYSCALLS to __TIMESIZE != 64 since the setsockopt
might be called by libraries built without __TIME_BITS=64.  The
MSG_CTRUNC is only set for the 64 bit symbols, it should happen only
if 64 bit time_t programs run older kernels.

Checked on x86_64-linux-gnu and i686-linux-gnu.

[1] https://github.com/systemd/systemd/pull/20567

Reviewed-by: Florian Weimer <fweimer@redhat.com>

(cherry picked from commit 948ce73b31)
2022-02-01 15:52:41 -03:00
Adhemerval ZanellaandFabian Vogt e098446037 linux: Fix ancillary 64-bit time timestamp conversion (BZ #28349, BZ#28350)
The __convert_scm_timestamps only updates the control message last
pointer for SOL_SOCKET type, so if the message control buffer contains
multiple ancillary message types the converted timestamp one might
overwrite a valid message.

The test checks if the extra ancillary space is correctly handled
by recvmsg/recvmmsg, where if there is no extra space for the 64-bit
time_t converted message the control buffer should be marked with
MSG_TRUNC.  It also check if recvmsg/recvmmsg handle correctly multiple
ancillary data.

Checked on x86_64-linux and on i686-linux-gnu on both 5.11 and
4.15 kernel.

Co-authored-by: Fabian Vogt <fvogt@suse.de>

Reviewed-by: Florian Weimer <fweimer@redhat.com>

(cherry picked from commit 8fba672472)
2022-02-01 15:52:37 -03:00
Adhemerval Zanella e09e7b1492 support: Add support_socket_so_timestamp_time64
Check if the socket support 64-bit network packages timestamps
(SO_TIMESTAMP and SO_TIMESTAMPNS).  This will be used on recvmsg
and recvmmsg tests to check if the timestamp should be generated.

Reviewed-by: Florian Weimer <fweimer@redhat.com>

(cherry picked from 38bc0f4e78)
2022-02-01 15:52:33 -03:00
H.J. Lu aa601d0244 x86: Use CHECK_FEATURE_PRESENT to check HLE [BZ #27398]
HLE is disabled on blacklisted CPUs.  Use CHECK_FEATURE_PRESENT, instead
of CHECK_FEATURE_ACTIVE, to check HLE.

(cherry picked from commit 501246c5e2)
2022-02-01 05:44:27 -08:00
H.J. Lu b952c25dc7 x86: Black list more Intel CPUs for TSX [BZ #27398]
Disable TSX and enable RTM_ALWAYS_ABORT for Intel CPUs listed in:

https://www.intel.com/content/www/us/en/support/articles/000059422/processors.html

This fixes BZ #27398.

Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 1e000d3d33)
2022-02-01 05:44:12 -08:00
Florian Weimer 948ebc098e Fix glibc 2.34 ABI omission (missing GLIBC_2.34 in dynamic loader)
The glibc 2.34 release really should have added a GLIBC_2.34
symbol to the dynamic loader. With it, we could move functions such
as dlopen or pthread_key_create that work on process-global state
into the dynamic loader (once we have fixed a longstanding issue
with static linking).  Without the GLIBC_2.34 symbol, yet another
new symbol version would be needed because old glibc will fail to
load binaries due to the missing symbol version in ld.so that newly
linked programs will require.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit af121ae3e7)
2022-01-31 14:58:02 +01:00
Florian Weimer de6cdd6875 elf/Makefile: Reflow and sort most variable assignments
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit 7de01e60c2)
2022-01-31 14:57:00 +01:00
H.J. Lu 511b244cc5 elf: Add a comment after trailing backslashes
(cherry picked from commit f4f70c2895)
2022-01-31 14:26:45 +01:00
H.J. Lu 31186e2cb7 elf: Sort tests and modules-names
Sort tests and modules-names to reduce future conflicts.

(cherry picked from commit 28713c0612)
2022-01-31 14:26:38 +01:00
H.J. Lu 72123e1b56 NEWS: Add a bug entry for BZ #28755 2022-01-26 20:20:43 -08:00
Noah Goldstein 08beb3a3f4 x86: Fix __wcsncmp_evex in strcmp-evex.S [BZ# 28755]
Fixes [BZ# 28755] for wcsncmp by redirecting length >= 2^56 to
__wcscmp_evex. For x86_64 this covers the entire address range so any
length larger could not possibly be used to bound `s1` or `s2`.

test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass.

Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 7e08db3359)
2022-01-26 14:04:01 -08:00
Noah Goldstein b50d5b746c x86: Fix __wcsncmp_avx2 in strcmp-avx2.S [BZ# 28755]
Fixes [BZ# 28755] for wcsncmp by redirecting length >= 2^56 to
__wcscmp_avx2. For x86_64 this covers the entire address range so any
length larger could not possibly be used to bound `s1` or `s2`.

test-strcmp, test-strncmp, test-wcscmp, and test-wcsncmp all pass.

Signed-off-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit ddf0992cf5)
2022-01-26 14:03:42 -08:00
Aurelien Jarno 1b9cd6a721 NEWS: add bug entry for BZ #28769 and BZ #28770 2022-01-24 23:45:03 +01:00
Florian Weimer 3438bbca90 Linux: Detect user namespace support in io/tst-getcwd-smallbuff
Otherwise the test fails with certain container runtimes.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 5b8e7980c5)
2022-01-24 18:15:02 +01:00
Siddhesh Poyarekar d084965adc realpath: Avoid overwriting preexisting error (CVE-2021-3998)
Set errno and failure for paths that are too long only if no other error
occurred earlier.

Related: BZ #28770

Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 84d2d0fe20)
2022-01-24 21:44:54 +05:30
Siddhesh Poyarekar 472e799a5f getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999)
No valid path returned by getcwd would fit into 1 byte, so reject the
size early and return NULL with errno set to ERANGE.  This change is
prompted by CVE-2021-3999, which describes a single byte buffer
underflow and overflow when all of the following conditions are met:

- The buffer size (i.e. the second argument of getcwd) is 1 byte
- The current working directory is too long
- '/' is also mounted on the current working directory

Sequence of events:

- In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG
  because the linux kernel checks for name length before it checks
  buffer size

- The code falls back to the generic getcwd in sysdeps/posix

- In the generic func, the buf[0] is set to '\0' on line 250

- this while loop on line 262 is bypassed:

    while (!(thisdev == rootdev && thisino == rootino))

  since the rootfs (/) is bind mounted onto the directory and the flow
  goes on to line 449, where it puts a '/' in the byte before the
  buffer.

- Finally on line 458, it moves 2 bytes (the underflowed byte and the
  '\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow.

- buf is returned on line 469 and errno is not set.

This resolves BZ #28769.

Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Signed-off-by: Qualys Security Advisory <qsa@qualys.com>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 23e0e8f5f1)
2022-01-24 11:37:06 +05:30
Siddhesh Poyarekar 8c8a71c85f tst-realpath-toolong: Fix hurd build
Define PATH_MAX to a constant if it isn't already defined, like in hurd.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 976db046bc)
2022-01-24 11:36:59 +05:30
Siddhesh Poyarekar f7a79879c0 realpath: Set errno to ENAMETOOLONG for result larger than PATH_MAX [BZ #28770]
realpath returns an allocated string when the result exceeds PATH_MAX,
which is unexpected when its second argument is not NULL.  This results
in the second argument (resolved) being uninitialized and also results
in a memory leak since the caller expects resolved to be the same as the
returned value.

Return NULL and set errno to ENAMETOOLONG if the result exceeds
PATH_MAX.  This fixes [BZ #28770], which is CVE-2021-3998.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit ee8d5e33ad)
2022-01-24 11:36:19 +05:30
Siddhesh Poyarekar 73c362840c stdlib: Fix formatting of tests list in Makefile
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit f9dab1b5f2)
2022-01-24 11:36:09 +05:30
Siddhesh Poyarekar 269eb9d930 stdlib: Sort tests in Makefile
Put one test per line and sort them.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 5b766603ef)
2022-01-24 11:36:03 +05:30
Siddhesh Poyarekar 062ff490c1 support: Add helpers to create paths longer than PATH_MAX
Add new helpers support_create_and_chdir_toolong_temp_directory and
support_chdir_toolong_temp_directory to create and descend into
directory trees longer than PATH_MAX.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit fb7bff12e8)
2022-01-24 11:35:18 +05:30
Paul A. Clarke 82b1acd9de powerpc: Fix unrecognized instruction errors with recent binutils
Recent versions of binutils (with commit
b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a) stopped preserving "sticky"
options across a base `.machine` directive, nullifying the use of
passing "-many" through GCC to the assembler.  As a result, some
instructions which were recognized even under older, more stringent
`.machine` directives become unrecognized instructions in that
context.

In `sysdeps/powerpc/tst-set_ppr.c`, the use of the `mfppr32` extended
mnemonic became unrecognized, as the default compilation with GCC for
32bit powerpc adds a `.machine ppc` in the resulting assembly, so the
command line option `-Wa,-many` is essentially ignored, and the ISA 2.06
instructions and mnemonics, like `mfppr32`, are unrecognized.

The compilation of `sysdeps/powerpc/tst-set_ppr.c` fails with:
Error: unrecognized opcode: `mfppr32'

Add appropriate `.machine` directives in the assembly to bracket the
`mfppr32` instruction.

Part of a 2019 fix (commit 9250e6610f) to
the above test's Makefile to add `-many` to the compilation when GCC
itself stopped passing `-many` to the assember no longer has any effect,
so remove that.

Reported-by: Joseph Myers <joseph@codesourcery.com>
(cherry picked from commit ee874f44fd)
2022-01-18 23:05:42 +01:00
Aurelien Jarno 1d401d1fcc x86: use default cache size if it cannot be determined [BZ #28784]
In some cases (e.g QEMU, non-Intel/AMD CPU) the cache information can
not be retrieved and the corresponding values are set to 0.

Commit 2d651eb926 ("x86: Move x86 processor cache info to
cpu_features") changed the behaviour in such case by defining the
__x86_shared_cache_size and __x86_data_cache_size variables to 0 instead
of using the default values. This cause an issue with the i686 SSE2
optimized bzero/routine which assumes that the cache size is at least
128 bytes, and otherwise tries to zero/set the whole address space minus
128 bytes.

Fix that by restoring the original code to only update
__x86_shared_cache_size and __x86_data_cache_size variables if the
corresponding cache sizes are not zero.

Fixes bug 28784
Fixes commit 2d651eb926

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit c242fcce06)
2022-01-17 19:46:24 +01:00
Florian Weimer 6890b8a3ae CVE-2022-23218: Buffer overflow in sunrpc svcunix_create (bug 28768)
The sunrpc function svcunix_create suffers from a stack-based buffer
overflow with overlong pathname arguments.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit f545ad4928)
2022-01-17 11:49:25 +01:00
Martin Sebor 1081f1d3dd sunrpc: Test case for clnt_create "unix" buffer overflow (bug 22542)
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit ef972a4c50)
2022-01-17 11:49:01 +01:00
Florian Weimer 7b5d433fd0 CVE-2022-23219: Buffer overflow in sunrpc clnt_create for "unix" (bug 22542)
Processing an overlong pathname in the sunrpc clnt_create function
results in a stack-based buffer overflow.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 226b46770c)
2022-01-17 11:48:59 +01:00
Florian Weimer 5575daae50 socket: Add the __sockaddr_un_set function
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit e368b12f6c)
2022-01-17 11:44:41 +01:00
H.J. Lu 03e6e02e6a Disable debuginfod in printer tests [BZ #28757]
With gdb-11.1-6.fc35.x86_64, I got

FAIL: nptl/test-cond-printers
FAIL: nptl/test-condattr-printers
FAIL: nptl/test-mutex-printers
FAIL: nptl/test-mutexattr-printers
FAIL: nptl/test-rwlock-printers
FAIL: nptl/test-rwlockattr-printers

$ cat nptl/test-condattr-printers.out
Error: Response does not match the expected pattern.
Command: start
Expected pattern: main
Response:  Temporary breakpoint 1 at 0x11d5: file test-condattr-printers.c, line 43.
Starting program: /export/build/gnu/tools-build/glibc-cet-gitlab/build-x86_64-linux/nptl/test-condattr-printers

This GDB supports auto-downloading debuginfo from the following URLs:
https://debuginfod.fedoraproject.org/
Enable debuginfod for this session? (y or [n])

Disable debuginfod to avoid GDB messages.  This fixes BZ #28757.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 7de501f941)
2022-01-14 14:37:32 +01:00
Joseph Myers 705f1e4606 Update syscall lists for Linux 5.16
Linux 5.16 has one new syscall, futex_waitv.  Update
syscall-names.list and regenerate the arch-syscall.h headers with
build-many-glibcs.py update-syscalls.

Tested with build-many-glibcs.py.

(cherry picked from commit 4997a533ae)
2022-01-14 09:35:16 +01:00
Florian Weimer 2fe2af88ab i386: Remove broken CAN_USE_REGISTER_ASM_EBP (bug 28771)
The configure check for CAN_USE_REGISTER_ASM_EBP tried to compile a
simple function that uses %ebp as an inline assembly operand.  If
compilation failed, CAN_USE_REGISTER_ASM_EBP was set 0, which
eventually had these consequences:

(1) %ebx was avoided as an inline assembly operand, with an
    assembler macro hack to avoid unnecessary register moves.
(2) %ebp was avoided as an inline assembly operand, using an
    out-of-line syscall function for 6-argument system calls.

(1) is no longer needed for any GCC version that is supported for
building glibc.  %ebx can be used directly as a register operand.
Therefore, this commit removes the %ebx avoidance completely.  This
avoids the assembler macro hack, which turns out to be incompatible
with the current Systemtap probe macros (which switch to .altmacro
unconditionally).

(2) is still needed in many build configurations.  The existing
configure check cannot really capture that because the simple function
succeeds to compile, while the full glibc build still fails.
Therefore, this commit removes the check, the CAN_USE_REGISTER_ASM_EBP
macro, and uses the out-of-line syscall function for 6-argument system
calls unconditionally.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit a78e6a10d0)
2022-01-13 15:21:32 +01:00
Joseph Myers 73558ffe84 Update syscall lists for Linux 5.15
Linux 5.15 has one new syscall, process_mrelease (and also enables the
clone3 syscall for RV32).  It also has a macro __NR_SYSCALL_MASK for
Arm, which is not a syscall but matches the pattern used for syscall
macro names.

Add __NR_SYSCALL_MASK to the names filtered out in the code dealing
with syscall lists, update syscall-names.list for the new syscall and
regenerate the arch-syscall.h headers with build-many-glibcs.py
update-syscalls.

Tested with build-many-glibcs.py.

(cherry picked from commit 3387c40a8b)
2022-01-13 13:51:38 +01:00
Paul A. Clarke e64235ff42 powerpc: Fix unrecognized instruction errors with recent GCC
Recent binutils commit b25f942e18d6ecd7ec3e2d2e9930eb4f996c258a
changes the behavior of `.machine` directives to override, rather
than augment, the base CPU. This can result in _reduced_ functionality
when, for example, compiling for default machine "power8", but explicitly
asking for ".machine power5", which loses Altivec instructions.

In tst-ucontext-ppc64-vscr.c, while the instructions provoking the new
error messages are bracketed by ".machine power5", which is ostensibly
Power ISA 2.03 (POWER5), the POWER5 processor did not support the
VSX subset, so these instructions are not recognized as "power5".

Error: unrecognized opcode: `vspltisb'
Error: unrecognized opcode: `vpkuwus'
Error: unrecognized opcode: `mfvscr'
Error: unrecognized opcode: `stvx'

Manually adding the VSX subset via ".machine altivec" is sufficient.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
(cherry picked from commit 064b475a2e)
2022-01-10 22:48:53 +01:00
Hans-Peter Nilsson d5ba02f67d timezone: test-case for BZ #28707
This test-case is the tzfile for Asuncion generated by
tzlib-2021e as follows, using the tzlib-2021e zic: "zic -d
DEST -r @1546300800 -L /dev/null -b slim
SOURCE/southamerica".  Note that in its type 2 header, it
has two entries in its "time-types" array (types), but only
one entry in its "transition types" array (type_idxs).

	* timezone/Makefile, timezone/tst-pr28707.c,
	timezone/testdata/gen-XT5.sh: New test.

Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
(cherry picked from commit ebe899af0d)
2022-01-07 10:21:11 +01:00
Hans-Peter Nilsson 85b24f9694 timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707)
When using a timezone file with a truncated starting time,
generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d
(also in tzlib-2021e; current as of this writing), glibc
asserts in __tzfile_read (on e.g. tzset() for this file) and
you may find lines matching "tzfile.c:435: __tzfile_read:
Assertion `num_types == 1' failed" in your syslog.

One example of such a file is the tzfile for Asuncion
generated by tzlib-2021e as follows, using the tzlib-2021e zic:
"zic -d DEST -r @1546300800 -L /dev/null -b slim
SOURCE/southamerica".  Note that in its type 2 header, it has
two entries in its "time-types" array (types), but only one
entry in its "transition types" array (type_idxs).

This is valid and expected already in the published RFC8536, and
not even frowned upon: "Local time for timestamps before the
first transition is specified by the first time type (time type
0)" ... "every nonzero local time type index SHOULD appear at
least once in the transition type array".  Note the "nonzero ...
index".  Until the 2021d zic, index 0 has been shared by the
first valid transition but with 2021d it's separate, set apart
as a placeholder and only "implicitly" indexed.  (A draft update
of the RFC mandates that the entry at index 0 is a placeholder
in this case, hence can no longer be shared.)

	* time/tzfile.c (__tzfile_read): Don't assert when no transitions
	are found.

Co-authored-by: Christopher Wong <Christopher.Wong@axis.com>
(cherry picked from commit c36f64aa6d)
2022-01-07 10:20:58 +01:00
Paul Eggert 515a6f53cd Fix subscript error with odd TZif file [BZ #28338]
* time/tzfile.c (__tzfile_compute): Fix unlikely off-by-one bug
that accessed before start of an array when an oddball-but-valid
TZif file was queried with an unusual time_t value.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 645277434a)
2022-01-07 10:20:02 +01:00
Wilco Dijkstra 217b84127b AArch64: Check for SVE in ifuncs [BZ #28744]
Add a check for SVE in the A64FX ifuncs for memcpy, memset and memmove.
This fixes BZ #28744.

(cherry picked from commit e5fa62b8db)
2022-01-07 10:10:27 +01:00
Andrea Monaco 41fddc064d intl/plural.y: Avoid conflicting declarations of yyerror and yylex
bison-3.8 includes these lines in the generated intl/plural.c:

  #if !defined __gettexterror && !defined YYERROR_IS_DECLARED
  void __gettexterror (struct parse_args *arg, const char *msg);
  #endif
  #if !defined __gettextlex && !defined YYLEX_IS_DECLARED
  int __gettextlex (YYSTYPE *yylvalp, struct parse_args *arg);
  #endif

Those default prototypes provided by bison conflict with the
declarations later on in plural.y.  This patch solves the issue.

Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit c6d7d6312c)
2021-12-23 13:48:04 +01:00
maminjie 8ad6d6d8ed Linux: Fix 32-bit vDSO for clock_gettime on powerpc32
When the clock_id is CLOCK_PROCESS_CPUTIME_ID or CLOCK_THREAD_CPUTIME_ID,
on the 5.10 kernel powerpc 32-bit, the 32-bit vDSO is executed successfully (
because the __kernel_clock_gettime in arch/powerpc/kernel/vdso32/gettimeofday.S
does not support these two IDs, the 32-bit time_t syscall will be used),
but tp32.tv_sec is equal to 0, causing the 64-bit time_t syscall to continue to be used,
resulting in two system calls.

Fix commit 72e84d1db2.

Signed-off-by: maminjie  <maminjie2@huawei.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

(cherry picked from commit e0fc721ce6)
2021-12-21 09:50:25 -03:00
Adhemerval Zanella 1d9764aba8 linux: Add sparck brk implementation
It turned that the generic implementation of brk() does not work
for sparc, since on failure kernel will just return the previous
input value without setting the conditional register.

This patches adds back a sparc32 and sparc64 implementation removed
by 720480934a.

Checked on sparc64-linux-gnu and sparcv9-linux-gnu.

(cherry picked from commit 5b86241a03)
2021-12-19 22:56:33 +01:00
Adhemerval Zanella e94544c82f Update sparc libm-test-ulps
(cherry picked from commit c52eb066bc)
2021-12-18 23:45:53 +01:00
John David Anglin 4029747c59 Update hppa libm-test-ulps
(cherry picked from commit d8cf84ac7e)
2021-12-17 23:51:39 +01:00
Aurelien Jarno aa3a97496c riscv: align stack before calling _dl_init [BZ #28703]
Align the stack pointer to 128 bits during the call to _dl_init() as
specified by the RISC-V ABI [1]. This fixes the elf/tst-align2 test.

Fixes bug 28703.

[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc

(cherry picked from commit 225da459ce)
2021-12-17 22:50:13 +01:00
Aurelien Jarno 9de8011c32 riscv: align stack in clone [BZ #28702]
The RISC-V ABI [1] mandates that "the stack pointer shall be aligned to
a 128-bit boundary upon procedure entry". This as not the case in clone.

This fixes the misc/tst-misalign-clone-internal and
misc/tst-misalign-clone tests.

Fixes bug 28702.

[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc

(cherry picked from commit d2e594d715)
2021-12-17 22:48:41 +01:00
Matheus Castanho 5daf13b1e6 powerpc64[le]: Allocate extra stack frame on syscall.S
The syscall function does not allocate the extra stack frame for scv like other
assembly syscalls using DO_CALL_SCV. So after commit d120fb9941 changed the
offset that is used to save LR, syscall ended up using an invalid offset,
causing regressions on powerpc64. So make sure the extra stack frame is
allocated in syscall.S as well to make it consistent with other uses of
DO_CALL_SCV and avoid similar issues in the future.

Tested on powerpc, powerpc64, and powerpc64le (with and without scv)

Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>

(cherry picked from commit ae91d3df24)
2021-12-17 17:19:22 -03:00
Aurelien Jarno 03de6917bd elf: Fix tst-cpu-features-cpuinfo for KVM guests on some AMD systems [BZ #28704]
On KVM guests running on some AMD systems, the IBRS feature is reported
as a synthetic feature using the Intel feature, while the cpuinfo entry
keeps the same. Handle that by first checking the presence of the Intel
feature on AMD systems.

Fixes bug 28704.

(cherry picked from commit 94058f6cde)
2021-12-17 20:35:45 +01:00
Florian Weimer dc9b69d533 nss: Use "files dns" as the default for the hosts database (bug 28700)
This matches what is currently in nss/nsswitch.conf.  The new ordering
matches what most distributions use in their installed configuration
files.

It is common to add localhost to /etc/hosts because the name does not
exist in the DNS, but is commonly used as a host name.

With the built-in "dns [!UNAVAIL=return] files" default, dns is
searched first and provides an answer for "localhost" (NXDOMAIN).
We never look at the files database as a result, so the contents of
/etc/hosts is ignored.  This means that "getent hosts localhost"
fail without a /etc/nsswitch.conf file, even though the host name
is listed in /etc/hosts.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit b99b0f93ee)
2021-12-17 12:17:18 +01:00
Florian Weimer 93aabf891e arm: Guard ucontext _rtld_global_ro access by SHARED, not PIC macro
Due to PIE-by-default, PIC is now defined in more cases.  libc.a
does not have _rtld_global_ro, and statically linking setcontext
fails.  SHARED is the right condition to use, so that libc.a
references _dl_hwcap instead of _rtld_global_ro.

For static PIE support, the !SHARED case would still have to be made
PIC.  This patch does not achieve that.

Fixes commit 23645707f1
("Replace --enable-static-pie with --disable-default-pie").

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit ce1e5b1122)
2021-12-17 12:16:13 +01:00
Xi Ruoyao 4db172a54d mips: increase stack alignment in clone to match the ABI
In "mips: align stack in clone [BZ #28223]"
(commit 1f51cd9a86) I made a mistake: I
misbelieved one "word" was 2-byte and "doubleword" should be 4-byte.
But in MIPS ABI one "word" is defined 32-bit (4-byte), so "doubleword" is
8-byte [1], and "quadword" is 16-byte [2].

[1]: "System V Application Binary Interface: MIPS(R) RISC Processor
      Supplement, 3rd edition", page 3-31
[2]: "MIPSpro(TM) 64-Bit Porting and Transition Guide", page 23

(cherry picked from commit 0f62fe0532)
2021-12-14 22:57:43 +01:00
Xi Ruoyao 7af07fe795 mips: align stack in clone [BZ #28223]
The MIPS O32 ABI requires 4 byte aligned stack, and the MIPS N64 and N32
ABI require 8 byte aligned stack.  Previously if the caller passed an
unaligned stack to clone the the child misbehaved.

Fixes bug 28223.

(cherry picked from commit 1f51cd9a86)
2021-12-14 22:57:39 +01:00
Stafford Horne 0686586515 pthread/tst-cancel28: Fix barrier re-init race condition
When running this test on the OpenRISC port I am working on this test
fails with a timeout.  The test passes when being straced or debugged.
Looking at the code there seems to be a race condition in that:

  1 main thread: calls xpthread_cancel
  2 sub thread : receives cancel signal
  3 sub thread : cleanup routine waits on barrier
  4 main thread: re-inits barrier
  5 main thread: waits on barrier

After getting to 5 the main thread and sub thread wait forever as the 2
barriers are no longer the same.

Removing the barrier re-init seems to fix this issue.  Also, the barrier
does not need to be reinitialized as that is done by default.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 9874ca536b)
2021-12-14 10:07:27 +05:30
Joseph Myers 1fe4b8d693 Use $(pie-default) with conformtest
My glibc bot showed that my conformtest changes fail the build of the
conformtest execution tests for x86_64-linux-gnu-static-pie, because
linking the newly built object with the newly built libc and the
associated options normally used for linking requires it to be built
as PIE.  Add $(pie-default) to the compiler command used so that PIE
options are used when required.

There's a case for using the whole of $(CFLAGS-.o) (which includes
$(pie-default)), but that raises questions of any impact from using
optimization flags from CFLAGS in these tests.  So for now just use
$(pie-default) as the key part of $(CFLAGS-.o) that's definitely
needed.

Tested with build-many-glibcs.py for x86_64-linux-gnu-static-pie.

(cherry picked from commit 885762aa31)
2021-12-13 20:59:48 +05:30
Joseph Myers 0dcbf4c870 Run conform/ tests using newly built libc
Although the conform/ header tests are built using the headers of the
glibc under test, the execution tests from conformtest (a few tests of
the values of macros evaluating to string constants) are linked and
run with system libc, not the newly built libc.

Apart from preventing testing in cross environments, this can be a
problem even for native testing.  Specifically, it can be useful to do
native testing when building with a cross compiler that links with a
libc that is not the system libc; for example, on x86_64, you can test
all three ABIs that way if the kernel support is present, even if the
host OS lacks 32-bit or x32 libraries or they are older than the
libraries in the sysroot used by the compiler used to build glibc.
This works for almost all tests, but not for these conformtest tests.

Arrange for conformtest to link and run test programs similarly to
other tests, with consequent refactoring of various variables in
Makeconfig to allow passing relevant parts of the link-time command
lines down to conformtest.  In general, the parts of the link command
involving $@ or $^ are separated out from the parts that should be
passed to conformtest (the variables passed to conformtest still
involve various variables whose names involve $(@F), but those
variables simply won't be defined for the conformtest makefile rules
and I think their presence there is harmless).

This is also most of the support that would be needed to allow running
those tests of string constants for cross testing when test-wrapper is
defined.  That will also need changes to where conformtest.py puts the
test executables, so it puts them in the main object directory
(expected to be shared with a test system in cross testing) rather
than /tmp (not expected to be shared) as at present.

Tested for x86_64.

(cherry picked from commit f3eef96390)
2021-12-13 09:07:38 +05:30
Florian Weimer e9f81c261a nptl: Add one more barrier to nptl/tst-create1
Without the bar_ctor_finish barrier, it was possible that thread2
re-locked user_lock before ctor had a chance to lock it.  ctor then
blocked in its locking operation, xdlopen from the main thread
did not return, and thread2 was stuck waiting in bar_dtor:

thread 1: started.
thread 2: started.
thread 2: locked user_lock.
constructor started: 0.
thread 1: in ctor: started.
thread 3: started.
thread 3: done.
thread 2: unlocked user_lock.
thread 2: locked user_lock.

Fixes the test in commit 83b5323261
("elf: Avoid deadlock between pthread_create and ctors [BZ #28357]").

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit 5cc3385654)
2021-12-10 11:56:06 +01:00
Matheus Castanho 387bff63dc powerpc64[le]: Fix CFI and LR save address for asm syscalls [BZ #28532]
Syscalls based on the assembly templates are missing CFI for r31, which gets
clobbered when scv is used, and info for LR is inaccurate, placed in the wrong
LOC and not using the proper offset. LR was also being saved to the callee's
frame, while the ABI mandates it to be saved to the caller's frame. These are
fixed by this commit.

After this change:

$ readelf -wF libc.so.6 | grep 0004b9d4.. -A 7 && objdump --disassemble=kill libc.so.6
00004a48 0000000000000020 00004a4c FDE cie=00000000 pc=000000000004b9d4..000000000004ba3c
   LOC           CFA      r31   ra
000000000004b9d4 r1+0     u     u
000000000004b9e4 r1+48    u     u
000000000004b9e8 r1+48    c-16  u
000000000004b9fc r1+48    c-16  c+16
000000000004ba08 r1+48    c-16
000000000004ba18 r1+48    u
000000000004ba1c r1+0     u

libc.so.6:     file format elf64-powerpcle

Disassembly of section .text:

000000000004b9d4 <kill>:
   4b9d4:       1f 00 4c 3c     addis   r2,r12,31
   4b9d8:       2c c3 42 38     addi    r2,r2,-15572
   4b9dc:       25 00 00 38     li      r0,37
   4b9e0:       d1 ff 21 f8     stdu    r1,-48(r1)
   4b9e4:       20 00 e1 fb     std     r31,32(r1)
   4b9e8:       98 8f ed eb     ld      r31,-28776(r13)
   4b9ec:       10 00 ff 77     andis.  r31,r31,16
   4b9f0:       1c 00 82 41     beq     4ba0c <kill+0x38>
   4b9f4:       a6 02 28 7d     mflr    r9
   4b9f8:       40 00 21 f9     std     r9,64(r1)
   4b9fc:       01 00 00 44     scv     0
   4ba00:       40 00 21 e9     ld      r9,64(r1)
   4ba04:       a6 03 28 7d     mtlr    r9
   4ba08:       08 00 00 48     b       4ba10 <kill+0x3c>
   4ba0c:       02 00 00 44     sc
   4ba10:       00 00 bf 2e     cmpdi   cr5,r31,0
   4ba14:       20 00 e1 eb     ld      r31,32(r1)
   4ba18:       30 00 21 38     addi    r1,r1,48
   4ba1c:       18 00 96 41     beq     cr5,4ba34 <kill+0x60>
   4ba20:       01 f0 20 39     li      r9,-4095
   4ba24:       40 48 23 7c     cmpld   r3,r9
   4ba28:       20 00 e0 4d     bltlr+
   4ba2c:       d0 00 63 7c     neg     r3,r3
   4ba30:       08 00 00 48     b       4ba38 <kill+0x64>
   4ba34:       20 00 e3 4c     bnslr+
   4ba38:       c8 32 fe 4b     b       2ed00 <__syscall_error>
        ...
   4ba44:       40 20 0c 00     .long 0xc2040
   4ba48:       68 00 00 00     .long 0x68
   4ba4c:       06 00 5f 5f     rlwnm   r31,r26,r0,0,3
   4ba50:       6b 69 6c 6c     xoris   r12,r3,26987

(cherry picked from commit d120fb9941)
2021-11-30 15:34:03 -03:00
Adhemerval Zanella f988b7f228 linux: Use /proc/stat fallback for __get_nprocs_conf (BZ #28624)
The /proc/statm fallback was removed by f13fb81ad3 if sysfs is
not available, reinstate it.

Checked on x86_64-linux-gnu.
(cherry-picked from commit 137ed5ac44)
2021-11-25 14:02:51 -03:00
Florian Weimer bfe68fe3c4 nptl: Do not set signal mask on second setjmp return [BZ #28607]
__libc_signal_restore_set was in the wrong place: It also ran
when setjmp returned the second time (after pthread_exit or
pthread_cancel).  This is observable with blocked pending
signals during thread exit.

Fixes commit b3cae39dcb
("nptl: Start new threads with all signals blocked [BZ #25098]").

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit e186fc5a31)
2021-11-24 09:22:10 +01:00
Florian Weimer a4f3bc2346 s390: Use long branches across object boundaries (jgh instead of jh)
Depending on the layout chosen by the linker, the 16-bit displacement
of the jh instruction is insufficient to reach the target label.

Analysis of the linker failure was carried out by Nick Clifton.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Stefan Liebler <stli@linux.ibm.com>
(cherry picked from commit 98966749f2)
2021-11-10 15:22:24 +01:00
Florian Weimer cf8c6a634c elf: Earlier missing dynamic segment check in _dl_map_object_from_fd
Separated debuginfo files have PT_DYNAMIC with p_filesz == 0.  We
need to check for that before the _dl_map_segments call because
that could attempt to write to mappings that extend beyond the end
of the file, resulting in SIGBUS.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit ea32ec354c)
2021-11-05 19:36:06 +01:00
Nikita Popov f411207a83 gconv: Do not emit spurious NUL character in ISO-2022-JP-3 (bug 28524)
Bugfix 27256 has introduced another issue:
In conversion from ISO-2022-JP-3 encoding, it is possible
to force iconv to emit extra NUL character on internal state reset.
To do this, it is sufficient to feed iconv with escape sequence
which switches active character set.
The simplified check 'data->__statep->__count != ASCII_set'
introduced by the aforementioned bugfix picks that case and
behaves as if '\0' character has been queued thus emitting it.

To eliminate this issue, these steps are taken:
* Restore original condition
'(data->__statep->__count & ~7) != ASCII_set'.
It is necessary since bits 0-2 may contain
number of buffered input characters.
* Check that queued character is not NUL.
Similar step is taken for main conversion loop.

Bundled test case follows following logic:
* Try to convert ISO-2022-JP-3 escape sequence
switching active character set
* Reset internal state by providing NULL as input buffer
* Ensure that nothing has been converted.

Signed-off-by: Nikita Popov <npv1310@gmail.com>
(cherry picked from commit ff012870b2)
2021-11-04 21:28:43 +01:00
H.J. Lu 6548a9bdba Avoid warning: overriding recipe for .../tst-ro-dynamic-mod.so
Add tst-ro-dynamic-mod to modules-names-nobuild to avoid

../Makerules:767: warning: ignoring old recipe for target '.../elf/tst-ro-dynamic-mod.so'

This updates BZ #28340 fix.

(cherry picked from commit 15e6d6785a)
2021-11-03 10:21:04 +01:00
H.J. Lu 5f36e5c701 ld.so: Initialize bootstrap_map.l_ld_readonly [BZ #28340]
1. Define DL_RO_DYN_SECTION to initalize bootstrap_map.l_ld_readonly
before calling elf_get_dynamic_info to get dynamic info in bootstrap_map,
2. Define a single

static inline bool
dl_relocate_ld (const struct link_map *l)
{
  /* Don't relocate dynamic section if it is readonly  */
  return !(l->l_ld_readonly || DL_RO_DYN_SECTION);
}

This updates BZ #28340 fix.

(cherry picked from commit 2ec99d8c42)
2021-11-03 07:53:12 +01:00
H.J. Lu f42373f911 ld.so: Replace DL_RO_DYN_SECTION with dl_relocate_ld [BZ #28340]
We can't relocate entries in dynamic section if it is readonly:

1. Add a l_ld_readonly field to struct link_map to indicate if dynamic
section is readonly and set it based on p_flags of PT_DYNAMIC segment.
2. Replace DL_RO_DYN_SECTION with dl_relocate_ld to decide if dynamic
section should be relocated.
3. Remove DL_RO_DYN_TEMP_CNT.
4. Don't use a static dynamic section to make readonly dynamic section
in vDSO writable.
5. Remove the temp argument from elf_get_dynamic_info.

This fixes BZ #28340.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit b413280cfb)
2021-11-03 07:50:30 +01:00
Siddhesh Poyarekar 01bffc013c Handle NULL input to malloc_usable_size [BZ #28506]
Hoist the NULL check for malloc_usable_size into its entry points in
malloc-debug and malloc and assume non-NULL in all callees.  This fixes
BZ #28506

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
(cherry picked from commit 88e316b064)
2021-10-29 14:56:53 +05:30
Szabolcs Nagy 024a7640ab elf: Avoid deadlock between pthread_create and ctors [BZ #28357]
The fix for bug 19329 caused a regression such that pthread_create can
deadlock when concurrent ctors from dlopen are waiting for it to finish.
Use a new GL(dl_load_tls_lock) in pthread_create that is not taken
around ctors in dlopen.

The new lock is also used in __tls_get_addr instead of GL(dl_load_lock).

The new lock is held in _dl_open_worker and _dl_close_worker around
most of the logic before/after the init/fini routines.  When init/fini
routines are running then TLS is in a consistent, usable state.
In _dl_open_worker the new lock requires catching and reraising dlopen
failures that happen in the critical section.

The new lock is reinitialized in a fork child, to keep the existing
behaviour and it is kept recursive in case malloc interposition or TLS
access from signal handlers can retake it.  It is not obvious if this
is necessary or helps, but avoids changing the preexisting behaviour.

The new lock may be more appropriate for dl_iterate_phdr too than
GL(dl_load_write_lock), since TLS state of an incompletely loaded
module may be accessed.  If the new lock can replace the old one,
that can be a separate change.

Fixes bug 28357.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 83b5323261)
2021-10-19 14:21:14 +02:00
Stafford Horne cb9b8b5d76 timex: Use 64-bit fields on 32-bit TIMESIZE=64 systems (BZ #28469)
This was found when testing the OpenRISC port I am working on.  These
two tests fail with SIGSEGV:

  FAIL: misc/tst-ntp_gettime
  FAIL: misc/tst-ntp_gettimex

This was found to be due to the kernel overwriting the stack space
allocated by the timex structure.  The reason for the overwrite being
that the kernel timex has 64-bit fields and user space code only
allocates enough stack space for timex with 32-bit fields.

On 32-bit systems with TIMESIZE=64 __USE_TIME_BITS64 is not defined.
This causes the timex structure to use 32-bit fields with type
__syscall_slong_t.

This patch adjusts the ifdef condition to allow 32-bit systems with
TIMESIZE=64 to use the 64-bit long long timex definition.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

(Cherry picked from commit 1d550265a7)
2021-10-18 17:45:42 -03:00
Adhemerval Zanella 76843f3b3e y2038: Use a common definition for stat for sparc32
The sparc32 misses support for support done by 4e8521333b.

Checked on sparcv9-linux-gnu.

(cherry picked from commit d2b1254db2)
2021-10-18 17:44:16 -03:00
H.J. Lu 79528414dc elf: Replace nsid with args.nsid [BZ #27609]
commit ec935dea63
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Apr 24 22:31:15 2020 +0200

    elf: Implement __libc_early_init

has

@@ -856,6 +876,11 @@ no more namespaces available for dlmopen()"));
   /* See if an error occurred during loading.  */
   if (__glibc_unlikely (exception.errstring != NULL))
     {
+      /* 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)[nsid].libc_map = NULL;
+

do_dlopen calls _dl_open with nsid == __LM_ID_CALLER (-2), which calls
dl_open_worker with args.nsid = nsid.  dl_open_worker updates args.nsid
if it is __LM_ID_CALLER.  After dl_open_worker returns, it is wrong to
use nsid.

Replace nsid with args.nsid after dl_open_worker returns.  This fixes
BZ #27609.

(cherry picked from commit 1e1ecea62e)
2021-10-13 05:03:44 -07:00
Stefan Liebler cb44a620ef S390: Add PCI_MIO and SIE HWCAPs
Both new HWCAPs were introduced in these kernel commits:
- 7e8403ecaf884f307b627f3c371475913dd29292
  "s390: add HWCAP_S390_PCI_MIO to ELF hwcaps"
- 7e82523f2583e9813e4109df3656707162541297
  "s390/hwcaps: make sie capability regular hwcap"

Also note that the kernel commit 511ad531afd4090625def4d9aba1f5227bd44b8e
"s390/hwcaps: shorten HWCAP defines" has shortened the prefix of the macros
from "HWCAP_S390_" to "HWCAP_".  For compatibility reasons, we do not
change the prefix in public glibc header file.

(cherry picked from commit f2e06656d0)
2021-10-07 06:59:31 +02:00
Siddhesh Poyarekar 558168c78e support: Also return fd when it is 0
The fd validity check in open_dev_null checks if fd > 0, which would
lead to a leaked fd if it is == 0.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 27b6edbb09)
2021-10-06 22:26:05 +05:30
Florian Weimer a996d13b8a Add missing braces to bsearch inline implementation [BZ #28400]
GCC treats the pragma as a statement, so that the else branch only
consists of the pragma, not the return statement.

Fixes commit a725ff1de9 ("Suppress
-Wcast-qual warnings in bsearch").

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit 32b96d0dec)
2021-10-01 18:20:12 +02:00
Jonathan Wakely 80a009119b Suppress -Wcast-qual warnings in bsearch
The first cast to (void *) is redundant but should be (const void *)
anyway, because that's the type of the lvalue being assigned to.

The second cast is necessary and intentionally not const-correct, so
tell the compiler not to warn about it.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit a725ff1de9)
2021-10-01 18:20:12 +02:00
Adhemerval Zanella 822662cf2a linux: Revert the use of sched_getaffinity on get_nproc (BZ #28310)
The use of sched_getaffinity on get_nproc and
sysconf (_SC_NPROCESSORS_ONLN) done in 903bc7dcc2 (BZ #27645)
breaks the top command in common hypervisor configurations and also
other monitoring tools.

The main issue using sched_getaffinity changed the symbols semantic
from system-wide scope of online CPUs to per-process one (which can
be changed with kernel cpusets or book parameters in VM).

This patch reverts mostly of the 903bc7dcc2, with the
exceptions:

  * No more cached values and atomic updates, since they are inherent
    racy.

  * No /proc/cpuinfo fallback, since /proc/stat is already used and
    it would require to revert more arch-specific code.

  * The alloca is replace with a static buffer of 1024 bytes.

So the implementation first consult the sysfs, and fallbacks to procfs.

Checked on x86_64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 342298278e)
2021-10-01 18:19:45 +02:00
Adhemerval Zanella cda99af14e linux: Simplify get_nprocs
This patch simplifies the memory allocation code and uses the sched
routines instead of reimplement it.  This still uses a stack
allocation buffer, so it can be used on malloc initialization code.

Linux currently supports at maximum of 4096 cpus for most architectures:

$ find -iname Kconfig | xargs git grep -A10 -w NR_CPUS | grep -w range
arch/alpha/Kconfig-	range 2 32
arch/arc/Kconfig-	range 2 4096
arch/arm/Kconfig-	range 2 16 if DEBUG_KMAP_LOCAL
arch/arm/Kconfig-	range 2 32 if !DEBUG_KMAP_LOCAL
arch/arm64/Kconfig-	range 2 4096
arch/csky/Kconfig-	range 2 32
arch/hexagon/Kconfig-	range 2 6 if SMP
arch/ia64/Kconfig-	range 2 4096
arch/mips/Kconfig-	range 2 256
arch/openrisc/Kconfig-	range 2 32
arch/parisc/Kconfig-	range 2 32
arch/riscv/Kconfig-	range 2 32
arch/s390/Kconfig-	range 2 512
arch/sh/Kconfig-	range 2 32
arch/sparc/Kconfig-	range 2 32 if SPARC32
arch/sparc/Kconfig-	range 2 4096 if SPARC64
arch/um/Kconfig-	range 1 1
arch/x86/Kconfig-# [NR_CPUS_RANGE_BEGIN ... NR_CPUS_RANGE_END] range.
arch/x86/Kconfig-	range NR_CPUS_RANGE_BEGIN NR_CPUS_RANGE_END
arch/xtensa/Kconfig-	range 2 32

With x86 supporting 8192:

arch/x86/Kconfig
 976 config NR_CPUS_RANGE_END
 977         int
 978         depends on X86_64
 979         default 8192 if  SMP && CPUMASK_OFFSTACK
 980         default  512 if  SMP && !CPUMASK_OFFSTACK
 981         default    1 if !SMP

So using a maximum of 32k cpu should cover all cases (and I would
expect once we start to have many more CPUs that Linux would provide
a more straightforward way to query for such information).

A test is added to check if sched_getaffinity can successfully return
with large buffers.

Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 33099d72e4)
2021-10-01 18:19:10 +02:00
Adhemerval Zanella e870aac897 misc: Add __get_nprocs_sched
This is an internal function meant to return the number of avaliable
processor where the process can scheduled, different than the
__get_nprocs which returns a the system available online CPU.

The Linux implementation currently only calls __get_nprocs(), which
in tuns calls sched_getaffinity.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 11a02b035b)
2021-10-01 18:19:09 +02:00
Florian Weimer 40bade26d5 nptl: pthread_kill must send signals to a specific thread [BZ #28407]
The choice between the kill vs tgkill system calls is not just about
the TID reuse race, but also about whether the signal is sent to the
whole process (and any thread in it) or to a specific thread.

This was caught by the openposix test suite:

  LTP: openposix test suite - FAIL: SIGUSR1 is member of new thread pendingset.
  <https://gitlab.com/cki-project/kernel-tests/-/issues/764>

Fixes commit 526c3cf11e ("nptl: Fix race
between pthread_kill and thread exit (bug 12889)").

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit eae81d7057)
2021-10-01 18:18:15 +02:00
Florian Weimer 4bf7251998 support: Add check for TID zero in support_wait_for_thread_exit
Some kernel versions (observed with kernel 5.14 and earlier) can list
"0" entries in /proc/self/task.  This happens when a thread exits
while the task list is being constructed.  Treat this entry as not
present, like the proposed kernel patch does:

[PATCH] procfs: Do not list TID 0 in /proc/<pid>/task
<https://lore.kernel.org/all/8735pn5dx7.fsf@oldenburg.str.redhat.com/>

Fixes commit 032d74eaf6 ("support: Add
support_wait_for_thread_exit").

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 176c88f521)
2021-10-01 18:17:19 +02:00
Florian Weimer 33adeaa3e2 nptl: Avoid setxid deadlock with blocked signals in thread exit [BZ #28361]
As part of the fix for bug 12889, signals are blocked during
thread exit, so that application code cannot run on the thread that
is about to exit.  This would cause problems if the application
expected signals to be delivered after the signal handler revealed
the thread to still exist, despite pthread_kill can no longer be used
to send signals to it.  However, glibc internally uses the SIGSETXID
signal in a way that is incompatible with signal blocking, due to the
way the setxid handshake delays thread exit until the setxid operation
has completed.  With a blocked SIGSETXID, the handshake can never
complete, causing a deadlock.

As a band-aid, restore the previous handshake protocol by not blocking
SIGSETXID during thread exit.

The new test sysdeps/pthread/tst-pthread-setuid-loop.c is based on
a downstream test by Martin Osvald.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 2849e2f533)
2021-09-23 11:02:19 +02:00
Adhemerval Zanella 772e33411b Use support_open_dev_null_range io/tst-closefrom, misc/tst-close_range, and posix/tst-spawn5 (BZ #28260)
It ensures a continuous range of file descriptor and avoid hitting
the RLIMIT_NOFILE.

Checked on x86_64-linux-gnu.

(cherry picked from commit 6b20880b22)
2021-09-21 22:26:26 +12:00
Adhemerval Zanella 5ad589d63b support: Add support_open_dev_null_range
It returns a range of file descriptor referring to the '/dev/null'
pathname.  The function takes care of restarting the open range
if a file descriptor is found within the specified range and
also increases RLIMIT_NOFILE if required.

Checked on x86_64-linux-gnu.

(cherry picked from commit e814f4b04e)
2021-09-21 22:26:26 +12:00
Florian Weimer 8b8a1d0b73 nptl: Fix type of pthread_mutexattr_getrobust_np, pthread_mutexattr_setrobust_np (bug 28036)
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit f3e6645633)
2021-09-21 07:15:25 +02:00
Florian Weimer 73c7f5a879 nptl: pthread_kill needs to return ESRCH for old programs (bug 19193)
The fix for bug 19193 breaks some old applications which appear
to use pthread_kill to probe if a thread is still running, something
that is not supported by POSIX.

(cherry picked from commit 95dba35bf0)
2021-09-20 14:58:57 +02:00
Aurelien Jarno 433ec4f14a posix: Fix attribute access mode on getcwd [BZ #27476]
There is a GNU extension that allows to call getcwd(NULL, >0). It is
described in the documentation, but also directly in the unistd.h
header, just above the declaration.

Therefore the attribute access mode added in commit 06febd8c67
is not correct. Drop it.
2021-09-19 18:45:38 +02:00
Joseph Myers 4ed990e5b9 Add MADV_POPULATE_READ and MADV_POPULATE_WRITE from Linux 5.14 to bits/mman-linux.h
Linux 5.14 adds constants MADV_POPULATE_READ and MADV_POPULATE_WRITE
(with the same values on all architectures).  Add these to glibc's
bits/mman-linux.h.

Tested for x86_64.

(cherry picked from commit 3561106278)
2021-09-15 14:34:33 +02:00
Joseph Myers 114581bf53 Update kernel version to 5.14 in tst-mman-consts.py
This patch updates the kernel version in the test tst-mman-consts.py
to 5.14.  (There are no new MAP_* constants covered by this test in
5.14 that need any other header changes.)

Tested with build-many-glibcs.py.

(cherry picked from commit 4b39e34983)
2021-09-15 14:34:33 +02:00
Joseph Myers 005bafcf5b Update syscall lists for Linux 5.14
Linux 5.14 has two new syscalls, memfd_secret (on some architectures
only) and quotactl_fd.  Update syscall-names.list and regenerate the
arch-syscall.h headers with build-many-glibcs.py update-syscalls.

Tested with build-many-glibcs.py.

(cherry picked from commit 89dc0372a9)
2021-09-15 14:34:33 +02:00
Joseph Myers 007d699d0e Use Linux 5.14 in build-many-glibcs.py
This patch makes build-many-glibcs.py use Linux 5.14.

Tested with build-many-glibcs.py (host-libraries, compilers and glibcs
builds).

(cherry picked from commit 4e04a47208)
2021-09-15 14:34:33 +02:00
Aurelien Jarno ae925404a1 Fix failing nss/tst-nss-files-hosts-long with local resolver
When a local resolver like unbound is listening on the IPv4 loopback
address 127.0.0.1, the nss/tst-nss-files-hosts-long test fails. This is
due to:
- the default resolver in the absence of resolv.conf being 127.0.0.1
- the default DNS NSS database configuration in the absence of
  nsswitch.conf being 'hosts: dns [!UNAVAIL=return] file'

This causes the requests for 'test4' and 'test6' to first be sent to the
local resolver, which responds with NXDOMAIN in the likely case those
records do no exist. In turn that causes the access to /etc/hosts to be
skipped, which is the purpose of that test.

Fix that by providing a simple nsswitch.conf file forcing access to
/etc/hosts for that test. I have tested that the only changed result in
the testsuite is that test.

(cherry picked from commit 2738480a4b)
2021-09-14 21:02:14 +02:00
Siddhesh Poyarekar 3fc51f35b4 iconvconfig: Fix behaviour with --prefix [BZ #28199]
The consolidation of configuration parsing broke behaviour with
--prefix, where the prefix bled into the modules cache.  Accept a
prefix which, when non-NULL, is prepended to the path when looking for
configuration files but only the original directory is added to the
modules cache.

This has no effect on the codegen of gconv_conf since it passes NULL.

Reported-by: Patrick McCarty <patrick.mccarty@intel.com>
Reported-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
(cherry picked from commit 43cea6d565)
2021-09-13 20:51:04 +05:30
Florian Weimer a8ac8c4725 nptl: Fix race between pthread_kill and thread exit (bug 12889)
A new thread exit lock and flag are introduced.  They are used to
detect that the thread is about to exit or has exited in
__pthread_kill_internal, and the signal is not sent in this case.

The test sysdeps/pthread/tst-pthread_cancel-select-loop.c is derived
from a downstream test originally written by Marek Polacek.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 526c3cf11e)
2021-09-13 13:38:51 +02:00
Florian Weimer 3abf3bd4ed nptl: pthread_kill, pthread_cancel should not fail after exit (bug 19193)
This closes one remaining race condition related to bug 12889: if
the thread already exited on the kernel side, returning ESRCH
is not correct because that error is reserved for the thread IDs
(pthread_t values) whose lifetime has ended.  In case of a
kernel-side exit and a valid thread ID, no signal needs to be sent
and cancellation does not have an effect, so just return 0.

sysdeps/pthread/tst-kill4.c triggers undefined behavior and is
removed with this commit.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 8af8456004)
2021-09-13 13:38:51 +02:00
Florian Weimer addc9d62d6 support: Add support_wait_for_thread_exit
(cherry picked from commit 032d74eaf6)
2021-09-13 13:38:51 +02:00
Jiaxun Yang 52d0119743 MIPS: Setup errno for {f,l,}xstat
{f,l,}xstat stub for MIPS is using INTERNAL_SYSCALL
to do xstat syscall for glibc ver, However it leaves
errno untouched and thus giving bad errno output.

Setup errno properly when syscall returns non-zero.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

(cherry picked from commit 66016ec8ae)
2021-09-07 10:56:33 -03:00
H.J. Lu f2413f2710 x86-64: Use testl to check __x86_string_control
Use testl, instead of andl, to check __x86_string_control to avoid
updating __x86_string_control.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 3c8b9879ca)
2021-08-31 08:09:25 -07:00
Arjun Shankar 9acab0bba6 elf: Fix missing colon in LD_SHOW_AUXV output [BZ #28253]
This commit adds a missing colon in the AT_MINSIGSTKSZ entry in
the _dl_show_auxv function.

(cherry picked from commit 82fbcd7118)
2021-08-20 16:34:29 +02:00
Nikita Popov 7c987a5ccb librt: add test (bug 28213)
This test implements following logic:
1) Create POSIX message queue.
   Register a notification with mq_notify (using NULL attributes).
   Then immediately unregister the notification with mq_notify.
   Helper thread in a vulnerable version of glibc
   should cause NULL pointer dereference after these steps.
2) Once again, register the same notification.
   Try to send a dummy message.
   Test is considered successfulif the dummy message
   is successfully received by the callback function.

Signed-off-by: Nikita Popov <npv1310@gmail.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 4cc79c2177)
2021-08-16 11:35:35 +05:30
Nikita Popov 7947430322 librt: fix NULL pointer dereference (bug 28213)
Helper thread frees copied attribute on NOTIFY_REMOVED message
received from the OS kernel.  Unfortunately, it fails to check whether
copied attribute actually exists (data.attr != NULL).  This worked
earlier because free() checks passed pointer before actually
attempting to release corresponding memory.  But
__pthread_attr_destroy assumes pointer is not NULL.

So passing NULL pointer to __pthread_attr_destroy will result in
segmentation fault.  This scenario is possible if
notification->sigev_notify_attributes == NULL (which means default
thread attributes should be used).

Signed-off-by: Nikita Popov <npv1310@gmail.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit b805aebd42)
2021-08-09 20:21:04 +05:30
Florian Weimer 31902ae639 Linux: Fix fcntl, ioctl, prctl redirects for _TIME_BITS=64 (bug 28182)
__REDIRECT and __THROW are not compatible with C++ due to the ordering of the
__asm__ alias and the throw specifier. __REDIRECT_NTH has to be used
instead.

Fixes commit 8a40aff86b ("io: Add time64 alias
for fcntl"), commit 82c395d91e ("misc: Add
time64 alias for ioctl"), commit b39ffab860
("Linux: Add time64 alias for prctl").

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit c87fcacc50)
2021-08-06 16:42:40 +02:00
Siddhesh Poyarekar 9995d0588f iconv_charmap: Close output file when done
Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit 1e0e6d656d)
2021-08-04 15:53:46 +05:30
Siddhesh Poyarekar 7ff4da3dc2 copy_and_spawn_sgid: Avoid double calls to close()
If close() on infd and outfd succeeded, reset the fd numbers so that
we don't attempt to close them again.

Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit 45caed9d67)
2021-08-04 15:53:46 +05:30
Siddhesh Poyarekar a5bd2e10e0 gaiconf_init: Avoid double-free in label and precedence lists
labellist and precedencelist could get freed a second time if there
are allocation failures, so set them to NULL to avoid a double-free.

Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit 77a34079d8)
2021-08-04 15:53:46 +05:30
Siddhesh Poyarekar 3a48da47a9 gconv_parseconfdir: Fix memory leak
The allocated `conf` would leak if we have to skip over the file due
to the underlying filesystem not supporting dt_type.

Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit 5f9b78fe35)
2021-08-04 15:51:21 +05:30
Siddhesh Poyarekar 0b03996304 ldconfig: avoid leak on empty paths in config file
Reviewed-by: Arjun Shankar <arjun@redhat.com>
(cherry picked from commit b0234d79e7)
2021-08-04 15:50:50 +05:30
397 changed files with 10740 additions and 3077 deletions
+16 -7
View File
@@ -412,12 +412,13 @@ link-extra-libs-tests = $(libsupport)
# Command for linking PIE programs with the C library.
ifndef +link-pie
+link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
-Wl,-O1 -nostdlib -nostartfiles -o $@ \
+link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
-Wl,-O1 -nostdlib -nostartfiles \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)S$(start-installed-name)) \
$(+preinit) $(+prectorS) \
$(+preinit) $(+prectorS)
+link-pie-before-libc = -o $@ $(+link-pie-before-inputs) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
S$(start-installed-name))\
$(+preinit) $(link-extra-libs) \
@@ -442,11 +443,12 @@ endef
endif
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \
+link-static-before-inputs = -nostdlib -nostartfiles -static \
$(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) \
$(+preinit) $(+prectorT)
+link-static-before-libc = -o $@ $(+link-static-before-inputs) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
$(+preinit) $(link-extra-libs-static) \
@@ -473,13 +475,16 @@ 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-libc = -nostdlib -nostartfiles -o $@ \
+link-before-inputs = -nostdlib -nostartfiles \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \
$(+preinit) $(+prector) \
$(+preinit) $(+prector)
+link-before-libc = -o $@ $(+link-before-inputs) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
$(+preinit) $(link-extra-libs) \
@@ -491,6 +496,8 @@ $(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)
@@ -505,6 +512,8 @@ 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,6 +424,12 @@ $(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.
+80
View File
@@ -4,6 +4,86 @@ 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
+25
View File
@@ -0,0 +1,25 @@
/* 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
+11 -2
View File
@@ -29,14 +29,23 @@ bsearch (const void *__key, const void *__base, size_t __nmemb, size_t __size,
while (__l < __u)
{
__idx = (__l + __u) / 2;
__p = (void *) (((const char *) __base) + (__idx * __size));
__p = (const void *) (((const char *) __base) + (__idx * __size));
__comparison = (*__compar) (__key, __p);
if (__comparison < 0)
__u = __idx;
else if (__comparison > 0)
__l = __idx + 1;
else
return (void *) __p;
{
#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 NULL;
-4
View File
@@ -283,10 +283,6 @@
/* 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
+5 -1
View File
@@ -175,7 +175,11 @@ $(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)' --flags='$(conformtest-cc-flags)' \
$(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)' \
--standard=$$std --header=$$hdr $(conformtest-xfail) \
$(conformtest-cross) \
> $@ 2>&1); \
+17 -3
View File
@@ -381,12 +381,16 @@ class MacroStrTest(object):
class HeaderTests(object):
"""The set of tests run for a header."""
def __init__(self, header, standard, cc, flags, cross, xfail):
def __init__(self, header, standard, cc, flags, ldflags, libs,
run_program_prefix, 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'
@@ -590,7 +594,8 @@ 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 -o %s' % (self.cc, self.cflags, c_file, exe_file))
cmd = ('%s %s %s %s %s -o %s' % (self.cc, self.cflags, self.ldflags,
c_file, self.libs, exe_file))
try:
subprocess.check_call(cmd, shell=True)
except subprocess.CalledProcessError:
@@ -600,7 +605,9 @@ class HeaderTests(object):
self.note_skip(name)
return
try:
subprocess.check_call(exe_file, shell=True)
subprocess.check_call('%s %s' % (self.run_program_prefix,
exe_file),
shell=True)
except subprocess.CalledProcessError:
self.note_error(name, self.group_xfail)
return
@@ -719,12 +726,19 @@ 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()
+3 -20
View File
@@ -377,32 +377,15 @@ 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);
#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);
_dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded);
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
#else /* !SHARED */
call_init (argc, argv, __environ);
#ifndef SHARED
_dl_debug_initialize (0, LM_ID_BASE);
#endif
+75 -38
View File
@@ -1,4 +1,5 @@
# Copyright (C) 1998-2021 Free Software Foundation, Inc.
# Copyright (C) 1998-2022 Free Software Foundation, Inc.
# 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
@@ -108,30 +109,68 @@ 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.
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++
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))))
# backtrace_symbols only works if we link with -rdynamic. backtrace
# requires unwind tables on most architectures.
@@ -148,19 +187,25 @@ LDFLAGS-tst-backtrace6 = -rdynamic
CFLAGS-tst-ssp-1.c += -fstack-protector-all
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
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)
ifeq ($(have-ssp),yes)
tests += tst-ssp-1
endif
ifeq (,$(CXX))
tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
tst-lfschk4 tst-lfschk5 tst-lfschk6
tests-unsupported = $(tests-cc-chk)
endif
extra-libs = libSegFault libpcprofile
@@ -187,18 +232,10 @@ ifeq ($(run-built-tests),yes)
LOCALES := de_DE.UTF-8
include ../gen-locales.mk
$(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)
define chk-gen-locales
$(objpfx)$(1).out: $(gen-locales)
endef
$(foreach t, $(tests-all-chk), $(eval $(call chk-gen-locales,$(t))))
endif
sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
-2
View File
@@ -1,2 +0,0 @@
#define _FORTIFY_SOURCE 1
#include "tst-chk1.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FORTIFY_SOURCE 2
#include "tst-chk1.c"
-1
View File
@@ -1 +0,0 @@
#include "tst-chk1.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FORTIFY_SOURCE 1
#include "tst-chk1.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FORTIFY_SOURCE 2
#include "tst-chk1.c"
+98 -55
View File
@@ -1,4 +1,5 @@
/* Copyright (C) 2004-2021 Free Software Foundation, Inc.
/* Copyright (C) 2004-2022 Free Software Foundation, Inc.
Copyright The GNU Toolchain Authors.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
@@ -37,6 +38,17 @@
#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
@@ -83,8 +95,14 @@ 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;
@@ -123,6 +141,10 @@ 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;
@@ -153,7 +175,7 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10))
FAIL ();
if (mempcpy (buf + 5, "abcde", 5) != buf + 10
if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
|| memcmp (buf, "aabcdabcde", 10))
FAIL ();
@@ -198,7 +220,7 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10))
FAIL ();
if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
|| memcmp (buf, "aabcdabcde", 10))
FAIL ();
@@ -257,7 +279,8 @@ do_test (void)
if (memcmp (a.buf1, "aabcdefghi", 10))
FAIL ();
if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
!= a.buf1 + 5 + MEMPCPY_RET ("abcde")
|| memcmp (a.buf1, "aabcdabcde", 10))
FAIL ();
@@ -338,6 +361,7 @@ 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
@@ -345,6 +369,7 @@ 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);
@@ -455,6 +480,7 @@ 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
@@ -462,6 +488,7 @@ 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);
@@ -541,7 +568,7 @@ do_test (void)
if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL ();
if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
|| wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL ();
@@ -574,7 +601,8 @@ do_test (void)
if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL ();
if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
!= wbuf + 5 + WMEMPCPY_RET (L"abcde")
|| wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL ();
@@ -616,7 +644,8 @@ do_test (void)
if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
FAIL ();
if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
!= wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
|| wmemcmp (wa.buf1, L"aabcdabcde", 10))
FAIL ();
@@ -685,6 +714,7 @@ 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
@@ -692,6 +722,7 @@ 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);
@@ -759,6 +790,7 @@ 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
@@ -766,6 +798,7 @@ 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);
@@ -897,6 +930,7 @@ 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,
@@ -926,6 +960,7 @@ 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)
{
@@ -947,93 +982,95 @@ do_test (void)
rewind (stdin);
if (fgets (buf, sizeof (buf), stdin) != buf
if (fgets (buf, buf_size, stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
FAIL ();
rewind (stdin);
if (fgets (buf, l0 + sizeof (buf), stdin) != buf
if (fgets (buf, l0 + buf_size, stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
if (fgets (buf, buf_size + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
if (fgets (buf, l0 + buf_size + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
#endif
rewind (stdin);
if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
#ifdef _GNU_SOURCE
if (fgets_unlocked (buf, buf_size, stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
if (fgets_unlocked (buf, buf_size, stdin) != buf
|| memcmp (buf, "ABCDEFGHI", 10))
FAIL ();
rewind (stdin);
if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
if (fgets_unlocked (buf, buf_size + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf)
FAIL ();
CHK_FAIL_END
#endif
rewind (stdin);
#endif
if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf)
if (fread (buf, 1, buf_size, stdin) != buf_size
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread (buf, sizeof (buf), 1, stdin) != 1
if (fread (buf, buf_size, 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
rewind (stdin);
if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
if (fread (buf, l0 + 1, buf_size, stdin) != buf_size
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1
if (fread (buf, buf_size, l0 + 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1)
FAIL ();
CHK_FAIL_END
#endif
rewind (stdin);
if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf)
if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1
if (fread_unlocked (buf, buf_size, 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
@@ -1048,100 +1085,100 @@ do_test (void)
rewind (stdin);
if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size
|| memcmp (buf, "abcdefgh\nA", 10))
FAIL ();
if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1
if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1
|| memcmp (buf, "BCDEFGHI\na", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1)
FAIL ();
CHK_FAIL_END
#endif
lseek (fileno (stdin), 0, SEEK_SET);
if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
|| memcmp (buf, "ABCDEFGHI", 9))
FAIL ();
lseek (fileno (stdin), 0, SEEK_SET);
if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1)
if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1)
FAIL ();
CHK_FAIL_END
#endif
if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
!= sizeof (buf) - 1
if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2)
!= buf_size - 1
|| memcmp (buf, "\nABCDEFGH", 9))
FAIL ();
if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
!= sizeof (buf) - 1
if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
!= buf_size - 1
|| memcmp (buf, "h\nABCDEFG", 9))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
!= buf_size + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
!= buf_size + 1)
FAIL ();
CHK_FAIL_END
#endif
if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
!= sizeof (buf) - 1
if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2)
!= buf_size - 1
|| memcmp (buf, "\nABCDEFGH", 9))
FAIL ();
if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
|| memcmp (buf, "abcdefgh\n", 9))
FAIL ();
if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
!= sizeof (buf) - 1
if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
!= buf_size - 1
|| memcmp (buf, "h\nABCDEFG", 9))
FAIL ();
#if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START
if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
!= buf_size + 1)
FAIL ();
CHK_FAIL_END
CHK_FAIL_START
if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
!= sizeof (buf) + 1)
if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
!= buf_size + 1)
FAIL ();
CHK_FAIL_END
#endif
@@ -1179,7 +1216,7 @@ do_test (void)
CHK_FAIL2_END
CHK_FAIL2_START
snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4);
CHK_FAIL2_END
int sp[2];
@@ -1569,7 +1606,10 @@ do_test (void)
ret = 1;
}
int fd = posix_openpt (O_RDWR);
int fd;
#ifdef _GNU_SOURCE
fd = posix_openpt (O_RDWR);
if (fd != -1)
{
char enough[1000];
@@ -1585,6 +1625,7 @@ do_test (void)
#endif
close (fd);
}
#endif
#if PATH_MAX > 0
confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
@@ -1702,8 +1743,9 @@ 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
@@ -1711,6 +1753,7 @@ do_test (void)
CHK_FAIL_START
ppoll (fds, l0 + 2, NULL, NULL);
CHK_FAIL_END
# endif
#endif
return ret;
-2
View File
@@ -1,2 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk1.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk2.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk3.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk1.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk2.c"
-2
View File
@@ -1,2 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "tst-chk3.c"
+37
View File
@@ -0,0 +1,37 @@
/* 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>
+840 -215
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -48,6 +48,9 @@ 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;
@@ -55,6 +58,7 @@ 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
@@ -0,0 +1,381 @@
/* 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;
}
}
+11 -64
View File
@@ -266,9 +266,6 @@ _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;
@@ -302,22 +299,7 @@ _dl_close_worker (struct link_map *map, bool force)
#ifdef SHARED
/* Auditing checkpoint: we remove an object. */
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;
}
}
_dl_audit_objclose (imap);
#endif
/* This object must not be used anymore. */
@@ -478,25 +460,7 @@ _dl_close_worker (struct link_map *map, bool force)
#ifdef SHARED
/* Auditing checkpoint: we will start deleting objects. */
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;
}
}
}
_dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
#endif
/* Notify the debugger we are about to remove some loaded objects. */
@@ -549,6 +513,9 @@ _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));
@@ -784,33 +751,13 @@ _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. */
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;
}
}
}
/* 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);
#endif
if (__builtin_expect (ns->_ns_loaded == NULL, 0)
+32
View File
@@ -0,0 +1,32 @@
/* 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);
+22 -18
View File
@@ -17,6 +17,7 @@
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>
@@ -27,6 +28,24 @@
#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)
@@ -39,24 +58,9 @@ _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);
struct link_map *resolve_conflict_map __attribute__ ((__unused__))
= GL(dl_ns)[LM_ID_BASE]._ns_loaded;
#include "dynamic-link.h"
resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
/* Override these, defined in dynamic-link.h. */
#undef CHECK_STATIC_TLS
@@ -67,8 +71,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, conflict, NULL, NULL, (void *) conflict->r_offset,
0);
elf_machine_rela (l, NULL, conflict, NULL, NULL,
(void *) conflict->r_offset, 0);
}
#endif
}
+9 -15
View File
@@ -64,6 +64,10 @@ _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];
@@ -147,27 +151,17 @@ _dl_fini (void)
#ifdef SHARED
/* Auditing checkpoint: another object closed. */
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;
}
}
_dl_audit_objclose (l);
#endif
}
/* Correct the previous increment. */
--l->l_direct_opencount;
}
#ifdef SHARED
_dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
#endif
}
}
+57 -112
View File
@@ -58,6 +58,7 @@ struct filebuf
};
#include "dynamic-link.h"
#include "get-dynamic-info.h"
#include <abi-tag.h>
#include <stackinfo.h>
#include <sysdep.h>
@@ -1053,42 +1054,6 @@ _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))
@@ -1130,6 +1095,7 @@ _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;
@@ -1142,13 +1108,16 @@ _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)
if (ph->p_filesz == 0)
empty_dynamic = true; /* Usually separate debuginfo. */
else
{
/* 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;
@@ -1264,6 +1233,13 @@ _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;
@@ -1281,18 +1257,10 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
}
}
if (l->l_ld == 0)
{
if (__glibc_unlikely (type == ET_DYN))
{
errstring = N_("object file has no dynamic section");
goto lose;
}
}
else
if (l->l_ld != 0)
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
elf_get_dynamic_info (l, NULL);
elf_get_dynamic_info (l);
/* Make sure we are not dlopen'ing an object that has the
DF_1_NOOPEN flag set, or a PIE object. */
@@ -1507,24 +1475,32 @@ 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 (__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;
}
}
if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
_dl_audit_objopen (l, nsid);
#endif
return l;
@@ -1620,32 +1596,20 @@ open_verify (const char *name, int fd,
#ifdef SHARED
/* Give the auditing libraries a chance. */
if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
&& loader->l_auditing == 0)
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
const char *original_name = 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 (loader, cnt);
name = afct->objsearch (name, &state->cookie, whatcode);
if (name == NULL)
/* Ignore the path. */
return -1;
}
afct = afct->next;
}
name = _dl_audit_objsearch (name, loader, whatcode);
if (name == NULL)
return -1;
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
@@ -2084,36 +2048,17 @@ _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)
&& (loader == NULL || loader->l_auditing == 0))
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
{
struct audit_ifaces *afct = GLRO(dl_audit);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
const char *before = name;
name = _dl_audit_objsearch (name, loader, LA_SER_ORIG);
if (name == NULL)
{
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;
fd = -1;
goto no_file;
}
if (before != name && strcmp (before, name) != 0)
origname = before;
}
#endif
+10 -7
View File
@@ -59,16 +59,19 @@ _dl_new_object (char *realname, const char *libname, int type,
{
#ifdef SHARED
unsigned int naudit;
if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0))
if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0))
{
assert (type == lt_executable);
assert (nsid == LM_ID_BASE);
if (mode & __RTLD_OPENEXEC)
{
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 before we know whether
/* We create the map for the executable and vDSO before we know whether
we have auditing libraries and if yes, how many. Assume the
worst. */
naudit = DL_NNS;
+36 -23
View File
@@ -66,6 +66,9 @@ 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;
@@ -482,7 +485,7 @@ call_dl_init (void *closure)
}
static void
dl_open_worker (void *a)
dl_open_worker_begin (void *a)
{
struct dl_open_args *args = a;
const char *file = args->file;
@@ -608,25 +611,7 @@ dl_open_worker (void *a)
#ifdef SHARED
/* Auditing checkpoint: we have added all objects. */
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;
}
}
}
_dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
#endif
/* Notify the debugger all new objects are now ready to go. */
@@ -774,6 +759,36 @@ dl_open_worker (void *a)
_dl_call_libc_early_init (libc_map, false);
}
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. */
@@ -886,7 +901,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)[nsid].libc_map = NULL;
GL(dl_ns)[args.nsid].libc_map = NULL;
/* Remove the object from memory. It may be in an inconsistent
state if relocation failed, for example. */
@@ -899,8 +914,6 @@ 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));
+20 -8
View File
@@ -19,9 +19,16 @@
#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. */
@@ -30,25 +37,30 @@ _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 ());
elf_get_dynamic_info (main_map, NULL);
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);
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info);
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map, 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, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0);
main_map->l_relocated = 1;
/* Initialize _r_debug. */
+45 -32
View File
@@ -162,6 +162,32 @@ _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)
@@ -179,12 +205,28 @@ _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)
consider_profiling |= GLRO(dl_audit) != NULL;
{
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;
}
}
#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)
@@ -243,39 +285,10 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
{
/* Do the actual relocation of the object's GOT and other data. */
/* 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);
ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
#ifndef PROF
if (__glibc_unlikely (consider_profiling)
if ((consider_profiling || consider_symbind)
&& l->l_info[DT_PLTRELSZ] != NULL)
{
/* Allocate the array which will contain the already found
+37 -216
View File
@@ -16,9 +16,8 @@
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>
@@ -30,19 +29,6 @@
#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
@@ -51,7 +37,7 @@
function. */
DL_FIXUP_VALUE_TYPE
attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
_dl_fixup (
# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@@ -138,6 +124,37 @@ _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;
@@ -147,7 +164,8 @@ _dl_fixup (
#ifndef PROF
DL_FIXUP_VALUE_TYPE
__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
__attribute ((noinline))
DL_ARCH_FIXUP_ATTRIBUTE
_dl_profile_fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@@ -296,84 +314,7 @@ _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)
{
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;
}
_dl_audit_symbind (l, reloc_result, defsym, &value, result);
#endif
/* Store the result for later runs. */
@@ -396,78 +337,7 @@ _dl_profile_fixup (
#ifdef SHARED
/* Auditing checkpoint: report the PLT entering and allow the
auditors to change the value. */
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);
}
_dl_audit_pltenter (l, reloc_result, &value, regs, &framesize);
#endif
/* Store the frame size information. */
@@ -479,52 +349,3 @@ _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
@@ -0,0 +1,51 @@
/* 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,6 +229,13 @@ __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
@@ -428,3 +435,11 @@ _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)
{
}
+1 -46
View File
@@ -52,54 +52,9 @@ _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);
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;
}
_dl_audit_symbind_alt (match, ref, &value, result);
}
#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 },
+22 -11
View File
@@ -519,8 +519,12 @@ _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)
_dl_allocate_tls_init (void *result, bool init_tls)
{
if (result == NULL)
/* The memory allocation failed. */
@@ -532,7 +536,7 @@ _dl_allocate_tls_init (void *result)
size_t maxgen = 0;
/* Protects global dynamic TLS related state. */
__rtld_lock_lock_recursive (GL(dl_load_lock));
__rtld_lock_lock_recursive (GL(dl_load_tls_lock));
/* Check if the current dtv is big enough. */
if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
@@ -593,7 +597,14 @@ _dl_allocate_tls_init (void *result)
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. */
/* 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;
memset (__mempcpy (dest, map->l_tls_initimage,
map->l_tls_initimage_size), '\0',
map->l_tls_blocksize - map->l_tls_initimage_size);
@@ -606,7 +617,7 @@ _dl_allocate_tls_init (void *result)
listp = listp->next;
assert (listp != NULL);
}
__rtld_lock_unlock_recursive (GL(dl_load_lock));
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
/* The DTV version is up-to-date now. */
dtv[0].counter = maxgen;
@@ -620,7 +631,7 @@ _dl_allocate_tls (void *mem)
{
return _dl_allocate_tls_init (mem == NULL
? _dl_allocate_tls_storage ()
: allocate_dtv (mem));
: allocate_dtv (mem), true);
}
rtld_hidden_def (_dl_allocate_tls)
@@ -745,7 +756,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_lock)
This code may be called during TLS access when GL(dl_load_tls_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
@@ -867,11 +878,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_lock));
__rtld_lock_lock_recursive (GL(dl_load_tls_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_lock));
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
}
else if (__glibc_likely (the_map->l_tls_offset
!= FORCED_DYNAMIC_TLS_OFFSET))
@@ -883,7 +894,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_lock));
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
dtv[GET_ADDR_MODULE].pointer.val = p;
@@ -891,7 +902,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_lock));
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
}
struct dtv_pointer result = allocate_and_init (the_map);
dtv[GET_ADDR_MODULE].pointer = result;
@@ -962,7 +973,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_lock). Reading
/* This may be called without holding the GL(dl_load_tls_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))
+50 -19
View File
@@ -16,6 +16,8 @@
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'. */
@@ -37,8 +39,8 @@
relocations; they should be set up to call _dl_runtime_resolve, rather
than fully resolved now. */
auto inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map,
static inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
ElfW(Addr) reladdr, ElfW(Addr) relsize,
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
int lazy, int skip_ifunc)
@@ -68,13 +70,13 @@ elf_dynamic_do_Rel (struct link_map *map,
}
else
# endif
elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
elf_machine_lazy_rel (map, scope, 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, l_addr, r2, skip_ifunc);
elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc);
# endif
}
else
@@ -123,6 +125,10 @@ elf_dynamic_do_Rel (struct link_map *map,
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)
{
@@ -133,10 +139,19 @@ elf_dynamic_do_Rel (struct link_map *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);
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
}
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
@@ -146,7 +161,7 @@ elf_dynamic_do_Rel (struct link_map *map,
{
ElfW(Half) ndx
= version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
elf_machine_rel (map, r2,
elf_machine_rel (map, scope, r2,
&symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r2->r_offset),
@@ -158,23 +173,39 @@ elf_dynamic_do_Rel (struct link_map *map,
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;
}
else
if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
{
if (r2 == NULL)
r2 = r;
end2 = r;
continue;
}
# endif
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
(void *) (l_addr + r->r_offset), skip_ifunc);
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
}
# 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, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
NULL, (void *) (l_addr + r2->r_offset),
skip_ifunc);
# endif
+31 -61
View File
@@ -16,35 +16,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* 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 <dl-machine.h>
#include <elf.h>
#ifdef RESOLVE_MAP
@@ -59,40 +31,38 @@ int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
copying memory, breaking the very code written to handle the
unaligned cases. */
# if ! ELF_MACHINE_NO_REL
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,
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,
void *const reloc_addr, int skip_ifunc);
auto inline void __attribute__((always_inline))
static 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
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))
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))
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
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
static inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
int skip_ifunc);
# else
auto inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map,
static inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
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
@@ -114,7 +84,7 @@ elf_machine_lazy_rel (struct link_map *map,
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, do_lazy, skip_ifunc, test_rel) \
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
@@ -152,18 +122,18 @@ elf_machine_lazy_rel (struct link_map *map,
} \
\
if (ELF_DURING_STARTUP) \
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
ranges[0].nrelative, 0, skip_ifunc); \
elf_dynamic_do_##reloc ((map), scope, 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), \
elf_dynamic_do_##reloc ((map), scope, \
ranges[ranges_index].start, \
ranges[ranges_index].size, \
ranges[ranges_index].nrelative, \
ranges[ranges_index].lazy, \
skip_ifunc); \
skip_ifunc); \
} \
} while (0)
@@ -175,29 +145,29 @@ elf_machine_lazy_rel (struct link_map *map,
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL)
# else
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */
# define ELF_DYNAMIC_DO_REL(map, scope, 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, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL)
# else
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */
# define ELF_DYNAMIC_DO_RELA(map, scope, 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, lazy, consider_profile, skip_ifunc) \
# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
do { \
int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \
(consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \
} while (0)
#endif
+14 -38
View File
@@ -16,19 +16,17 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This file is included multiple times and therefore lacks a header
file inclusion guard. */
/* Populate dynamic tags in l_info. */
#ifndef _GET_DYNAMIC_INFO_H
#define _GET_DYNAMIC_INFO_H
#include <assert.h>
#include <dl-machine-rel.h>
#include <libc-diag.h>
#ifndef RESOLVE_MAP
static
#else
auto
#endif
inline void __attribute__ ((unused, always_inline))
elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
static inline void __attribute__ ((unused, always_inline))
elf_get_dynamic_info (struct link_map *l)
{
#if __ELF_NATIVE_CLASS == 32
typedef Elf32_Word d_tag_utype;
@@ -36,7 +34,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
typedef Elf64_Xword d_tag_utype;
#endif
#if !defined RTLD_BOOTSTRAP && !defined STATIC_PIE_BOOTSTRAP
#ifndef STATIC_PIE_BOOTSTRAP
if (l->l_ld == NULL)
return;
#endif
@@ -69,28 +67,15 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
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)
if (l->l_addr != 0 && dl_relocate_ld (l))
{
ElfW(Addr) l_addr = l->l_addr;
int cnt = 0;
# define ADJUST_DYN_INFO(tag) \
do \
if (info[tag] != NULL) \
{ \
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; \
} \
info[tag]->d_un.d_ptr += l_addr; \
while (0)
ADJUST_DYN_INFO (DT_HASH);
@@ -107,9 +92,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
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
@@ -129,18 +112,10 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
if (info[DT_REL] != NULL)
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
#endif
#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
#ifdef STATIC_PIE_BOOTSTRAP
assert (info[DT_RUNPATH] == NULL);
assert (info[DT_RPATH] == NULL);
#else
#endif
if (info[DT_FLAGS] != NULL)
{
/* Flags are used. Translate to the old form where available.
@@ -178,5 +153,6 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
if (info[DT_RUNPATH] != NULL)
/* If both RUNPATH and RPATH are given, the latter is ignored. */
info[DT_RPATH] = NULL;
#endif
}
#endif
+5 -1
View File
@@ -503,7 +503,11 @@ add_dir_1 (const char *line, const char *from_file, int from_line)
entry->path[--i] = '\0';
if (i == 0)
return;
{
free (entry->path);
free (entry);
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. */
#define LAV_CURRENT 1
#include <bits/link_lavcurrent.h>
/* Activity types signaled through la_activity. */
enum
+38 -80
View File
@@ -32,7 +32,6 @@
#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>
@@ -50,9 +49,19 @@
#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.
@@ -322,6 +331,7 @@ 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 =
@@ -463,6 +473,7 @@ _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;
@@ -499,28 +510,19 @@ _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
# 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
struct dl_start_final_info info;
rtld_timer_start (&info.start_time);
#endif
@@ -546,14 +548,15 @@ _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 ();
elf_get_dynamic_info (&bootstrap_map, NULL);
bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
elf_get_dynamic_info (&bootstrap_map);
#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.l_info);
ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info);
#endif
if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)])
@@ -561,7 +564,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, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0);
}
bootstrap_map.l_relocated = 1;
@@ -988,7 +991,7 @@ file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
return;
}
if (lav > LAV_CURRENT)
if (!_dl_audit_check_version (lav))
{
_dl_debug_printf ("\
ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n",
@@ -1013,13 +1016,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
"la_objsearch\0"
"la_objopen\0"
"la_preinit\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
LA_SYMBIND "\0"
#define STRING(s) __STRING (s)
"la_" STRING (ARCH_LA_PLTENTER) "\0"
"la_" STRING (ARCH_LA_PLTEXIT) "\0"
@@ -1061,25 +1058,6 @@ 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)
@@ -1098,8 +1076,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)
{
notify_audit_modules_of_loaded_object (main_map);
notify_audit_modules_of_loaded_object (&GL(dl_rtld_map));
_dl_audit_objopen (main_map, LM_ID_BASE);
_dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE);
}
}
@@ -1468,6 +1446,7 @@ 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
@@ -1613,7 +1592,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, NULL);
elf_get_dynamic_info (main_map);
/* If the main map is libc.so, update the base namespace to
refer to this map. If libc.so is loaded later, this happens
@@ -1783,18 +1762,7 @@ dl_main (const ElfW(Phdr) *phdr,
/* Auditing checkpoint: we are ready to signal that the initial map
is being constructed. */
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;
}
}
_dl_audit_activity_map (main_map, LA_ACT_ADD);
/* We have two ways to specify objects to preload: via environment
variable and via the file /etc/ld.so.preload. The latter can also
@@ -1918,6 +1886,12 @@ 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. */
@@ -2419,7 +2393,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);
_dl_allocate_tls_init (tcbp, false);
/* And finally install it for the main thread. */
if (! tls_init_tp_called)
@@ -2475,23 +2449,7 @@ dl_main (const ElfW(Phdr) *phdr,
#ifdef SHARED
/* Auditing checkpoint: we have added all objects. */
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;
}
}
}
_dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
#endif
/* Notify the debugger all new objects are now ready to go. We must re-get
+3 -4
View File
@@ -30,11 +30,9 @@ 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,
0, LM_ID_BASE);
__RTLD_VDSO, 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;
@@ -45,6 +43,7 @@ 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)
{
@@ -65,7 +64,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, dyn_temp);
elf_get_dynamic_info (l);
_dl_setup_hash (l);
l->l_relocated = 1;
+7
View File
@@ -17,6 +17,7 @@
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>
@@ -232,6 +233,12 @@ 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
@@ -0,0 +1,67 @@
/* 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
@@ -0,0 +1,41 @@
/* 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
@@ -0,0 +1,33 @@
/* 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
@@ -0,0 +1,60 @@
/* 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>
+129
View File
@@ -0,0 +1,129 @@
/* 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
@@ -0,0 +1,23 @@
/* 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
@@ -0,0 +1,38 @@
/* 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
@@ -0,0 +1,94 @@
/* 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
@@ -0,0 +1,23 @@
/* 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
@@ -0,0 +1,25 @@
/* 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
@@ -0,0 +1,42 @@
/* 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
@@ -0,0 +1,124 @@
/* 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
@@ -0,0 +1,239 @@
/* 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
@@ -0,0 +1,23 @@
/* 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
@@ -0,0 +1,36 @@
/* 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
@@ -0,0 +1,31 @@
/* 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
@@ -0,0 +1,25 @@
/* 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
@@ -0,0 +1,37 @@
/* 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
@@ -0,0 +1,31 @@
/* 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
@@ -0,0 +1,23 @@
/* 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
@@ -0,0 +1,2 @@
/* It tests LD_BIND_NOW=1 instead of linking with -Wl,-z,now */
#include "tst-audit24a.c"
+36
View File
@@ -0,0 +1,36 @@
/* 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
@@ -0,0 +1,33 @@
/* 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
@@ -0,0 +1,28 @@
/* 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
@@ -0,0 +1,31 @@
/* 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
@@ -0,0 +1,25 @@
/* 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
@@ -0,0 +1,129 @@
/* 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
@@ -0,0 +1,128 @@
/* 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
@@ -0,0 +1,30 @@
/* 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
@@ -0,0 +1,30 @@
/* 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
@@ -0,0 +1,22 @@
/* 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
@@ -0,0 +1,22 @@
/* 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
@@ -0,0 +1,25 @@
/* 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;
}
+73
View File
@@ -0,0 +1,73 @@
/* 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
@@ -0,0 +1,25 @@
/* 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
@@ -0,0 +1,46 @@
/* 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
@@ -0,0 +1,57 @@
/* 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
@@ -0,0 +1,80 @@
/* 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
@@ -0,0 +1,22 @@
/* 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
@@ -0,0 +1,51 @@
/* 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
@@ -0,0 +1,74 @@
/* 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
@@ -0,0 +1,29 @@
/* 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
@@ -0,0 +1,114 @@
/* 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
@@ -0,0 +1,104 @@
/* 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
@@ -0,0 +1,3 @@
#define TEST_NAME "tst-audit24c"
#define TEST_MOD "tst-audit24a"
#include "tst-auditmod24a.c"
+120
View File
@@ -0,0 +1,120 @@
/* 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
@@ -0,0 +1,79 @@
/* 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;
}
+19
View File
@@ -0,0 +1,19 @@
/* Test case for DSO with readonly dynamic section.
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 = -1;
+16
View File
@@ -0,0 +1,16 @@
SECTIONS
{
. = SIZEOF_HEADERS;
.dynamic : { *(.dynamic) } :text :dynamic
.rodata : { *(.data*) *(.bss*) } :text
/DISCARD/ : {
*(.note.gnu.property)
}
.note : { *(.note.*) } :text :note
}
PHDRS
{
text PT_LOAD FLAGS(5) FILEHDR PHDRS;
dynamic PT_DYNAMIC FLAGS(4);
note PT_NOTE FLAGS(4);
}
+31
View File
@@ -0,0 +1,31 @@
/* Test case for DSO with readonly dynamic section.
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/test-driver.h>
extern int foo;
static int
do_test (void)
{
TEST_COMPARE (foo, -1);
return 0;
}
#include <support/test-driver.c>
+1 -1
View File
@@ -478,7 +478,7 @@ __gconv_read_conf (void)
__gconv_get_path ();
for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt)
gconv_parseconfdir (__gconv_path_elem[cnt].name,
gconv_parseconfdir (NULL, __gconv_path_elem[cnt].name,
__gconv_path_elem[cnt].len);
#endif

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