-
Notifications
You must be signed in to change notification settings - Fork 906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dnsdist: Fix a double-free when a DoH cross-protocol response is dropped #11075
dnsdist: Fix a double-free when a DoH cross-protocol response is dropped #11075
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks good.
I checked the places where DoHTCPCrossQuerySender
and DoHCrossProtocolQuery
objects are used, and noted one spot where an DoHTCPCrossQuerySender
object is first created and then the get()
is done: line 1328. I do not think it is wrong, but the pattern looked strange to me.
Thanks Otto! I'll review all the places where we touch the reference counter to check that we are doing the right thing. I'll also check one more time if we cannot use a smart pointer instead but h2o's API make that hard, if not impossible. |
It was indeed leaking when a UDP response to a DoH query was truncated. I pushed three commits:
|
2171e7c does not play well with TSAN, investigating. |
As far as I can tell this is not actually needed, as we decrement it right away, but it prevents TSAN from reporting a race when the UDP response comes very fast, is truncated, and the query is then passed to a TCP worker. TSAN seems to think that the thread is still sending the UDP query when we touch it again in the TCP worker, which does not really make sense to me. My guess is that the memory barrier needed to update the ref counter makes TSAN happy, but I might be missing something.
Fixed for now, it looks like TSAN is confused by the fact that the answer from the backend might come back in a UDP responder thread before the |
In
still |
The comment should say that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some small remarks. Ref counting is inherently a bit of a scary subject as it is easy to get wrong, but I do think this approach is better than before.
pdns/dnsdist-idstate.hh
Outdated
@@ -241,7 +241,7 @@ struct IDState | |||
std::unique_ptr<QTag> qTag{nullptr}; // 8 | |||
boost::optional<uint32_t> tempFailureTTL; // 8 | |||
const ClientState* cs{nullptr}; // 8 | |||
DOHUnit* du{nullptr}; // 8 | |||
DOHUnit* du{nullptr}; // 8 (not a unique_ptr because we currently need to be able to peek at it without knowing taking ownership until later) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: use duNaked
or something like that to make it very clear it's not a smart pointer when using it as other instances of du
hold a unique_pointer
.
Thanks, Otto! I pushed a few commits following your advice, I'm still pondering the |
yes, that is more clear |
I'm going to merge this without changing the |
Short description
Introduced in 1.7.0, and only when a cross-protocol response to a DoH query is dropped by a rule.
Checklist
I have: