Around line 116, if n->flag is true then n->u.key and n->val are freed. However, since the memory allocated at line 110 was not initialized, n may contain any kind of data, which may unpredictably cause n->flag to have a nonzero value. When it does, a segfault occurs during free(n->u.key) or free(n->val).
Valgrind detects this issue as a conditional jump based on an uninitialized value. (Note that because the initial elements of the xht_t.zen member are zeroed during allocation via calloc, a hash collision must be created before this behavior can be witnessed. With a prime value of 11, hash keys "server" and "version9" produce the necessary collision. Of course, while this is enough to detect the issue under valgrind, it is not enough to actually trigger the segfault every time because that depends on the random bits in the memory that was allocated.)
This pull request resolves the issue by zeroing n after its memory is allocated.
In
libmdnsd/xht.c
, at line 110, if a candidate node is not found, a new one is allocated.Around line 116, if
n->flag
is true thenn->u.key
andn->val
are freed. However, since the memory allocated at line 110 was not initialized,n
may contain any kind of data, which may unpredictably causen->flag
to have a nonzero value. When it does, a segfault occurs duringfree(n->u.key)
orfree(n->val)
.Valgrind detects this issue as a conditional jump based on an uninitialized value. (Note that because the initial elements of the
xht_t.zen
member are zeroed during allocation viacalloc
, a hash collision must be created before this behavior can be witnessed. With aprime
value of11
, hash keys"server"
and"version9"
produce the necessary collision. Of course, while this is enough to detect the issue under valgrind, it is not enough to actually trigger the segfault every time because that depends on the random bits in the memory that was allocated.)This pull request resolves the issue by zeroing
n
after its memory is allocated.