systemctl: unset const char* arguments in static destructors
When fuzzing, the following happens: - we parse 'data' and produce an argv array, - one of the items in argv is assigned to arg_host, - the argv array is subsequently freed by strv_freep(), and arg_host has a dangling symlink. In normal use, argv is static, so arg_host can never become a dangling pointer. In fuzz-systemctl-parse-argv, if we repeatedly parse the same array, we have some dangling pointers while we're in the middle of parsing. If we parse the same array a second time, at the end all the dangling pointers will have been replaced again. But for a short time, if parsing one of the arguments uses another argument, we would use a dangling pointer. Such a case occurs when we have --host=… --boot-loader-entry=help. The latter calls acquire_bus() which uses arg_host. I'm not particularly happy with making the code more complicated just for fuzzing, but I think it's better to resolve this, even if the issue cannot occur in normal invocations, than to deal with fuzzer reports. Should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=31714.
This commit is contained in:
@@ -79,6 +79,13 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
|
||||
memcpy_safe(_q_, p, _l_); \
|
||||
})
|
||||
|
||||
static inline void unsetp(void *p) {
|
||||
/* A trivial "destructor" that can be used in cases where we want to
|
||||
* unset a pointer from a _cleanup_ function. */
|
||||
|
||||
*(void**)p = NULL;
|
||||
}
|
||||
|
||||
static inline void freep(void *p) {
|
||||
*(void**)p = mfree(*(void**) p);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user