mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-10-26 12:24:42 +00:00
Fix DNSSEC frec use-after-free in TCP validation path.
Full credit to Jerry Tom <goonsomeway@gmail.com> for finding this. When DNSSEC validation falls back to TCP (via a forked child process), the parent uses a uid-based check to detect whether a frec has been freed and reused before the child returns. It doesn't, however check for the more likely scenario which is that the frec has simply been freed via the timeout path in get_new_frec(). This leads to a use-after-free on an already freed frec.
This commit is contained in:
1 file changed
+6
-4
+6
-4
@@ -1091,10 +1091,12 @@ int cache_recv_insert(time_t now, int fd)
|
||||
if (op == PIPE_OP_KILLED)
|
||||
my_syslog(LOG_INFO, _("TCP process for DNSSEC validation timed out"));
|
||||
|
||||
/* There's a tiny chance that the frec may have been freed
|
||||
and reused before the TCP process returns. Detect that with
|
||||
the uid field which is unique modulo 2^32 for each use. */
|
||||
if (uid == forward->uid)
|
||||
/* There's a chance that the frec may have timed-out and been
|
||||
freed before the TCP process returns, so check that the
|
||||
frec is still marked in use. Even if it is in use, there's a tiny chance
|
||||
that the frec may have been freed and _reused_ before the TCP process returns.
|
||||
Detect that with the uid field which is unique modulo 2^32 for each use. */
|
||||
if (forward->sentto && uid == forward->uid)
|
||||
{
|
||||
if (op == PIPE_OP_RESULT)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user