Skip to content

Conversation

@keszybz
Copy link
Member

@keszybz keszybz commented Jun 22, 2020

No description provided.

keszybz added 8 commits June 22, 2020 16:32
It's such a common operation to allocate the set and put an item in it,
that it deserves a helper. set_ensure_put() has the same return values
as set_put().

Comes with tests!
Patch contains a coccinelle script, but it only works in some cases. Many
parts were converted by hand.

Note: I did not fix errors in return value handing. This will be done separate
to keep the patch comprehensible. No functional change is intended in this
patch.
We would say "ignoring", but invalidate the peer anyway.
Let's only do that if we modified the peer irreperably.

Also add comments explaining allocation handling.
…tches

AddressSanitizer:DEADLYSIGNAL
=================================================================
==12==ERROR: AddressSanitizer: ABRT on unknown address 0x00000000000c (pc 0x7f0a518b3428 bp 0x7fffa463bfd0 sp 0x7fffa463be68 T0)
SCARINESS: 10 (signal)
    #0 0x7f0a518b3428 in raise (/lib/x86_64-linux-gnu/libc.so.6+0x35428)
    #1 0x7f0a518b5029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029)
    #2 0x7f0a52ca635a in log_assert_failed_realm /work/build/../../src/systemd/src/basic/log.c:819:9
    #3 0x4eea92 in config_parse_wireguard_endpoint /work/build/../../src/systemd/src/network/netdev/wireguard.c:808:9
    #4 0x7f0a52b2f74e in next_assignment /work/build/../../src/systemd/src/shared/conf-parser.c:133:32
    #5 0x7f0a52b2954e in parse_line /work/build/../../src/systemd/src/shared/conf-parser.c:242:16
    #6 0x7f0a52b28911 in config_parse /work/build/../../src/systemd/src/shared/conf-parser.c:377:21
    #7 0x7f0a52b29ec6 in config_parse_many_files /work/build/../../src/systemd/src/shared/conf-parser.c:439:21
    #8 0x7f0a52b2a5a6 in config_parse_many /work/build/../../src/systemd/src/shared/conf-parser.c:507:16
    #9 0x4d8d6c in netdev_load_one /work/build/../../src/systemd/src/network/netdev/netdev.c:732:13
    #10 0x4d3e2b in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/network/fuzz-netdev-parser.c:23:16
    #11 0x6b3266 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:558:15
    #12 0x6af860 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:470:3
    #13 0x6b6970 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:770:7
    #14 0x6b7376 in fuzzer::Fuzzer::Loop(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:799:3
    #15 0x67573f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:846:6
    #16 0x667097 in main /src/libfuzzer/FuzzerMain.cpp:19:10
    #17 0x7f0a5189e82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #18 0x4295a8 in _start (out/fuzz-netdev-parser+0x4295a8)

DEDUP_TOKEN: raise--abort--log_assert_failed_realm
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: ABRT (/lib/x86_64-linux-gnu/libc.so.6+0x35428) in raise
==12==ABORTING
This version is more efficient, which doesn't matter, but it allows us
to remove a bunch of error handling, which is always nice.
set_put()/set_ensure_put() return 0, not -EEXIST, if the entry is already
found in the set. In this case this does not make any difference, but let's
not confuse the reader.
@keszybz
Copy link
Member Author

keszybz commented Jun 22, 2020

Updated with a fix for the issue found by @qhill and two failures found by CI (with test case for one of them).

keszybz added 12 commits June 24, 2020 10:38
This combines set_ensure_allocated() with set_consume(). The cool thing is that
because we know the hash ops, we can correctly free the item if appropriate.
Similarly to set_consume(), the goal is to simplify handling of the case where
the item needs to be freed on error and if already present in the set.
…ery()

Old code was correct, but let's make things more explicit.
_cleanup_set_free_ is enough for unit_files, because unit_files is
allocated in set_put_strdup(), which uses string_hash_ops_free.

This fixes a leak if marker was already present in the table.
… the set

I'm not sure if it is actually possible to encounter this condition. But
let's make the handling correct regardless.
On error, we'd just free the object, and not close the fd.

While at it, let's use set_ensure_consume() to make sure we don't leak
the object if it was already in the set. I'm not sure if that condition
can be achieved.
I'm not sure if I understand the code correctly, but it seems that if
storig in the second set failed, we'd return with the first set having
no reference on the link object, and the link object could be freed in the
future, leaving the set with a dangling reference.
Also use double space before the tracking args at the end. Without
the comma this looks ugly, but it's a bit better with the double space.
At least it doesn't look like a variable with a type.
@keszybz keszybz force-pushed the set-handling-more branch from 2d41c31 to e198eba Compare June 24, 2020 08:39
@keszybz
Copy link
Member Author

keszybz commented Jun 24, 2020

set_ensure_consume() was busted. I was even failing under valgrind the test I added in the patch. Somehow I managed to miss that ;(

for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {

STRV_FOREACH(p, sysvrcnd_path)
for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably be size_t as ELEMENTOFS() reurns size_t

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a static table with 4 elements, u8 would suffice ;) I don't think it's worth spinning up the CI for this...

}

for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


finish:
for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@keszybz
Copy link
Member Author

keszybz commented Jun 24, 2020

bionic-amd64 timed out, but I don't quite see why. I'll assume this is unrelated.

@keszybz keszybz merged commit f83803a into systemd:master Jun 24, 2020
@keszybz keszybz deleted the set-handling-more branch June 24, 2020 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants