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:
Simon Kelley committed 2026-05-29 17:24:54 +01:00
1 parent 0375e40824
commit 77d4749a5e
1 file changed
+6 -4
+6 -4
View File
@@ -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)
{