Fix handling of cases where a duplicate item is added to a set and related cleanups#16238
Merged
keszybz merged 20 commits intosystemd:masterfrom Jun 24, 2020
Merged
Fix handling of cases where a duplicate item is added to a set and related cleanups#16238keszybz merged 20 commits intosystemd:masterfrom
keszybz merged 20 commits intosystemd:masterfrom
Conversation
qhill
reviewed
Jun 22, 2020
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.
d6479b4 to
2d41c31
Compare
Member
Author
|
Updated with a fix for the issue found by @qhill and two failures found by CI (with test case for one of them). |
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.
No funtional change.
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.
2d41c31 to
e198eba
Compare
Member
Author
|
set_ensure_consume() was busted. I was even failing under valgrind the test I added in the patch. Somehow I managed to miss that ;( |
poettering
approved these changes
Jun 24, 2020
| for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) { | ||
|
|
||
| STRV_FOREACH(p, sysvrcnd_path) | ||
| for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i ++) { |
Member
There was a problem hiding this comment.
should probably be size_t as ELEMENTOFS() reurns size_t
Member
Author
There was a problem hiding this comment.
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++) |
|
|
||
| finish: | ||
| for (i = 0; i < ELEMENTSOF(rcnd_table); i++) | ||
| for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++) |
Member
Author
|
bionic-amd64 timed out, but I don't quite see why. I'll assume this is unrelated. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.