Commit Graph
57 Commits
Author SHA1 Message Date
Mike Yuan 08c3010399 elf-util: fix alignment 2026-01-03 20:08:12 +01:00
Daan De Meyer 52ecf376fa tree-wide: Migrate to pidref_safe_fork()
Let's migrate all remaining callers of safe_fork()
to pidref_safe_fork() and get rid of safe_fork().
2026-01-02 20:08:41 +01:00
Yu Watanabe 9ba0e5674b Bump required minimum version of elfutils to 0.177
Major distributions already have elfutils >= 0.190.
Let's bump the required minimum version.

Note, elfutils 0.177 was released on 2019-08-14.

See also #38608.
2026-01-02 11:12:27 +09:00
Jelle van der Waa 887db52362 elf-util: prefer using SD_JSON_BUILD_PAIR_* macros
No functional change, just refactoring.
2025-11-14 15:47:15 +01:00
Daan De Meyer 004b7f1f7e elf-util: Add support for parsing dlopen metadata
Then we can add support for showing dlopen metadata to systemd-analyze.
2025-10-30 08:41:43 +01:00
Yu Watanabe 76afd4dc4a elf-util: drop 'sym_' prefix from cleanup function 2025-10-25 11:26:39 +09:00
Daan De Meyer ff33c8f87d Extend test-dlopen-so to also cover cases when built without support
Let's make things more consistent and have all dlopen_xxx() functions
return EOPNOTSUPP on failure and verify this behavior in test-dlopen-so.
2025-09-17 19:40:17 +01:00
Zbigniew Jędrzejewski-Szmek 505a5d2bcd Merge remote-tracking branch 'systemd-security/coredump-d' 2025-05-29 17:22:19 +02:00
Zbigniew Jędrzejewski-Szmek 9ce8e3e449 Define helper to call PR_SET_DUMPABLE 2025-05-29 00:19:24 +02:00
Daan De Meyer 69a283c5f2 shared: Clean up includes
Split out of #37344.
2025-05-24 14:00:44 +02:00
Daan De Meyer 1cf40697e3 tree-wide: Sort includes
This was done by running a locally built clang-format with
https://github.com/llvm/llvm-project/pull/137617 and
https://github.com/llvm/llvm-project/pull/137840 applied on all .c
and .h files.
2025-04-30 09:30:51 +02:00
Daan De Meyer 93a1f7921a basic: Stop including log.h in macro.h
Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
2025-04-18 14:19:15 +02:00
Ivan Kruglov 7022563b5b use report_errno_and_exit() in src/shared/elf-util.c 2024-11-06 11:18:38 +01:00
Michal Sekletar 68511cebe5 coredump: generate properly symbolized stacktrace for containerized processes 2024-08-06 18:32:42 +02:00
Lennart Poettering 18eaff4272 tree-wide: fix type of read() return variable at a couple of places
read() returns ssize_t (i.e. 64bit typically). We assigned it to int
variables in some cases (i.e. 32bit typically). Let's not be so sloppy,
and not accidentally drop 32bit on the floor.

(of course, this is not an issue IRL since we'll not have allocations
above 2^32 ever we could read into, but still, let's clean this up)
2024-06-22 17:05:36 +09:00
Lennart Poettering be5bee2a13 tree-wide: port over to new builder apis 2024-06-19 22:50:02 +02:00
Mike Yuan 609bc3ae16 Merge pull request #33037 from keszybz/dlopen-open-code-definitions
Make dlopen macros more explicit and drop mac_selinux_free()
2024-06-15 12:49:59 +02:00
Lennart Poettering 309a747fa6 libsystemd: turn json.[ch] into a public API
This is preparation for making our Varlink API a public API. Since our
Varlink API is built on top of our JSON API we need to make that public
first (it's a nice API, but JSON APIs there are already enough, this is
purely about the Varlink angle).

I made most of the json.h APIs public, and just placed them in
sd-json.h. Sometimes I wasn't so sure however, since the underlying data
structures would have to be made public too. If in doubt I didn#t risk
it, and moved the relevant API to src/libsystemd/sd-json/json-util.h
instead (without any sd_* symbol prefixes).

This is mostly a giant search/replace patch.
2024-06-12 18:42:22 +02:00
Zbigniew Jędrzejewski-Szmek 5c672e90a6 basic/dlfcn-util: deobfuscate macro definitions
When looking at how dlopen for various libs is implemented, I found that the
macros hide too much. I find it much easier to see what is going on if 'extern'
and '= NULL' are written explicitly. After all, we don't hide those for other
definitions, e.g. our style guide says that static variables should be
initialized with '= NULL'. With that change, it's much more obvious what is
a variable declaration and what is a variable initialization.
2024-06-12 15:21:15 +02:00
Lennart PoetteringandLuca Boccassi cd7c207795 tree-wide: add dlopen ELF notes to all dlopen() deps of ours
Use 'recommended' priority for the default compression library, to
indicate that it should be prioritized over the other ones, as it
will be used to compress journals/core files.
Also use 'recommended' for kmod, as systems will likely fail to boot
if it's missing from the initrd.
Use 'suggested' for everything else.

There is one dlopen'ed TPM library that has the name generated
at runtime (depending on the driver), so that cannot be added, as it
needs to be known at build time.
Also when we support multiple ABI versions list them all, as for the
same reason we cannot know which one will be used at build time.

$ dlopen-notes.py build/libsystemd.so.0.39.0 build/src/shared/libsystemd-shared-256.so
libarchive.so.13 suggested
libbpf.so.0 suggested
libbpf.so.1 suggested
libcryptsetup.so.12 suggested
libdw.so.1 suggested
libelf.so.1 suggested
libfido2.so.1 suggested
libgcrypt.so.20 suggested
libidn2.so.0 suggested
libip4tc.so.2 suggested
libkmod.so.2 recommended
liblz4.so.1 suggested
liblzma.so.5 suggested
libp11-kit.so.0 suggested
libpcre2-8.so.0 suggested
libpwquality.so.1 suggested
libqrencode.so.3 suggested
libqrencode.so.4 suggested
libtss2-esys.so.0 suggested
libtss2-mu.so.0 suggested
libtss2-rc.so.0 suggested
libzstd.so.1 recommended

Co-authored-by: Luca Boccassi <bluca@debian.org>
2024-05-08 11:07:36 +01:00
Lennart Poettering 9dbabd0a8b tree-wide: switch dlopen hooks over to DLSYM_PROTOTYPE()/DLSYM_FUNCTION()
We have these pretty macros, let's use them everywhere (so far we mostly
used them for newer additions only).

This PR is mostly an excercise in "perl -p -i -e", but there are some
special cases:

* idn-util.c exposes a function whose prototype in the official library
  headers is marked with the "const" attribute, and this apparently does
  not propagate along typeof() correctly and then
  __builtin_types_compatible_p() fails later because it detects that
  prototype and original function don't match in prototype.

* libbpf removed some symbols in newer versions, hence we need to define
  some prototypes manually to still be able to build.

* libcryptsetup marked a symbol as deprecated we want to use (knowing it
  is deprecated). By using the macros this is detected by the compiler.
  We work around it via the usual warning off macros.

Note by using these macros we assume that all symbols are known during
build time. Which might not be the case. We might need to revert this
commit for some symbols if this trips up builds on older distros.
2024-03-01 15:51:24 +00:00
Adrian Vovk a7a67dfd9d fundamental: Add overflow-safe math helpers
ADD_SAFE/SUB_SAFE/MUL_SAFE do addition/subtraction/multiplication
respectively with an overflow check. If an overflow occurs these return
false, otherwise true. Example: (c = a + b) would become ADD_SAFE(&c, a,
b)

INC_SAFE/DEC_SAFE/MUL_ASSIGN_SAFE are like above but they also reassign
the first argument. Example: (a += b) would become INC_SAFE(&a, b)
2024-02-13 13:08:20 -05:00
Frantisek Sumsal c83f4220a1 tree-wide: use IN_SET() more 2023-12-27 11:15:48 +01:00
Lennart Poettering 7113640493 fd-uitl: rename PIPE_EBADF → EBADF_PAIR, and add EBADF_TRIPLET
We use it for more than just pipe() arrays. For example also for
socketpair(). Hence let's give it a generic name.

Also add EBADF_TRIPLET to mirror this for things like
stdin/stdout/stderr arrays, which we use a bunch of times.
2023-10-26 22:30:42 +02:00
Yu Watanabe 86cbbc6d05 tree-wide: check if return value of lseek() and friends is negative
We usually check return value of syscalls or glibc functions by it is
negative or not, something like that `if (stat(path, &st) < 0)`.
Let's also use the same style for lseek() and friends even the type of
their return value is off_t.

Note, fseeko() returns int, instead of off_t.
2023-10-19 18:31:44 +09:00
Mike Yuan e22c60a9d5 io-util: introduce loop_write_full that takes a timeout
Also drop do_poll as the use case is covered
by timeout.
2023-09-07 20:30:44 +08:00
Lennart Poettering e931768eb4 json: rename json_append() → json_variant_merge_objectb()
json_append() is a useful wrapper around json_variant_merge(). However,
I think the naming sould be cleaned up a bit of both functions.

I thinker "merge" is the better word than "append", since it does
decidedly more than just append: it replaces existing fields of the same
name, hence "merge" sounds more appropriate. This is as opposed to the
similar operations for arrays, where no such override logic is applied
and we really just append, hence those functions are called "append"
already.

To make clearer that "merge" is about objects, and "append" about
arrays, also include "object" in the name.

Also, include "json_variant" in the name, like we do for almost all
other functions in the JSON API that take a JSON object as primary
input, and hence are kinda object methods.

Finally, let's follow the logic that helpers that combine json_build()
with some other operation get suffixed with "b" like we already have in
some cases.

Hence:

json_variant_merge() → json_variant_merge_object()
       json_append() → json_variant_merge_objectb()

This mirrors nicely the existing:
                       json_variant_append_array()
                       json_vairant_append_arrayb()

This also drops the variant of json_append() that takes a va_arg
parameter (i.e. json_appendv()). We have no user of that so far, and
given the nature as a helper function only I don#t see that happening,
and if it happens after all it's trivial to bring back.
2023-08-24 13:20:39 +02:00
Romain Geissler 3965f173ea elf-util: check for overflow when computing end of core's PT_LOAD segments 2023-06-23 12:35:34 +01:00
Romain Geissler 21a2c735e2 elf-util: discard PT_LOAD segment early based on the start address.
Indeed when iterating over all the PT_LOAD segment of the core dump
while trying to look for the elf headers of a given module, we iterate
over them all and try to use the first one for which we can parse a
package metadata, but the start address is never taken into account,
so absolutely nothing guarantees we actually parse the right ELF header
of the right module we are currently iterating on.

This was tested like this:
 - Create a core dump using sleep on a fedora 37 container, with an
   explicit LD_PRELOAD of a library having a valid package metadata:

    podman run -t -i --rm -v $(pwd):$(pwd) -w $(pwd) fedora:37 bash -x -c \
        'LD_PRELOAD=libreadline.so.8 sleep 1000 & SLEEP_PID="$!" && sleep 1 && kill -11 "${SLEEP_PID}" && mv "core.${SLEEP_PID}" the-core'

 - Then from a fedora 38 container with systemd installed, the resulting
   core dump has been passed to systemd-coredump with and without this
   patch. Without this patch, we get:

       Module /usr/bin/sleep from rpm bash-5.2.15-3.fc38.x86_64
       Module /usr/lib64/libtinfo.so.6.3 from rpm coreutils-9.1-8.fc37.x86_64
       Module /usr/lib64/libc.so.6 from rpm coreutils-9.1-8.fc37.x86_64
       Module /usr/lib64/libreadline.so.8.2 from rpm coreutils-9.1-8.fc37.x86_64
       Module /usr/lib64/ld-linux-x86-64.so.2 from rpm coreutils-9.1-8.fc37.x86_64

   While with this patch we get:

       Module /usr/bin/sleep from rpm bash-5.2.15-3.fc38.x86_64
       Module /usr/lib64/libtinfo.so.6.3 from rpm ncurses-6.3-5.20220501.fc37.x86_64
       Module /usr/lib64/libreadline.so.8.2 from rpm readline-8.2-2.fc37.x86_64

So the parsed package metadata reported by systemd-coredump when the module
files are not found on the host (ie the case of crash inside a container) are
now correct. The inconsistency of the first module in the above example
(sleep is indeed not provided by the bash package) can be ignored as it
is a consequence of how this was tested.

In addition to this, this also fixes the performance issue of
systemd-coredump in case of the crashing process uses a large number of
shared libraries and having no package metadata, as reported in
https://sourceware.org/pipermail/elfutils-devel/2023q2/006225.html.
2023-06-21 19:07:20 +01:00
Yu Watanabe 2485b7e2b8 tree-wide: use memstream-util 2023-06-01 06:48:47 +09:00
Yu Watanabe a694747d45 elf-util: rename stack_context_destroy() -> stack_context_done() 2023-06-01 06:47:48 +09:00
Yu Watanabe 5d2a48da12 tree-wide: use _cleanup_set_free_ and friends
Instead of _cleanup_(set_freep) or so.
2023-06-01 06:47:48 +09:00
Frantisek Sumsal f392dfb5a1 tree-wide: check memstream buffer after closing the handle
When closing the FILE handle attached to a memstream, it may attempt to
do a realloc() that may fail during OOM situations, in which case we are
left with the buffer pointer pointing to NULL and buffer size > 0. For
example:

```
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>

    void *realloc(void *ptr, size_t size) {
        return NULL;
    }

    int main(int argc, char *argv[])
    {
        FILE *f;
        char *buf;
        size_t sz = 0;

        f = open_memstream(&buf, &sz);
        if (!f)
            return -ENOMEM;

        fputs("Hello", f);

        fflush(f);
        printf("buf: 0x%lx, sz: %lu, errno: %d\n",
                    (unsigned long) buf, sz, errno);
        fclose(f);
        printf("buf: 0x%lx, sz: %lu, errno: %d\n",
                    (unsigned long) buf, sz, errno);

        return 0;
    }
```

```
$ gcc -o main main.c
$ ./main
buf: 0x74d4a0, sz: 5, errno: 0
buf: 0x0, sz: 5, errno: 0
```

This might do unexpected things if the underlying code expects a valid
pointer to the memstream buffer after closing the handle.

Found by Nallocfuzz.
2023-05-24 21:59:10 +02:00
Yu Watanabe 911f8f0183 process-util: rename FORK_NULL_STDIO -> FORK_REARRANGE_STDIO
And make safe_fork_full() takes fds to be assigned to stdio.
2023-02-21 07:37:51 +09:00
Yu Watanabe 19ee48a6c2 tree-wide: introduce PIPE_EBADF macro 2022-12-20 11:12:58 +09:00
Zbigniew Jędrzejewski-Szmek 3401477982 tree-wide: use -EBADF also in pipe initializers
In some places, initialization is dropped when unnecesary.
2022-12-19 15:00:59 +01:00
Zbigniew Jędrzejewski-Szmek c5966ab5bf coredump: cescape invalid json data before logging
In both cases, the json string is short, so we can print it, which is useful
for diagnosing invalid data in packages. But we need escape non-printable
characters.

https://bugzilla.redhat.com/show_bug.cgi?id=2152685

I went over the rest of the codebase, and it seems that other calls to
json_parse() don't have this problem.
2022-12-14 01:37:19 +09:00
Zbigniew Jędrzejewski-Szmek 3ae6b3bf72 basic: rename util.h to logarithm.h
util.h is now about logarithms only, so we can rename it. Many files included
util.h for no apparent reason… Those includes are dropped.
2022-11-08 18:21:10 +01:00
Zbigniew Jędrzejewski-Szmek 076b807be4 coredump: avoid deadlock when passing processed backtrace data
We would deadlock when passing the data back from the forked-off process that
was doing backtrace generation back to the coredump parent. This is because we
fork the child and wait for it to exit. The child tries to write too much data
to the output pipe, and and after the first 64k blocks on the parent because
the pipe is full. The bug surfaced in Fedora because of a combination of four
factors:
- 87707784c7 was backported to v251.5, which
  allowed coredump processing to be successful.
- 1a0281a3eb was NOT backported, so the output
  was very verbose.
- Fedora has the ELF package metadata available, so a lot of output can be
  generated. Most other distros just don't have the information.
- gnome-calendar crashes and has a bazillion modules and 69596 bytes of output
  are generated for it.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=2135778.

The code is changed to try to write data opportunistically. If we get partial
information, that is still logged. In is generally better to log partial
backtrace information than nothing at all.
2022-10-19 09:46:55 +02:00
Zbigniew Jędrzejewski-Szmek 87a16eb8b5 shared/json: use different return code for empty input
It is useful to distinguish if json_parse_file() got no input or invalid input.
Use different return codes for the two cases.
2022-10-19 09:46:55 +02:00
Yu Watanabe f6e88aac2c elf-util: drop assertion for metadata in report_module_metadata()
Fixes a bug introduced by 1a0281a3eb.

Fixes RHBZ#2134741 (https://bugzilla.redhat.com/show_bug.cgi?id=2134741).
2022-10-14 18:08:11 +02:00
Zbigniew Jędrzejewski-Szmek 470c9768c1 coredump: print build-id only when package version is missing
The build-id is quite verbose, and probably not very useful to a user when they
already know the nvra of the package.
2022-09-28 10:48:25 +02:00
Zbigniew Jędrzejewski-Szmek 1a0281a3eb coredump: shorten output about package metadata to one line
We would print the whole thing in extenso. Users generally don't care,
and would likely prefer to just get the compact identifier of the package
that they can use in a bug report or package manager commands.

Before:
systemd-coredump[40645]: [🡕] Process 1975 (gnome-shell) of user 1000 dumped core.

                         Module /usr/bin/gnome-shell (deleted) with build-id aafdb7d69a7efca937e490080ad9348541fc57d8
                         Metadata for module /usr/bin/gnome-shell (deleted) owned by FDO found: {
                                 "type" : "rpm",
                                 "name" : "gnome-shell",
                                 "version" : "43~rc-3.fc37",
                                 "architecture" : "x86_64",
                                 "osCpe" : "cpe:/o:fedoraproject:fedora:37"
                         }

                         Module /usr/lib64/gnome-shell/libgvc.so (deleted) with build-id 56cbb9862e1ee84ca1549b94f2b4cda03537613e
                         Metadata for module /usr/lib64/gnome-shell/libgvc.so (deleted) owned by FDO found: {
                                 "type" : "rpm",
                                 "name" : "gnome-shell",
                                 "version" : "43~rc-2.fc37",
                                 "architecture" : "x86_64",
                                 "osCpe" : "cpe:/o:fedoraproject:fedora:37"
                         }

                         Module /usr/lib64/libLLVM-14.so (deleted) with build-id ffa7e43f48eb4c189304c0241b1862710de4c3a4
                         Metadata for module /usr/lib64/libLLVM-14.so (deleted) owned by FDO found: {
                                 "type" : "rpm",
                                 "name" : "gnome-shell",
                                 "version" : "43~rc-2.fc37",
                                 "architecture" : "x86_64",
                                 "osCpe" : "cpe:/o:fedoraproject:fedora:37"
                         }

After:
systemd-coredump[235218]: [🡕] Process 235216 (bash) of user 1000 dumped core.

                          Module libtinfo.so.6 from rpm ncurses-6.3-3.20220501.fc37.x86_64, build-id=71a04d23fd572525eb6efc47026c379725e06d96
                          Module bash from rpm bash-5.1.16-3.fc37.x86_64, build-id=6c936aff95a2ccda04a3fb685a81a84a0a8d10da
                          Stack trace of thread 235216:
                          #0  0x00007fa409ec8d8b kill (libc.so.6 + 0x38d8b)
                          #1  0x0000560d35e366b1 kill_builtin (bash + 0xad6b1)
                          #2  0x0000560d35dd7227 execute_builtin.lto_priv.0 (bash + 0x4e227)
                          #3  0x0000560d35dd0459 execute_simple_command (bash + 0x47459)
                          #4  0x0000560d35dd1de0 execute_command_internal (bash + 0x48de0)
                          #5  0x0000560d35e307aa parse_and_execute (bash + 0xa77aa)
                          #6  0x0000560d35e91b08 run_one_command.isra.0 (bash + 0x108b08)
                          #7  0x0000560d35dba07c main (bash + 0x3107c)
                          #8  0x00007fa409eb3510 __libc_start_call_main (libc.so.6 + 0x23510)
                          #9  0x00007fa409eb35c9 __libc_start_main@@GLIBC_2.34 (libc.so.6 + 0x235c9)
                          #10 0x0000560d35dbad85 _start (bash + 0x31d85)
2022-09-28 10:47:42 +02:00
Zbigniew Jędrzejewski-Szmek 87707784c7 coredump: when parsing json, optionally copy the string first 2022-09-28 09:38:13 +02:00
David Tardon 995340074e tree-wide: use ASSERT_PTR more 2022-09-13 08:13:27 +02:00
Daan De Meyer ee48779e05 shared: Add more dlopen() tests
Add dlopen_dw(), dlopen_elf() and dlopen_pcre2() to the dlopen test.
To enable adding dlopen_pcre2(), we move pcre2-dlopen.h/c from
src/journal to src/shared.
2022-03-01 21:07:17 +00:00
Yu Watanabe 80b241f2ec elf-util: add missing assertion 2022-01-04 04:27:11 +09:00
Yu Watanabe fe8fdc4760 elf-util: reduce variable scope 2022-01-04 04:27:11 +09:00
Yu Watanabe d090049c01 elf-util: executable argument for parse_elf() may be NULL
Fixes assertion triggered by parse_package_metadata() and json_build().
2022-01-04 04:27:09 +09:00
Yu Watanabe 3876cfafd0 elf-util: reduce variable scope and indentation 2022-01-04 04:11:55 +09:00