-
Notifications
You must be signed in to change notification settings - Fork 0
[WIP] nspawn: Add --system-call-filter option #1
Conversation
src/nspawn/nspawn-seccomp.c
Outdated
| .help = "System calls filter for systemd-nspawn", | ||
| .value = | ||
| "_sysctl\0" | ||
| "add_key" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the \0? I wonder why it's there for _sysctl but not for the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My fault, I need to add \0 everywhere, as it separates syscalls in filter, like here https://github.com/systemd/systemd/blob/master/src/shared/seccomp-util.c#L267-L647
src/nspawn/nspawn-seccomp.h
Outdated
| SyscallFilterSet filter; | ||
| int capability; | ||
| } SyscallFilterSetCap; | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to have the typedef SyscallFilterSetCap inside the "#ifdef"?
I am not quite sure about systemd, but in the Linux kernel header files, they try to have the definitions being defined both in #ifdef block and the #else block, sometimes with dummy struct/functions definitions for the #else block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
example of dummy function from http://www.linuxjournal.com/node/5780/print :
#if ENABLE_BLAAH
#define blaah(x) if(x) printf("blaah %d\n",x)
#else
#define blaah(x) do { } while(0)
#endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I thought that seccomp-util.h can be included only when having seccomp headers, but that's not true, so I removed it. Thanks for pointing out.
f7bddac to
c5face9
Compare
c5face9 to
32e96f0
Compare
The --system-call-filter option allows to override the default seccomp filter with the list predefined by the user. Fixes systemd#5163
32e96f0 to
51a8791
Compare
We would only log a terse message when pid1 or systemd-journald crashed. It seems better to reuse the normal code paths as much as possible, with the following differences: - if pid1 crashes, we cannot launch the helper, so we don't analyze the coredump, just write it to file directly from the helper invoked by the kernel; - if journald crashes, we can produce the backtrace, but we don't log full structured messages. With comparison to previous code, advantages are: - we go through most of the steps, so for example vacuuming is performed, - we gather and log more data. In particular for journald and pid1 crashes we generate a backtrace, and for pid1 crashes we record the metadata (fdinfo, maps, etc.), - coredumpctl shows pid1 crashes. A disavantage (inefficiency) is that we gather metadata for journald crashes which is then ignored because _TRANSPORT=kernel does not support structued messages. Messages for the systemd-journald "crash" have _TRANSPORT=kernel, and _TRANSPORT=journal for the pid1 "crash". Feb 26 16:27:55 systemd[1]: systemd-journald.service: Main process exited, code=dumped, status=11/SEGV Feb 26 16:27:55 systemd[1]: systemd-journald.service: Unit entered failed state. Feb 26 16:37:54 systemd-coredump[18801]: Process 18729 (systemd-journal) of user 0 dumped core. Feb 26 16:37:54 systemd-coredump[18801]: Coredump diverted to /var/lib/systemd/coredump/core.systemd-journal.0.36c14bf3c6ce4c38914f441038990979.18729.1488145074000000.lz4 Feb 26 16:37:54 systemd-coredump[18801]: Stack trace of thread 18729: Feb 26 16:37:54 systemd-coredump[18801]: #0 0x00007f46d6a06b8d fsync (libpthread.so.0) Feb 26 16:37:54 systemd-coredump[18801]: #1 0x00007f46d71bfc47 journal_file_set_online (libsystemd-shared-233.so) Feb 26 16:37:54 systemd-coredump[18801]: #2 0x00007f46d71c1c31 journal_file_append_object (libsystemd-shared-233.so) Feb 26 16:37:54 systemd-coredump[18801]: #3 0x00007f46d71c3405 journal_file_append_data (libsystemd-shared-233.so) Feb 26 16:37:54 systemd-coredump[18801]: #4 0x00007f46d71c4b7c journal_file_append_entry (libsystemd-shared-233.so) Feb 26 16:37:54 systemd-coredump[18801]: #5 0x00005577688cf056 write_to_journal (systemd-journald) Feb 26 16:37:54 systemd-coredump[18801]: #6 0x00005577688d2e98 dispatch_message_real (systemd-journald) Feb 26 16:37:54 kernel: systemd-coredum: 9 output lines suppressed due to ratelimiting Feb 26 16:37:54 systemd-journald[18810]: Journal started Feb 26 16:50:59 systemd-coredump[19229]: Due to PID 1 having crashed coredump collection will now be turned off. Feb 26 16:51:00 systemd[1]: Caught <SEGV>, dumped core as pid 19228. Feb 26 16:51:00 systemd[1]: Freezing execution. Feb 26 16:51:00 systemd-coredump[19229]: Process 19228 (systemd) of user 0 dumped core. Stack trace of thread 19228: #0 0x00007fab82075c47 kill (libc.so.6) #1 0x000055fdf7c38b6b crash (systemd) #2 0x00007fab824175c0 __restore_rt (libpthread.so.0) #3 0x00007fab82148573 epoll_wait (libc.so.6) #4 0x00007fab8366f84a sd_event_wait (libsystemd-shared-233.so) #5 0x00007fab836701de sd_event_run (libsystemd-shared-233.so) #6 0x000055fdf7c4a380 manager_loop (systemd) #7 0x000055fdf7c402c2 main (systemd) systemd#8 0x00007fab82060401 __libc_start_main (libc.so.6) systemd#9 0x000055fdf7c3818a _start (systemd) Poor machine ;)
So don't even try to added the filter to reduce noise. The test is updated to skip calling _sysctl because the kernel prints an oops-like message that is confusing and unhelpful: Jul 15 21:07:01 rpi3 kernel: test-seccomp[8448]: syscall -10080 Jul 15 21:07:01 rpi3 kernel: Code: aa0503e4 aa0603e5 aa0703e6 d4000001 (b13ffc1f) Jul 15 21:07:01 rpi3 kernel: CPU: 3 PID: 8448 Comm: test-seccomp Tainted: G W 4.11.8-300.fc26.aarch64 #1 Jul 15 21:07:01 rpi3 kernel: Hardware name: raspberrypi rpi/rpi, BIOS 2017.05 06/24/2017 Jul 15 21:07:01 rpi3 kernel: task: ffff80002bb0bb00 task.stack: ffff800036354000 Jul 15 21:07:01 rpi3 kernel: PC is at 0xffff8669c7c4 Jul 15 21:07:01 rpi3 kernel: LR is at 0xaaaac64b6750 Jul 15 21:07:01 rpi3 kernel: pc : [<0000ffff8669c7c4>] lr : [<0000aaaac64b6750>] pstate: 60000000 Jul 15 21:07:01 rpi3 kernel: sp : 0000ffffdc640fd0 Jul 15 21:07:01 rpi3 kernel: x29: 0000ffffdc640fd0 x28: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x27: 0000000000000000 x26: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x25: 0000000000000000 x24: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x23: 0000000000000000 x22: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x21: 0000aaaac64b4940 x20: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x19: 0000aaaac64b88f8 x18: 0000000000000020 Jul 15 21:07:01 rpi3 kernel: x17: 0000ffff8669c7a0 x16: 0000aaaac64d2ee0 Jul 15 21:07:01 rpi3 kernel: x15: 0000000000000000 x14: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x13: 203a657275746365 x12: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x11: 0000ffffdc640418 x10: 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x9 : 0000000000000005 x8 : 00000000ffffd8a0 Jul 15 21:07:01 rpi3 kernel: x7 : 7f7f7f7f7f7f7f7f x6 : 7f7f7f7f7f7f7f7f Jul 15 21:07:01 rpi3 kernel: x5 : 65736d68716f7277 x4 : 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x3 : 0000000000000008 x2 : 0000000000000000 Jul 15 21:07:01 rpi3 kernel: x1 : 0000000000000000 x0 : 0000000000000000 Jul 15 21:07:01 rpi3 kernel: (cherry picked from commit 1e20e640132c700c23494bb9e2619afb83878380)
In general we'd leak anything that was allocated in the first parsing of
netdev, e.g. netdev name, host name, etc. Use normal netdev_unref to make sure
everything is freed.
--- command ---
/home/zbyszek/src/systemd/build2/test-network
--- stderr ---
/etc/systemd/network/wg0.netdev:3: Failed to parse netdev kind, ignoring: wireguard
/etc/systemd/network/wg0.netdev:5: Unknown section 'WireGuard'. Ignoring.
/etc/systemd/network/wg0.netdev:9: Unknown section 'WireGuardPeer'. Ignoring.
NetDev has no Kind configured in /etc/systemd/network/wg0.netdev. Ignoring
/etc/systemd/network/br0.network:13: Unknown lvalue 'NetDev' in section 'Network'
br0: netdev ready
=================================================================
==11666==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f3a314cf238 in __interceptor_strdup (/lib64/libasan.so.4+0x77238)
#1 0x7f3a30e71ad1 in free_and_strdup ../src/basic/string-util.c:870
#2 0x7f3a30d34fba in config_parse_ifname ../src/shared/conf-parser.c:981
#3 0x7f3a30d2f5b0 in next_assignment ../src/shared/conf-parser.c:155
#4 0x7f3a30d30303 in parse_line ../src/shared/conf-parser.c:273
#5 0x7f3a30d30dee in config_parse ../src/shared/conf-parser.c:390
#6 0x7f3a30d310a5 in config_parse_many_files ../src/shared/conf-parser.c:428
#7 0x7f3a30d3181c in config_parse_many ../src/shared/conf-parser.c:487
systemd#8 0x55b4200f9b00 in netdev_load_one ../src/network/netdev/netdev.c:634
systemd#9 0x55b4200fb562 in netdev_load ../src/network/netdev/netdev.c:778
systemd#10 0x55b4200c607a in manager_load_config ../src/network/networkd-manager.c:1299
systemd#11 0x55b4200818e0 in test_load_config ../src/network/test-network.c:128
systemd#12 0x55b42008343b in main ../src/network/test-network.c:254
systemd#13 0x7f3a305f8889 in __libc_start_main (/lib64/libc.so.6+0x20889)
SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).
-------
Early in journal_file_set_offline() f->header->state is tested to see if it's != STATE_ONLINE, and since there's no need to do anything if the journal isn't online, the function simply returned here. Since moving part of the offlining process to a separate thread, there are two problems here: 1. We can't simply check f->header->state, because if there is an offline thread active it may modify f->header->state. 2. Even if the journal is deemed offline, the thread responsible may still need joining, so a bare return may leak the thread's resources like its stack. To address #1, the helper journal_file_is_offlining() is called prior to accessing f->header->state. If journal_file_is_offlining() returns true, f->header->state isn't even checked, because an offlining journal is obviously online, and we'll just continue with the normal set offline code path. If journal_file_is_offlining() returns false, then it's safe to check f->header->state, because the offline_state is beyond the point of modifying f->header->state, and there's a memory barrier in the helper. If we find f->header->state is != STATE_ONLINE, then we call the idempotent journal_file_set_offline_thread_join() on the way out of the function, to join a potential lingering offline thread.
Early in journal_file_set_offline() f->header->state is tested to see if it's != STATE_ONLINE, and since there's no need to do anything if the journal isn't online, the function simply returned here. Since moving part of the offlining process to a separate thread, there are two problems here: 1. We can't simply check f->header->state, because if there is an offline thread active it may modify f->header->state. 2. Even if the journal is deemed offline, the thread responsible may still need joining, so a bare return may leak the thread's resources like its stack. To address #1, the helper journal_file_is_offlining() is called prior to accessing f->header->state. If journal_file_is_offlining() returns true, f->header->state isn't even checked, because an offlining journal is obviously online, and we'll just continue with the normal set offline code path. If journal_file_is_offlining() returns false, then it's safe to check f->header->state, because the offline_state is beyond the point of modifying f->header->state, and there's a memory barrier in the helper. If we find f->header->state is != STATE_ONLINE, then we call the idempotent journal_file_set_offline_thread_join() on the way out of the function, to join a potential lingering offline thread.
==14==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200055fa9c at pc 0x0000005458f1 bp 0x7ffc78940d90 sp 0x7ffc78940d88
READ of size 1 at 0x60200055fa9c thread T0
#0 0x5458f0 in dhcp6_option_parse_domainname /work/build/../../src/systemd/src/libsystemd-network/dhcp6-option.c:555:29
#1 0x54706e in dhcp6_lease_set_domains /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-lease.c:242:13
#2 0x53fce0 in client_parse_message /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:984:29
#3 0x53f3bc in client_receive_advertise /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:1083:13
#4 0x53d57f in client_receive_message /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:1182:21
#5 0x7f0f7159deee in source_dispatch /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3042:21
#6 0x7f0f7159d431 in sd_event_dispatch /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3455:21
#7 0x7f0f7159ea8d in sd_event_run /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3512:21
systemd#8 0x531f2b in fuzz_client /work/build/../../src/systemd/src/fuzz/fuzz-dhcp6-client.c:44:9
systemd#9 0x531bc1 in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-dhcp6-client.c:53:9
systemd#10 0x57bec8 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:570:15
systemd#11 0x579d67 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:479:3
systemd#12 0x57dc92 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:707:19
systemd#13 0x580ca6 in fuzzer::Fuzzer::Loop(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, fuzzer::fuzzer_allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) /src/libfuzzer/FuzzerLoop.cpp:838:5
systemd#14 0x55e968 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6
systemd#15 0x551a1c in main /src/libfuzzer/FuzzerMain.cpp:20:10
systemd#16 0x7f0f701a082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
systemd#17 0x41e928 in _start (/out/fuzz-dhcp6-client+0x41e928)
==14==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020001c761a at pc 0x000000540abc bp 0x7ffd0caf2c50 sp 0x7ffd0caf2c48
READ of size 2 at 0x6020001c761a thread T0
#0 0x540abb in client_parse_message /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:849:73
#1 0x53f3bc in client_receive_advertise /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:1083:13
#2 0x53d57f in client_receive_message /work/build/../../src/systemd/src/libsystemd-network/sd-dhcp6-client.c:1182:21
#3 0x7f71d8c3eeee in source_dispatch /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3042:21
#4 0x7f71d8c3e431 in sd_event_dispatch /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3455:21
#5 0x7f71d8c3fa8d in sd_event_run /work/build/../../src/systemd/src/libsystemd/sd-event/sd-event.c:3512:21
#6 0x531f2b in fuzz_client /work/build/../../src/systemd/src/fuzz/fuzz-dhcp6-client.c:44:9
#7 0x531bc1 in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-dhcp6-client.c:53:9
systemd#8 0x57bef8 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:570:15
systemd#9 0x579d97 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:479:3
systemd#10 0x57dcc2 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:707:19
systemd#11 0x580cd6 in fuzzer::Fuzzer::Loop(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, fuzzer::fuzzer_allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) /src/libfuzzer/FuzzerLoop.cpp:838:5
systemd#12 0x55e998 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6
systemd#13 0x551a4c in main /src/libfuzzer/FuzzerMain.cpp:20:10
systemd#14 0x7f71d784182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
systemd#15 0x41e928 in _start (/out/fuzz-dhcp6-client+0x41e928)
A couple of changes: 1. Clearly name the drop-in entry files "Type #1", and the unified kernel images "Type #2", and be clearer that the latter is specific to UEFI. 2. Suffix all directory paths with a trailing "/" to clarify that these are directories. Also, enclose them all in ``. 3. Add introductory paragraph that explains that there is Type #1 and Type #2 and what they are about. 4. Explain that Type #2 is about signed UEFI SecureBoot. 5. Don't claim that $BOOT/loader/ contains really all files defined by the spec, because that's not true, Type #2 images are not located there after all. Fixes: systemd#10399
This is useful for a couple of cases, I'm mostly interested in case #1: 1. Verifying "reasonable" values in a trivially scriptable way 2. Debugging unexpected time span parsing directly Test Plan: ``` % build/systemd-analyze timespan 20 Original: 20 μs: 20 Human: 20us % build/systemd-analyze timespan 20ms Original: 20ms μs: 20000 Human: 20ms % build/systemd-analyze timespan 20z Failed to parse time span '20z': Invalid argument ```
This is a follow-up to 8857fb9 that prevents the fuzzer from crashing with ``` ==220==ERROR: AddressSanitizer: ABRT on unknown address 0x0000000000dc (pc 0x7ff4953c8428 bp 0x7ffcf66ec290 sp 0x7ffcf66ec128 T0) SCARINESS: 10 (signal) #0 0x7ff4953c8427 in gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35427) #1 0x7ff4953ca029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029) #2 0x7ff49666503a in log_assert_failed_realm /work/build/../../src/systemd/src/basic/log.c:805:9 #3 0x7ff496614ecf in safe_close /work/build/../../src/systemd/src/basic/fd-util.c:66:17 #4 0x548806 in server_done /work/build/../../src/systemd/src/journal/journald-server.c:2064:9 #5 0x5349fa in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-journald-kmsg.c:26:9 #6 0x592755 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:571:15 #7 0x590627 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:480:3 systemd#8 0x594432 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:708:19 systemd#9 0x5973c6 in fuzzer::Fuzzer::Loop(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, fuzzer::fuzzer_allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) /src/libfuzzer/FuzzerLoop.cpp:839:5 systemd#10 0x574541 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6 systemd#11 0x5675fc in main /src/libfuzzer/FuzzerMain.cpp:20:10 systemd#12 0x7ff4953b382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) systemd#13 0x420f58 in _start (/out/fuzz-journald-kmsg+0x420f58) ```
Fix a bug when activating netlink
Fixes: oss-fuzz#22208 ``` test/fuzz/fuzz-calendarspec/oss-fuzz-22208... ../src/shared/calendarspec.c:666:48: runtime error: signed integer overflow: 2147000000 + 1000000 cannot be represented in type 'int' #0 0x7f0b9f6cc56a in prepend_component ../src/shared/calendarspec.c:666 #1 0x7f0b9f6cd03a in parse_chain ../src/shared/calendarspec.c:718 #2 0x7f0b9f6cea1c in parse_calendar_time ../src/shared/calendarspec.c:845 #3 0x7f0b9f6d1397 in calendar_spec_from_string ../src/shared/calendarspec.c:1084 #4 0x401570 in LLVMFuzzerTestOneInput ../src/fuzz/fuzz-calendarspec.c:17 #5 0x401ae0 in main ../src/fuzz/fuzz-main.c:39 #6 0x7f0b9e31b1a2 in __libc_start_main (/lib64/libc.so.6+0x271a2) #7 0x40122d in _start (/home/fsumsal/repos/systemd/build/fuzz-calendarspec+0x40122d) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../src/shared/calendarspec.c:666:48 in ``` (cherry picked from commit c07f18f)
We'd try to map a zero-byte buffer from a NULL pointer, which is undefined behaviour.
src/systemd/src/libsystemd/sd-bus/bus-message.c:3161:60: runtime error: applying zero offset to null pointer
#0 0x7f6ff064e691 in find_part /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3161:60
#1 0x7f6ff0640788 in message_peek_body /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3283:16
#2 0x7f6ff064e8db in enter_struct_or_dict_entry /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3967:21
#3 0x7f6ff06444ac in bus_message_enter_struct /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:4009:13
#4 0x7f6ff0641dde in sd_bus_message_enter_container /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:4136:21
#5 0x7f6ff0619874 in sd_bus_message_dump /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-dump.c:178:29
#6 0x4293d9 in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-bus-message.c:39:9
#7 0x441986 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:558:15
systemd#8 0x44121e in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:470:3
systemd#9 0x443164 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:770:7
systemd#10 0x4434bc in fuzzer::Fuzzer::Loop(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:799:3
systemd#11 0x42d2bc in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:846:6
systemd#12 0x42978a in main /src/libfuzzer/FuzzerMain.cpp:19:10
systemd#13 0x7f6fef13c82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
systemd#14 0x407808 in _start (out/fuzz-bus-message+0x407808)
(cherry picked from commit b17af3e)
We'd try to map a zero-byte buffer from a NULL pointer, which is undefined behaviour.
src/systemd/src/libsystemd/sd-bus/bus-message.c:3161:60: runtime error: applying zero offset to null pointer
#0 0x7f6ff064e691 in find_part /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3161:60
#1 0x7f6ff0640788 in message_peek_body /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3283:16
#2 0x7f6ff064e8db in enter_struct_or_dict_entry /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:3967:21
#3 0x7f6ff06444ac in bus_message_enter_struct /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:4009:13
#4 0x7f6ff0641dde in sd_bus_message_enter_container /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-message.c:4136:21
#5 0x7f6ff0619874 in sd_bus_message_dump /work/build/../../src/systemd/src/libsystemd/sd-bus/bus-dump.c:178:29
#6 0x4293d9 in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-bus-message.c:39:9
#7 0x441986 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:558:15
systemd#8 0x44121e in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:470:3
systemd#9 0x443164 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:770:7
systemd#10 0x4434bc in fuzzer::Fuzzer::Loop(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:799:3
systemd#11 0x42d2bc in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:846:6
systemd#12 0x42978a in main /src/libfuzzer/FuzzerMain.cpp:19:10
systemd#13 0x7f6fef13c82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
systemd#14 0x407808 in _start (out/fuzz-bus-message+0x407808)
(cherry picked from commit b17af3e)
```
p11-kit-0.23.20-1.fc32.x86_64 pam-1.3.1-26.fc33.x86_64 xz-libs-5.2.5-1.fc33.x86_64 zlib-1.2.11-21.fc32.x86_64
(gdb) bt
lvalue=0x560e10 "SendOption", ltype=2, rvalue=0x560e1b "11:string", data=0x561e20, userdata=0x561cd0) at ../src/network/networkd-dhcp-common.c:580
table=0x4392e0 <network_network_gperf_lookup>, section=0x560ef0 "DHCPv4", section_line=14, lvalue=0x560e10 "SendOption", rvalue=0x560e1b "11:string", flags=CONFIG_PARSE_WARN,
userdata=0x561cd0) at ../src/shared/conf-parser.c:132
lookup=0x7ffff7d2f76d <config_item_perf_lookup>, table=0x4392e0 <network_network_gperf_lookup>, flags=CONFIG_PARSE_WARN, section=0x7fffffffc9f8, section_line=0x7fffffffc9a0,
section_ignored=0x7fffffffc99d, l=0x560e10 "SendOption", userdata=0x561cd0) at ../src/shared/conf-parser.c:270
lookup=0x7ffff7d2f76d <config_item_perf_lookup>, table=0x4392e0 <network_network_gperf_lookup>, flags=CONFIG_PARSE_WARN, userdata=0x561cd0) at ../src/shared/conf-parser.c:395
lookup=0x7ffff7d2f76d <config_item_perf_lookup>, table=0x4392e0 <network_network_gperf_lookup>, flags=CONFIG_PARSE_WARN, userdata=0x561cd0) at ../src/shared/conf-parser.c:452
dropin_dirname=0x7fffffffcbd0 "veth99.network.d", sections=0x4f3a18 "Match", lookup=0x7ffff7d2f76d <config_item_perf_lookup>, table=0x4392e0 <network_network_gperf_lookup>,
flags=CONFIG_PARSE_WARN, userdata=0x561cd0) at ../src/shared/conf-parser.c:511
(gdb) q
A debugging session is active.
Inferior 1 [process 118718] will be killed.
```
```
$ printf '[DHCPv4]\nSendOption=1:uint8' >crash
$ ./out/fuzz-network-parser ./crash
INFO: Seed: 1158717610
INFO: Loaded 2 modules (199728 inline 8-bit counters): 136668 [0x7faf3e91a930, 0x7faf3e93bf0c), 63060 [0xadf190, 0xaee7e4),
INFO: Loaded 2 PC tables (199728 PCs): 136668 [0x7faf3e93bf10,0x7faf3eb51cd0), 63060 [0xaee7e8,0xbe4d28),
./out/fuzz-network-parser: Running 1 inputs 1 time(s) each.
Running: ./crash
Assertion 's' failed at src/basic/parse-util.c:458, function int safe_atou8(const char *, uint8_t *)(). Aborting.
==5588== ERROR: libFuzzer: deadly signal
#0 0x51811e in __sanitizer_print_stack_trace (/home/vagrant/systemd/out/fuzz-network-parser+0x51811e)
#1 0x46b921 in fuzzer::PrintStackTrace() (/home/vagrant/systemd/out/fuzz-network-parser+0x46b921)
#2 0x44ded6 in fuzzer::Fuzzer::CrashCallback() (.part.0) (/home/vagrant/systemd/out/fuzz-network-parser+0x44ded6)
#3 0x44df9d in fuzzer::Fuzzer::StaticCrashSignalCallback() (/home/vagrant/systemd/out/fuzz-network-parser+0x44df9d)
#4 0x7faf3d6d7b1f (/lib64/libpthread.so.0+0x14b1f)
#5 0x7faf3d3c2624 in raise (/lib64/libc.so.6+0x3c624)
#6 0x7faf3d3ab8d8 in abort (/lib64/libc.so.6+0x258d8)
#7 0x7faf3e12593a in log_assert_failed_realm /home/vagrant/systemd/build/../src/basic/log.c:819:9
systemd#8 0x7faf3e140ce1 in safe_atou8 /home/vagrant/systemd/build/../src/basic/parse-util.c:458:9
systemd#9 0x68089c in config_parse_dhcp_send_option /home/vagrant/systemd/build/../src/network/networkd-dhcp-common.c:517:21
systemd#10 0x7faf3debed4e in next_assignment /home/vagrant/systemd/build/../src/shared/conf-parser.c:132:32
systemd#11 0x7faf3deb7783 in parse_line /home/vagrant/systemd/build/../src/shared/conf-parser.c:270:16
systemd#12 0x7faf3deb606c in config_parse /home/vagrant/systemd/build/../src/shared/conf-parser.c:395:21
systemd#13 0x7faf3deb85ee in config_parse_many_files /home/vagrant/systemd/build/../src/shared/conf-parser.c:452:21
systemd#14 0x7faf3deb8c57 in config_parse_many /home/vagrant/systemd/build/../src/shared/conf-parser.c:511:16
systemd#15 0x57c2eb in network_load_one /home/vagrant/systemd/build/../src/network/networkd-network.c:470:13
systemd#16 0x543490 in LLVMFuzzerTestOneInput /home/vagrant/systemd/build/../src/network/fuzz-network-parser.c:26:16
systemd#17 0x44e3e8 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/home/vagrant/systemd/out/fuzz-network-parser+0x44e3e8)
systemd#18 0x433505 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/home/vagrant/systemd/out/fuzz-network-parser+0x433505)
systemd#19 0x43c449 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/home/vagrant/systemd/out/fuzz-network-parser+0x43c449)
systemd#20 0x42c4a6 in main (/home/vagrant/systemd/out/fuzz-network-parser+0x42c4a6)
systemd#21 0x7faf3d3ad1a2 in __libc_start_main (/lib64/libc.so.6+0x271a2)
systemd#22 0x42c4fd in _start (/home/vagrant/systemd/out/fuzz-network-parser+0x42c4fd)
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
```
(cherry picked from commit 1eb7342)
"Linux" conflicts /efi/Linux when /efi is the install location. /efi/Linux is already reserved for unified kernel images so we can't use it for type #1 images. Instead, we use "Default".
This lets the libc/xcrypt allocate as much storage area as it needs. Should fix systemd#16965: testsuite-46.sh[74]: ==74==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f3e972e1080 at pc 0x7f3e9be8deed bp 0x7ffce4f28530 sp 0x7ffce4f27ce0 testsuite-46.sh[74]: WRITE of size 131232 at 0x7f3e972e1080 thread T0 testsuite-46.sh[74]: #0 0x7f3e9be8deec (/usr/lib/clang/10.0.1/lib/linux/libclang_rt.asan-x86_64.so+0x9feec) testsuite-46.sh[74]: #1 0x559cd05a6412 in user_record_make_hashed_password /systemd-meson-build/../build/src/home/user-record-util.c:818:21 testsuite-46.sh[74]: #2 0x559cd058fb03 in create_home /systemd-meson-build/../build/src/home/homectl.c:1112:29 testsuite-46.sh[74]: #3 0x7f3e9b5b3058 in dispatch_verb /systemd-meson-build/../build/src/shared/verbs.c:103:24 testsuite-46.sh[74]: #4 0x559cd058c101 in run /systemd-meson-build/../build/src/home/homectl.c:3325:16 testsuite-46.sh[74]: #5 0x559cd058c00a in main /systemd-meson-build/../build/src/home/homectl.c:3328:1 testsuite-46.sh[74]: #6 0x7f3e9a88b151 in __libc_start_main (/usr/lib/libc.so.6+0x28151) testsuite-46.sh[74]: #7 0x559cd0583e7d in _start (/usr/bin/homectl+0x24e7d) testsuite-46.sh[74]: Address 0x7f3e972e1080 is located in stack of thread T0 at offset 32896 in frame testsuite-46.sh[74]: #0 0x559cd05a60df in user_record_make_hashed_password /systemd-meson-build/../build/src/home/user-record-util.c:789 testsuite-46.sh[74]: This frame has 6 object(s): testsuite-46.sh[74]: [32, 40) 'priv' (line 790) testsuite-46.sh[74]: [64, 72) 'np' (line 791) testsuite-46.sh[74]: [96, 104) 'salt' (line 809) testsuite-46.sh[74]: [128, 32896) 'cd' (line 810) testsuite-46.sh[74]: [33152, 33168) '.compoundliteral' <== Memory access at offset 32896 partially underflows this variable testsuite-46.sh[74]: [33184, 33192) 'new_array' (line 832) <== Memory access at offset 32896 partially underflows this variable testsuite-46.sh[74]: HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork testsuite-46.sh[74]: (longjmp and C++ exceptions *are* supported) testsuite-46.sh[74]: SUMMARY: AddressSanitizer: stack-buffer-overflow (/usr/lib/clang/10.0.1/lib/linux/libclang_rt.asan-x86_64.so+0x9feec) It seems 'struct crypt_data' is 32896 bytes, but libclang_rt wants more, at least 33168?
Coverity says: CID 1446387 (#1 of 1): Bad bit shift operation (BAD_SHIFT) 8. negative_shift: In expression 1U << (int)cmd, shifting by a negative amount has undefined behavior. The shift amount, cmd, is -22. I don't think there's any issue, unless we forget to set token->data appropriately. Let's add an assert.
The current pattern '#' triggers on the openSUSE kernel version that is printed early during boot when no actual prompt is ready > [ 0.000000] Linux version 5.12.10-1-default (geeko@buildhost) (gcc (SUSE Linux) 11.1.1 20210510 [revision 23855a176609fe8dda6abaf2b21846b4517966eb], GNU ld (GNU Binutils; openSUSE Tumbleweed) 2.36.1.20210326-4) #1 SMP Fri Jun 11 05:05:06 UTC 2021 (b92eaf7) Instead wait for pattern that: a) should have fewer false positives, b) still be with working on distro shells: openSUSE (red color) ^[[1m^[[31mimage:~ #^[[m^O arch [root@image ~]# debian root@image:~# ubuntu root@image:~# fedora [root@image ~]#
When exiting PID 1 we most likely don't have stdio/stdout open, so the final LSan check would not print any actionable information and would just crash PID 1 leading up to a kernel panic, which is a bit annoying. Let's instead attempt to open /dev/console, and if we succeed redirect LSan's report there. The result is a bit messy, as it's slightly interleaved with the kernel panic, but it's definitely better than not having the stack trace at all: [ OK ] Reached target final.target. [ OK ] Finished systemd-poweroff.service. [ OK ] Reached target poweroff.target. ================================================================= 3 1m 43.251782] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 [ 43.252838] CPU: 2 PID: 1 Comm: systemd Not tainted 6.4.12-200.fc38.x86_64 #1 ==[1==ERR O R :4 3Le.a2k53562] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-1.fc38 04/01/2014 [ 43.254683] Call Trace: [ 43.254911] <TASK> [ 43.255107] dump_stack_lvl+0x47/0x60 S[ a 43.n2555i05] panic+t0x192/0x350 izer[ :43.255966 ] do_exit+0x990/0xdb10 etec[ 43.256504] do_group_exit+0x31/0x80 [ 43.256889] __x64_sys_exit_group+0x18/0x20 [ 43.257288] do_syscall_64+0x60/0x90 o_user_mod leaks[ 43.257618] ? syscall_exit_t +0x2b/0x40 [ 43.258411] ? do_syscall_64+0x6c/0x90 1mDirect le[ 43.258755] ak of 21 byte(s)? exc_page_fault+0x7f/0x180 [ 43.259446] entry_SYSCALL_64_after_hwframe+0x72/0xdc [ 43.259901] RiIP: 0033:0x7f357nb8f3ad4 1 objec[ 43.260354] Ctode: 48 89 (f7 0f 05 c3 sf3 0f 1e fa b8 3b 00 00 00) 0f 05 c3 0f 1f 4 0 00 f3 0f 1e fa 50 58 b8 e7 00 00 00 48 83 ec 08 48 63 ff 0f 051 [ 43.262581] RSP: 002b:00007ffc25872440 EFLAGS: 00000202 ORIG_RAX: 00000000000000e7 a RBX: 00007f357be9b218 RCX: 00007f357b8f3ad4m:ffd [ 43.264512] RDX: 0000000000000001 RSI: 00007f357b933b63 RDI: 0000000000000001 [ 43.265355] RBP: 00007f357be9b218 R08: efffffffffffffff R09: 00007ffc258721ef [ 43.266191] R10: 000000000000003f R11: 0000000000000202 R12: 00000fe6ae9e0000 [ 43.266891] R13: 00007f3574f00000 R14: 0000000000000000 R15: 0000000000000007 [ 43.267517] </TASK> #0 0x7f357b8814a8 in strdup (/lib64/libasan.so.8+0x814a8) (BuildId: e5f0a0d511a659fbc47bf41072869139cb2db47f) #1 0x7f3578d43317 in cg_path_decode_unit ../src/basic/cgroup-util.c:1132 #2 0x7f3578d43936 in cg_path_get_unit ../src/basic/cgroup-util.c:1190 #3 0x7f3578d440f6 in cg_pid_get_unit ../src/basic/cgroup-util.c:1234 #4 0x7f35789263d7 in bus_log_caller ../src/shared/bus-util.c:734 #5 0x7f357a9cf10a in method_reload ../src/core/dbus-manager.c:1621 #6 0x7f3578f77497 in method_callbacks_run ../src/libsystemd/sd-bus/bus-objects.c:406 #7 0x7f3578f80dd8 in object_find_and_run ../src/libsystemd/sd-bus/bus-objects.c:1319 systemd#8 0x7f3578f82487 in bus_process_object ../src/libsystemd/sd-bus/bus-objects.c:1439 systemd#9 0x7f3578fe41f1 in process_message ../src/libsystemd/sd-bus/sd-bus.c:3007 systemd#10 0x7f3578fe477b in process_running ../src/libsystemd/sd-bus/sd-bus.c:3049 systemd#11 0x7f3578fe75d1 in bus_process_internal ../src/libsystemd/sd-bus/sd-bus.c:3269 systemd#12 0x7f3578fe776e in sd_bus_process ../src/libsystemd/sd-bus/sd-bus.c:3296 systemd#13 0x7f3578feaedc in io_callback ../src/libsystemd/sd-bus/sd-bus.c:3638 systemd#14 0x7f35791c2f68 in source_dispatch ../src/libsystemd/sd-event/sd-event.c:4187 systemd#15 0x7f35791cc6f9 in sd_event_dispatch ../src/libsystemd/sd-event/sd-event.c:4808 systemd#16 0x7f35791cd830 in sd_event_run ../src/libsystemd/sd-event/sd-event.c:4869 systemd#17 0x7f357abcd572 in manager_loop ../src/core/manager.c:3244 systemd#18 0x41db21 in invoke_main_loop ../src/core/main.c:1960 systemd#19 0x426615 in main ../src/core/main.c:3125 systemd#20 0x7f3577c49b49 in __libc_start_call_main (/lib64/libc.so.6+0x27b49) (BuildId: 245240a31888ad5c11bbc55b18e02d87388f59a9) systemd#21 0x7f3577c49c0a in __libc_start_main_alias_2 (/lib64/libc.so.6+0x27c0a) (BuildId: 245240a31888ad5c11bbc55b18e02d87388f59a9) systemd#22 0x408494 in _start (/usr/lib/systemd/systemd+0x408494) (BuildId: fe61e1b0f00b6a36aa34e707a98c15c52f6b960a) SUMMARY: AddressSanitizer: 21 byte(s) leaked in 1 allocation(s). [ 43.295912] Kernel Offset: 0x7000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 43.297036] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 ]--- Originally noticed in systemd#28579.
Just showing my idea and progress, not ready for submitting upstream yet.
The --system-call-filter option allows to override the default
seccomp filter with the list predefined by the user.
Fixes systemd#5163