Commit Graph

2987 Commits

Author SHA1 Message Date
Florian Weimer
6ade91c211 elf: Avoid some free (NULL) calls in _dl_update_slotinfo
This has been confirmed to work around some interposed mallocs.  Here
is a discussion of the impact test ust/libc-wrapper/test_libc-wrapper
in lttng-tools:

  New TLS usage in libgcc_s.so.1, compatibility impact
  <https://inbox.sourceware.org/libc-alpha/8734v1ieke.fsf@oldenburg.str.redhat.com/>

Reportedly, this patch also papers over a similar issue when tcmalloc
2.9.1 is not compiled with -ftls-model=initial-exec.  Of course the
goal really should be to compile mallocs with the initial-exec TLS
model, but this commit appears to be a useful interim workaround.

Fixes commit d2123d6827 ("elf: Fix slow
tls access after dlopen [BZ #19924]").

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit afe42e935b)
2024-06-03 19:05:39 +02:00
Adhemerval Zanella
71149c2a2e elf: Only process multiple tunable once (BZ 31686)
The 680c597e9c commit made loader reject ill-formatted strings by
first tracking all set tunables and then applying them. However, it does
not take into consideration if the same tunable is set multiple times,
where parse_tunables_string appends the found tunable without checking
if it was already in the list. It leads to a stack-based buffer overflow
if the tunable is specified more than the total number of tunables.  For
instance:

  GLIBC_TUNABLES=glibc.malloc.check=2:... (repeat over the number of
  total support for different tunable).

Instead, use the index of the tunable list to get the expected tunable
entry.  Since now the initial list is zero-initialized, the compiler
might emit an extra memset and this requires some minor adjustment
on some ports.

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

Reported-by: Yuto Maeda <maeda@cyberdefense.jp>
Reported-by: Yutaro Shimizu <shimizu@cyberdefense.jp>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit bcae44ea85)
2024-05-07 14:06:56 -03:00
H.J. Lu
fd658f026f elf: Also compile dl-misc.os with $(rtld-early-cflags)
Also compile dl-misc.os with $(rtld-early-cflags) to avoid

Program received signal SIGILL, Illegal instruction.
0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2",
    endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156
156	  bool positive = true;
(gdb) bt
 #0  0x00007ffff7fd36ea in _dl_strtoul (nptr=nptr@entry=0x7fffffffe2c9 "2",
    endptr=endptr@entry=0x7fffffffd728) at dl-misc.c:156
 #1  0x00007ffff7fdb1a9 in tunable_initialize (
    cur=cur@entry=0x7ffff7ffbc00 <tunable_list+2176>,
    strval=strval@entry=0x7fffffffe2c9 "2", len=len@entry=1)
    at dl-tunables.c:131
 #2  0x00007ffff7fdb3a2 in parse_tunables (valstring=<optimized out>)
    at dl-tunables.c:258
 #3  0x00007ffff7fdb5d9 in __GI___tunables_init (envp=0x7fffffffdd58)
    at dl-tunables.c:288
 #4  0x00007ffff7fe44c3 in _dl_sysdep_start (
    start_argptr=start_argptr@entry=0x7fffffffdcb0,
    dl_main=dl_main@entry=0x7ffff7fe5f80 <dl_main>)
    at ../sysdeps/unix/sysv/linux/dl-sysdep.c:110
 #5  0x00007ffff7fe5cae in _dl_start_final (arg=0x7fffffffdcb0) at rtld.c:494
 #6  _dl_start (arg=0x7fffffffdcb0) at rtld.c:581
 #7  0x00007ffff7fe4b38 in _start ()
(gdb)

when setting GLIBC_TUNABLES in glibc compiled with APX.
Reviewed-by: Florian Weimer <fweimer@redhat.com>

(cherry picked from commit 049b7684c9)
2024-04-25 08:20:19 -07:00
Adhemerval Zanella
aded2fc004 elf: Enable TLS descriptor tests on aarch64
The aarch64 uses 'trad' for traditional tls and 'desc' for tls
descriptors, but unlike other targets it defaults to 'desc'.  The
gnutls2 configure check does not set aarch64 as an ABI that uses
TLS descriptors, which then disable somes stests.

Also rename the internal machinery fron gnu2 to tls descriptors.

Checked on aarch64-linux-gnu.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

(cherry picked from commit 3d53d18fc7)
2024-04-01 11:16:32 -07:00
Adhemerval Zanella
a8ba52bde5 arm: Update _dl_tlsdesc_dynamic to preserve caller-saved registers (BZ 31372)
ARM _dl_tlsdesc_dynamic slow path has two issues:

  * The ip/r12 is defined by AAPCS as a scratch register, and gcc is
    used to save the stack pointer before on some function calls.  So it
    should also be saved/restored as well.  It fixes the tst-gnu2-tls2.

  * None of the possible VFP registers are saved/restored.  ARM has the
    additional complexity to have different VFP bank sizes (depending of
    VFP support by the chip).

The tst-gnu2-tls2 test is extended to check for VFP registers, although
only for hardfp builds.  Different than setcontext, _dl_tlsdesc_dynamic
does not have  HWCAP_ARM_IWMMXT (I don't have a way to properly test
it and it is almost a decade since newer hardware was released).

With this patch there is no need to mark tst-gnu2-tls2 as XFAIL.

Checked on arm-linux-gnueabihf.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>

(cherry picked from commit 64c7e34428)
2024-04-01 11:16:27 -07:00
H.J. Lu
a364304718 x86: Update _dl_tlsdesc_dynamic to preserve caller-saved registers
Compiler generates the following instruction sequence for GNU2 dynamic
TLS access:

	leaq	tls_var@TLSDESC(%rip), %rax
	call	*tls_var@TLSCALL(%rax)

or

	leal	tls_var@TLSDESC(%ebx), %eax
	call	*tls_var@TLSCALL(%eax)

CALL instruction is transparent to compiler which assumes all registers,
except for EFLAGS and RAX/EAX, are unchanged after CALL.  When
_dl_tlsdesc_dynamic is called, it calls __tls_get_addr on the slow
path.  __tls_get_addr is a normal function which doesn't preserve any
caller-saved registers.  _dl_tlsdesc_dynamic saved and restored integer
caller-saved registers, but didn't preserve any other caller-saved
registers.  Add _dl_tlsdesc_dynamic IFUNC functions for FNSAVE, FXSAVE,
XSAVE and XSAVEC to save and restore all caller-saved registers.  This
fixes BZ #31372.

Add GLRO(dl_x86_64_runtime_resolve) with GLRO(dl_x86_tlsdesc_dynamic)
to optimize elf_machine_runtime_setup.
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>

(cherry picked from commit 0aac205a81)
2024-04-01 10:42:25 -07:00
Manjunath Matti
ee7f4c54e1 powerpc: Add HWCAP3/HWCAP4 data to TCB for Power Architecture.
This patch adds a new feature for powerpc.  In order to get faster
access to the HWCAP3/HWCAP4 masks, similar to HWCAP/HWCAP2 (i.e. for
implementing __builtin_cpu_supports() in GCC) without the overhead of
reading them from the auxiliary vector, we now reserve space for them
in the TCB.

Suggested-by: Peter Bergner <bergner@linux.ibm.com>
Reviewed-by: Peter Bergner <bergner@linux.ibm.com>
(cherry picked from commit 3ab9b88e2a)
2024-03-20 18:09:32 -05:00
Andreas Schwab
9c72830eb3 elf: correct relocation statistics for !ELF_MACHINE_START_ADDRESS
Fixes: 6628c742b2 ("elf: Remove prelink support")
2024-01-29 18:27:35 +01:00
Carlos O'Donell
94aa256a47 elf: Fix tst-nodeps2 test failure.
After 78ca44da01
("elf: Relocate libc.so early during startup and dlmopen (bug 31083)")
we start seeing tst-nodeps2 failures when building the testsuite with
--enable-hard-coded-path-in-tests.

When building the testsuite with --enable-hard-coded-path-in-tests
the tst-nodeps2-mod.so is not built with the required DT_RUNPATH
values and the test escapes the test framework and loads the system
libraries and aborts. The fix is to use the existing
$(link-test-modules-rpath-link) variable to set DT_RUNPATH correctly.

No regressions on x86_64.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2024-01-10 14:08:26 -05:00
Adhemerval Zanella
460860f457 Remove ia64-linux-gnu
Linux 6.7 removed ia64 from the official tree [1], following the general
principle that a glibc port needs upstream support for the architecture
in all the components it depends on (binutils, GCC, and the Linux
kernel).

Apart from the removal of sysdeps/ia64 and sysdeps/unix/sysv/linux/ia64,
there are updates to various comments referencing ia64 for which removal
of those references seemed appropriate. The configuration is removed
from README and build-many-glibcs.py.

The CONTRIBUTED-BY, elf/elf.h, manual/contrib.texi (the porting
mention), *.po files, config.guess, and longlong.h are not changed.

For Linux it allows cleanup some clone2 support on multiple files.

The following bug can be closed as WONTFIX: BZ 22634 [2], BZ 14250 [3],
BZ 21634 [4], BZ 10163 [5], BZ 16401 [6], and BZ 11585 [7].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43ff221426d33db909f7159fdf620c3b052e2d1c
[2] https://sourceware.org/bugzilla/show_bug.cgi?id=22634
[3] https://sourceware.org/bugzilla/show_bug.cgi?id=14250
[4] https://sourceware.org/bugzilla/show_bug.cgi?id=21634
[5] https://sourceware.org/bugzilla/show_bug.cgi?id=10163
[6] https://sourceware.org/bugzilla/show_bug.cgi?id=16401
[7] https://sourceware.org/bugzilla/show_bug.cgi?id=11585
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2024-01-08 17:09:36 -03:00
H.J. Lu
848746e88e elf: Add ELF_DYNAMIC_AFTER_RELOC to rewrite PLT
Add ELF_DYNAMIC_AFTER_RELOC to allow target specific processing after
relocation.

For x86-64, add

 #define DT_X86_64_PLT     (DT_LOPROC + 0)
 #define DT_X86_64_PLTSZ   (DT_LOPROC + 1)
 #define DT_X86_64_PLTENT  (DT_LOPROC + 3)

1. DT_X86_64_PLT: The address of the procedure linkage table.
2. DT_X86_64_PLTSZ: The total size, in bytes, of the procedure linkage
table.
3. DT_X86_64_PLTENT: The size, in bytes, of a procedure linkage table
entry.

With the r_addend field of the R_X86_64_JUMP_SLOT relocation set to the
memory offset of the indirect branch instruction.

Define ELF_DYNAMIC_AFTER_RELOC for x86-64 to rewrite the PLT section
with direct branch after relocation when the lazy binding is disabled.

PLT rewrite is disabled by default since SELinux may disallow modifying
code pages and ld.so can't detect it in all cases.  Use

$ export GLIBC_TUNABLES=glibc.cpu.plt_rewrite=1

to enable PLT rewrite with 32-bit direct jump at run-time or

$ export GLIBC_TUNABLES=glibc.cpu.plt_rewrite=2

to enable PLT rewrite with 32-bit direct jump and on APX processors with
64-bit absolute jump at run-time.

Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
2024-01-05 05:49:49 -08:00
Paul Eggert
1059defeee Update copyright dates not handled by scripts/update-copyrights
I've updated copyright dates in glibc for 2024.  This is the patch for
the changes not generated by scripts/update-copyrights and subsequent
build / regeneration of generated files.
2024-01-01 10:53:40 -08:00
Paul Eggert
dff8da6b3e Update copyright dates with scripts/update-copyrights 2024-01-01 10:53:40 -08:00
H.J. Lu
8d9f9c4460 elf: Always provide _dl_get_dl_main_map in libc.a
Always provide _dl_get_dl_main_map in libc.a.  It will be used by x86
to process PT_GNU_PROPERTY segment.
2024-01-01 05:22:48 -08:00
Szabolcs Nagy
980450f126 elf: Add TLS modid reuse test for bug 29039
This is a minimal regression test for bug 29039 which only affects
targets with TLSDESC and a reproducer requires that

1) Have modid gaps (closed modules) with old generation.
2) Update a DTV to a newer generation (needs a newer dlopen).
3) But do not update the closed gap entry in that DTV.
4) Reuse the modid gap for a new module (another dlopen).
5) Use dynamic TLSDESC in that new module with old generation (bug).
6) Access TLS via this TLSDESC and the now outdated DTV.

However step (3) in practice rarely happens: during DTV update the
entries for closed modids are initialized to "unallocated" and then
dynamic TLSDESC calls __tls_get_addr independently of its generation.
The only exception to this is DTV setup at thread creation (gaps are
initialized to NULL instead of unallocated) or DTV resize where the
gap entries are outside the previous DTV array (again NULL instead
of unallocated, and this requires loading > DTV_SURPLUS modules).

So the bug can only cause NULL (+ offset) dereference, not use after
free. And the easiest way to get (3) is via thread creation.

Note that step (5) requires that the newly loaded module has larger
TLS than the remaining optional static TLS. And for (6) there cannot
be other TLS access or dlopen in the thread that updates the DTV.

Tested on aarch64-linux-gnu.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2023-12-20 08:45:48 +00:00
Stefan Liebler
3150cc0c90 Fix elf/tst-env-setuid[-static] if test needs to be rerun.
If /tmp is mounted nosuid and make xcheck is run,
then tst-env-setuid fails UNSUPPORTED with "SGID failed: GID and EGID match"
and /var/tmp/tst-sonamemove-runmod1.so.profile is created.

If you then try to rerun the test with a suid mounted test-dir
(the SGID binary is created in test-dir which defaults to /tmp)
with something like that:
make tst-env-setuid-ENV="TMPDIR=..." t=elf/tst-env-setuid test
the test fails as the LD_PROFILE output file is still available
from the previous run.

Thus this patch removes the LD_PROFILE output file in parent
before spawning the SGID binary.

Even if LD_PROFILE is not supported anymore in static binaries,
use a different library and thus output file for tst-env-setuid
and tst-env-setuid-static in order to not interfere if both
tests are run in parallel.

Furthermore the checks in test_child are now more verbose.
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2023-12-20 08:41:06 +01:00
Adhemerval Zanella
f94446c38f elf: Do not set invalid tunables values
The loader now warns for invalid and out-of-range tunable values. The
patch also fixes the parsing of size_t maximum values, where
_dl_strtoul was failing for large values close to SIZE_MAX.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-12-19 13:25:45 -03:00
Adhemerval Zanella
2a969b53c0 elf: Do not duplicate the GLIBC_TUNABLES string
The tunable parsing duplicates the tunable environment variable so it
null-terminates each one since it simplifies the later parsing. It has
the drawback of adding another point of failure (__minimal_malloc
failing), and the memory copy requires tuning the compiler to avoid mem
operations calls.

The parsing now tracks the tunable start and its size. The
dl-tunable-parse.h adds helper functions to help parsing, like a strcmp
that also checks for size and an iterator for suboptions that are
comma-separated (used on hwcap parsing by x86, powerpc, and s390x).

Since the environment variable is allocated on the stack by the kernel,
it is safe to keep the references to the suboptions for later parsing
of string tunables (as done by set_hwcaps by multiple architectures).

Checked on x86_64-linux-gnu, powerpc64le-linux-gnu, and
aarch64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-12-19 13:25:45 -03:00
Florian Weimer
b3bee76c5f elf: Initialize GLRO(dl_lazy) before relocating libc in dynamic startup
GLRO(dl_lazy) is used to set the parameters for the early
_dl_relocate_object call, so the consider_profiling setting has to
be applied before the call.

Fixes commit 78ca44da01 ("elf: Relocate
libc.so early during startup and dlmopen (bug 31083)").

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2023-12-08 14:33:03 +01:00
Adhemerval Zanella
546a1ba664 elf: Fix wrong break removal from 8ee878592c
Reported-by: Alexander Monakov <amonakov@ispras.ru>
2023-12-07 11:17:35 -03:00
Adhemerval Zanella
4369019520 elf: Refactor process_envvars
It splits between process_envvars_secure and process_envvars_default,
with the former used to process arguments for __libc_enable_secure.
It does not have any semantic change, just simplify the code so there
is no need to handle __libc_enable_secure on each len switch.

Checked on x86_64-linux-gnu and aarch64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-12-05 13:21:36 -03:00
Adhemerval Zanella
61d848b554 elf: Ignore LD_BIND_NOW and LD_BIND_NOT for setuid binaries
To avoid any environment variable to change setuid binaries
semantics.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-12-05 13:21:36 -03:00
Adhemerval Zanella
876a12e513 elf: Ignore loader debug env vars for setuid
Loader already ignores LD_DEBUG, LD_DEBUG_OUTPUT, and
LD_TRACE_LOADED_OBJECTS. Both LD_WARN and LD_VERBOSE are similar to
LD_DEBUG, in the sense they enable additional checks and debug
information, so it makes sense to disable them.

Also add both LD_VERBOSE and LD_WARN on filtered environment variables
for setuid binaries.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-12-05 13:21:36 -03:00
Adhemerval Zanella
a4c3f5f46e elf: Add a way to check if tunable is set (BZ 27069)
The patch adds two new macros, TUNABLE_GET_DEFAULT and TUNABLE_IS_INITIALIZED,
here the former get the default value with a signature similar to
TUNABLE_GET, while the later returns whether the tunable was set by
the environment variable.

Checked on x86_64-linux-gnu.
Reviewed-by: DJ Delorie <dj@redhat.com>
Tested-by: Zhangfei Gao <zhangfei.gao@linaro.org>
2023-11-29 09:30:00 -03:00
Hector Martin
3921c5b40f elf: Fix TLS modid reuse generation assignment (BZ 29039)
_dl_assign_tls_modid() assigns a slotinfo entry for a new module, but
does *not* do anything to the generation counter. The first time this
happens, the generation is zero and map_generation() returns the current
generation to be used during relocation processing. However, if
a slotinfo entry is later reused, it will already have a generation
assigned. If this generation has fallen behind the current global max
generation, then this causes an obsolete generation to be assigned
during relocation processing, as map_generation() returns this
generation if nonzero. _dl_add_to_slotinfo() eventually resets the
generation, but by then it is too late. This causes DTV updates to be
skipped, leading to NULL or broken TLS slot pointers and segfaults.

Fix this by resetting the generation to zero in _dl_assign_tls_modid(),
so it behaves the same as the first time a slot is assigned.
_dl_add_to_slotinfo() will still assign the correct static generation
later during module load, but relocation processing will no longer use
an obsolete generation.

Note that slotinfo entry (aka modid) reuse typically happens after a
dlclose and only TLS access via dynamic tlsdesc is affected. Because
tlsdesc is optimized to use the optional part of static TLS, dynamic
tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls
tunable to a large enough value, or by LD_PRELOAD-ing the affected
modules.

Fixes bug 29039.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
2023-11-28 17:28:02 +00:00
Florian Weimer
78ca44da01 elf: Relocate libc.so early during startup and dlmopen (bug 31083)
This makes it more likely that objects without dependencies can
use IFUNC resolvers in libc.so.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2023-11-27 11:28:13 +01:00
Florian Weimer
a74c2e1cbc elf: Introduce the _dl_open_relocate_one_object function
It is extracted from dl_open_worker_begin.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2023-11-27 11:28:10 +01:00
Florian Weimer
b893410be3 elf: In _dl_relocate_object, skip processing if object is relocated
This is just a minor optimization.  It also makes it more obvious that
_dl_relocate_object can be called multiple times.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2023-11-27 11:28:07 +01:00
Adhemerval Zanella
780c339202 elf: Add comments on how LD_AUDIT and LD_PRELOAD handle __libc_enable_secure
To make explicit why __libc_enable_secure is not checked.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
5451fa962c elf: Ignore LD_LIBRARY_PATH and debug env var for setuid for static
It mimics the ld.so behavior.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
a0f9bfc3a5 elf: Remove any_debug from dl_main_state
Its usage can be implied by the GLRO(dl_debug_mask).
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
55f41ef8de elf: Remove LD_PROFILE for static binaries
The _dl_non_dynamic_init does not parse LD_PROFILE, which does not
enable profile for dlopen objects.  Since dlopen is deprecated for
static objects, it is better to remove the support.

It also allows to trim down libc.a of profile support.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
4a133885a7 elf: Ignore LD_PROFILE for setuid binaries
Loader does not ignore LD_PROFILE in secure-execution mode (different
than man-page states [1]), rather it uses a different path
(/var/profile) and ignore LD_PROFILE_OUTPUT.

Allowing secure-execution profiling is already a non good security
boundary, since it enables different code paths and extra OS access by
the process.  But by ignoring LD_PROFILE_OUTPUT, the resulting profile
file might also be acceded in a racy manner since the file name does not
use any process-specific information (such as pid, timing, etc.).

Another side-effect is it forces lazy binding even on libraries that
might be with DF_BIND_NOW.

[1] https://man7.org/linux/man-pages/man8/ld.so.8.html
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
eb9291aaa6 elf: Emit warning if tunable is ill-formatted
So caller knows that the tunable will be ignored.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
434eca873f elf: Fix _dl_debug_vdprintf to work before self-relocation
The strlen might trigger and invalid GOT entry if it used before
the process is self-relocated (for instance on dl-tunables if any
error occurs).

For i386, _dl_writev with PIE requires to use the old 'int $0x80'
syscall mode because the calling the TLS register (gs) is not yet
initialized.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
680c597e9c elf: Do not parse ill-formatted strings
Instead of ignoring ill-formatted tunable strings, first, check all the
tunable definitions are correct and then set each tunable value. It
means that partially invalid strings, like "key1=value1:key2=key2=value'
or 'key1=value':key2=value2=value2' do not enable 'key1=value1'. It
avoids possible user-defined errors in tunable definitions.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
b4cf6cac73 elf: Do not process invalid tunable format
Tunable definitions with more than one '=' on are parsed and enabled,
and any subsequent '=' are ignored.  It means that tunables in the form
'tunable=tunable=value' or 'tunable=value=value' are handled as
'tunable=value'.  These inputs are likely user input errors, which
should not be accepted.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
11f7e3dd8f elf: Add all malloc tunable to unsecvars
Some environment variables allow alteration of allocator behavior
across setuid boundaries, where a setuid program may ignore the
tunable, but its non-setuid child can read it and adjust the memory
allocator behavior accordingly.

Most library behavior tunings is limited to the current process and does
not bleed in scope; so it is unclear how pratical this misfeature is.
If behavior change across privilege boundaries is desirable, it would be
better done with a wrapper program around the non-setuid child that sets
these envvars, instead of using the setuid process as the messenger.

The patch as fixes tst-env-setuid, where it fail if any unsecvars is
set.  It also adds a dynamic test, although it requires
--enable-hardcoded-path-in-tests so kernel correctly sets the setuid
bit (using the loader command directly would require to set the
setuid bit on the loader itself, which is not a usual deployment).

Co-authored-by: Siddhesh Poyarekar <siddhesh@sourceware.org>

Checked on x86_64-linux-gnu.
Reviewed-by: DJ Delorie <dj@redhat.com>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
9c96c87d60 elf: Ignore GLIBC_TUNABLES for setuid/setgid binaries
The tunable privilege levels were a retrofit to try and keep the malloc
tunable environment variables' behavior unchanged across security
boundaries.  However, CVE-2023-4911 shows how tricky can be
tunable parsing in a security-sensitive environment.

Not only parsing, but the malloc tunable essentially changes some
semantics on setuid/setgid processes.  Although it is not a direct
security issue, allowing users to change setuid/setgid semantics is not
a good security practice, and requires extra code and analysis to check
if each tunable is safe to use on all security boundaries.

It also means that security opt-in features, like aarch64 MTE, would
need to be explicit enabled by an administrator with a wrapper script
or with a possible future system-wide tunable setting.

Co-authored-by: Siddhesh Poyarekar  <siddhesh@sourceware.org>
Reviewed-by: DJ Delorie <dj@redhat.com>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
a72a4eb10b elf: Add GLIBC_TUNABLES to unsecvars
setuid/setgid process now ignores any glibc tunables, and filters out
all environment variables that might changes its behavior. This patch
also adds GLIBC_TUNABLES, so any spawned process by setuid/setgid
processes should set tunable explicitly.

Checked on x86_64-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Adhemerval Zanella
6c6fce572f elf: Remove /etc/suid-debug support
Since malloc debug support moved to a different library
(libc_malloc_debug.so), the glibc.malloc.check requires preloading the
debug library to enable it.  It means that suid-debug support has not
been working since 2.34.

To restore its support, it would require to add additional information
and parsing to where to find libc_malloc_debug.so.

It is one thing less that might change AT_SECURE binaries' behavior
due to environment configurations.

Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2023-11-21 16:15:42 -03:00
Florian Weimer
cfb5a97a93 ldconfig: Fixes for skipping temporary files.
Arguments to a memchr call were swapped, causing incorrect skipping
of files.

Files related to dpkg have different names: they actually end in
.dpkg-new and .dpkg-tmp, not .tmp as I mistakenly assumed.

Fixes commit 2aa0974d25 ("elf: ldconfig should skip
temporary files created by package managers").
2023-11-20 10:57:34 +01:00
Florian Weimer
8c8eff33e4 nptl: Rename tst-execstack to tst-execstack-threads
So that the test is harder to confuse with elf/tst-execstack
(although the tests are supposed to be the same).

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2023-11-20 09:22:21 +01:00
Florian Weimer
849274d48f elf: Fix force_first handling in dlclose (bug 30981)
The force_first parameter was ineffective because the dlclose'd
object was not necessarily the first in the maps array.  Also
enable force_first handling unconditionally, regardless of namespace.
The initial object in a namespace should be destructed first, too.

The _dl_sort_maps_dfs function had early returns for relocation
dependency processing which broke force_first handling, too, and
this is fixed in this change as well.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2023-11-16 20:16:05 +01:00
Adhemerval Zanella
a8dcffb306 elf: Handle non-directory name in search path (BZ 31035)
The open_path stops if a relative path in search path contains a
component that is a non directory (for instance, if the component
is an existing file).

For instance:

  $ cat > lib.c <<EOF
  > void foo (void) {}
  > EOF
  $ gcc -shared -fPIC -o lib.so lib.c
  $ cat > main.c <<EOF
  extern void foo ();
  int main () { foo (); return 0; }
  EOF
  $ gcc -o main main.c lib.so
  $ LD_LIBRARY_PATH=. ./main
  $ LD_LIBRARY_PATH=non-existing/path:. ./main
  $ LD_LIBRARY_PATH=$(pwd)/main:. ./main
  $ LD_LIBRARY_PATH=./main:. ./main
  ./main: error while loading shared libraries: lib.so: cannot open shared object file: No such file or directory

The invalid './main' should be ignored as a non-existent one,
instead as a valid but non accessible file.

Absolute paths do not trigger this issue because their status are
initialized as 'unknown' and open_path check if this is a directory.

Checked on x86_64-linux-gnu.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
2023-11-16 11:01:51 -03:00
Yanzhang Wang
2d27dc1c75 test: Run the tst-tls-allocation-failure-static-patched with test-wrapper.
If we use cross test with ssh, this test needs to be ran on the remote.
2023-11-13 15:55:33 +01:00
Adhemerval Zanella
bf033c0072 elf: Add glibc.mem.decorate_maps tunable
The PR_SET_VMA_ANON_NAME support is only enabled through a configurable
kernel switch, mainly because assigning a name to a
anonymous virtual memory area might prevent that area from being
merged with adjacent virtual memory areas.

For instance, with the following code:

   void *p1 = mmap (NULL,
                    1024 * 4096,
                    PROT_READ | PROT_WRITE,
                    MAP_PRIVATE | MAP_ANONYMOUS,
                    -1,
                    0);

   void *p2 = mmap (p1 + (1024 * 4096),
                    1024 * 4096,
                    PROT_READ | PROT_WRITE,
                    MAP_PRIVATE | MAP_ANONYMOUS,
                    -1,
                    0);

The kernel will potentially merge both mappings resulting in only one
segment of size 0x800000.  If the segment is names with
PR_SET_VMA_ANON_NAME with different names, it results in two mappings.

Although this will unlikely be an issue for pthread stacks and malloc
arenas (since for pthread stacks the guard page will result in
a PROT_NONE segment, similar to the alignment requirement for the arena
block), it still might prevent the mmap memory allocated for detail
malloc.

There is also another potential scalability issue, where the prctl
requires
to take the mmap global lock which is still not fully fixed in Linux
[1] (for pthread stacks and arenas, it is mitigated by the stack
cached and the arena reuse).

So this patch disables anonymous mapping annotations as default and
add a new tunable, glibc.mem.decorate_maps, can be used to enable
it.

[1] https://lwn.net/Articles/906852/

Checked on x86_64-linux-gnu and aarch64-linux-gnu.
Reviewed-by: DJ Delorie <dj@redhat.com>
2023-11-07 10:27:57 -03:00
Adhemerval Zanella
fee9e40a8d malloc: Decorate malloc maps
Add anonymous mmap annotations on loader malloc, malloc when it
allocates memory with mmap, and on malloc arena.  The /proc/self/maps
will now print:

   [anon: glibc: malloc arena]
   [anon: glibc: malloc]
   [anon: glibc: loader malloc]

On arena allocation, glibc annotates only the read/write mapping.

Checked on x86_64-linux-gnu and aarch64-linux-gnu.
Reviewed-by: DJ Delorie <dj@redhat.com>
2023-11-07 10:27:20 -03:00
Adhemerval Zanella
6afce56c19 nptl: Decorate thread stack on pthread_create
Linux 4.5 removed thread stack annotations due to the complexity of
computing them [1], and Linux added PR_SET_VMA_ANON_NAME on 5.17
as a way to name anonymous virtual memory areas.

This patch adds decoration on the stack created and used by
pthread_create, for glibc crated thread stack the /proc/self/maps will
now show:

  [anon: glibc: pthread stack: <tid>]

And for user-provided stacks:

  [anon: glibc: pthread user stack: <tid>]

The guard page is not decorated, and the mapping name is cleared when
the thread finishes its execution (so the cached stack does not have any
name associated).

Checked on x86_64-linux-gnu aarch64 aarch64-linux-gnu.

[1] 65376df582

Co-authored-by: Ian Rogers <irogers@google.com>
Reviewed-by: DJ Delorie <dj@redhat.com>
2023-11-07 10:27:20 -03:00
Adhemerval Zanella
d3476c20b2 linux: Sync Linux 6.6 elf.h
It adds NT_X86_SHSTK (2fab02b25ae7cf5), NT_RISCV_CSR/NT_RISCV_VECTOR
(9300f00439743c4), and NT_LOONGARCH_HW_BREAK/NT_LOONGARCH_HW_WATCH
(1a69f7a161a78ae).
2023-11-03 10:01:46 -03:00