Skip to content

ICP: Fix HttpRequest lifetime for ICP v3 queries#2377

Closed
rousskov wants to merge 2 commits intosquid-cache:masterfrom
measurement-factory:SQUID-111-icp-v3-http-request-uaf
Closed

ICP: Fix HttpRequest lifetime for ICP v3 queries#2377
rousskov wants to merge 2 commits intosquid-cache:masterfrom
measurement-factory:SQUID-111-icp-v3-http-request-uaf

Conversation

@rousskov
Copy link
Contributor

ACLFilledChecklist correctly locks and unlocks HttpRequest. Thus, when
given an unlocked request object, an on-stack checklist destroys it.
Upon icpAccessAllowed() return, Squid uses the destroyed request object.

This bug was probably introduced in 2003 commit 8000a96 that started
automatically unlocking requests in ACLChecklist destructor. However,
the bug did not affect allowed ICP v3 queries until 2007 commit f72fb56
started using the request object for them. 2005 commit 319bf5a fixed
an equivalent ICP v2 bug for denied queries but missed the ICP v3 case.

The scope, age, and effect of this bug imply that Squid v3+ deployments
receive no ICP v3 queries since 2007 (or earlier). Squid itself does not
send ICP v3 messages, responding with ICP v2 replies to ICP v3 queries.
TODO: Consider dropping ICP v3 support.

Also moved icpAccessAllowed() inside icpGetRequest() to deduplicate code
and reduce the risk of allowing a request without consulting icp_access.

ACLFilledChecklist correctly locks and unlocks HttpRequest. Thus, when
given an unlocked request object, an on-stack checklist destroys it.
Upon icpAccessAllowed() return, Squid uses the destroyed request object.

This bug was probably introduced in 2003 commit 8000a96 that started
automatically unlocking requests in ACLChecklist destructor. However,
the bug did not affect allowed ICP v3 queries until 2007 commit f72fb56
started _using_ the request object for them. 2005 commit 319bf5a fixed
an equivalent ICP v2 bug for denied queries but missed the ICP v3 case.

The scope and age of this bug imply that Squid v3+ deployments receive
no ICP v3 queries since 2007 (or earlier). Squid itself does not send
ICP v3 messages, responding with ICP v2 replies to ICP v3 queries. TODO:
Consider dropping ICP v3 support.

Also moved icpAccessAllowed() inside icpGetRequest() to deduplicate code
and reduce the risk of allowing a request without consulting icp_access.
And resolved seemingly simple/safe conflicts.
@rousskov rousskov added the S-could-use-an-approval An approval may speed this PR merger (but is not required) label Feb 18, 2026
Copy link
Contributor

@yadij yadij left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ICPState::request member will need to be included with this conversion to prevent the same issues appearing again whenever the ICP request is put in the "delayed UDP" queue instead of sent synchronously.

@yadij yadij added S-waiting-for-author author action is expected (and usually required) and removed S-could-use-an-approval An approval may speed this PR merger (but is not required) labels Feb 19, 2026
@rousskov
Copy link
Contributor Author

The ICPState::request member will need to be included with this conversion to prevent the same issues appearing again whenever the ICP request is put in the "delayed UDP" queue instead of sent synchronously.

What makes you think that? AFAICT, ICPState::request member is currently managed correctly -- it is unconditionally locked in the class constructor and unconditionally unlocked in the class destructor. It is never set or cleared directly. I can upgrade its type to Pointer, but it is not going to affect HttpRequest lifetime while increasing diff noise for this bug fix. Do you insist on that upgrade in this PR?

whenever the ICP request is put in the "delayed UDP" queue instead of sent synchronously.

DelayedUdpSend objects do not store HttpRequests. Also, ICPState-derived objects are always allocated on stack and, hence, are never queued for any asynchronous operations.

@rousskov rousskov requested a review from yadij February 19, 2026 14:01
@rousskov rousskov added S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box S-could-use-an-approval An approval may speed this PR merger (but is not required) and removed S-waiting-for-author author action is expected (and usually required) labels Feb 19, 2026
@yadij
Copy link
Contributor

yadij commented Feb 19, 2026

You are right, sorry. I only looked at the header and member type as raw-pointer. Approving now.

@yadij yadij added M-cleared-for-merge https://github.com/measurement-factory/anubis#pull-request-labels and removed S-waiting-for-reviewer ready for review: Set this when requesting a (re)review using GitHub PR Reviewers box S-could-use-an-approval An approval may speed this PR merger (but is not required) labels Feb 19, 2026
@rousskov rousskov added the S-could-use-an-approval An approval may speed this PR merger (but is not required) label Feb 19, 2026
squid-anubis pushed a commit that referenced this pull request Feb 20, 2026
ACLFilledChecklist correctly locks and unlocks HttpRequest. Thus, when
given an unlocked request object, an on-stack checklist destroys it.
Upon icpAccessAllowed() return, Squid uses the destroyed request object.

This bug was probably introduced in 2003 commit 8000a96 that started
automatically unlocking requests in ACLChecklist destructor. However,
the bug did not affect allowed ICP v3 queries until 2007 commit f72fb56
started _using_ the request object for them. 2005 commit 319bf5a fixed
an equivalent ICP v2 bug for denied queries but missed the ICP v3 case.

The scope, age, and effect of this bug imply that Squid v3+ deployments
receive no ICP v3 queries since 2007 (or earlier). Squid itself does not
send ICP v3 messages, responding with ICP v2 replies to ICP v3 queries.
TODO: Consider dropping ICP v3 support.

Also moved icpAccessAllowed() inside icpGetRequest() to deduplicate code
and reduce the risk of allowing a request without consulting icp_access.
@squid-anubis squid-anubis added the M-waiting-staging-checks https://github.com/measurement-factory/anubis#pull-request-labels label Feb 20, 2026
@squid-anubis squid-anubis added M-merged https://github.com/measurement-factory/anubis#pull-request-labels and removed M-waiting-staging-checks https://github.com/measurement-factory/anubis#pull-request-labels M-cleared-for-merge https://github.com/measurement-factory/anubis#pull-request-labels labels Feb 20, 2026
@rousskov rousskov removed the S-could-use-an-approval An approval may speed this PR merger (but is not required) label Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

M-merged https://github.com/measurement-factory/anubis#pull-request-labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants