Skip to content

dnsdist: Fix BPFFilter::addRangeRule - #17287

Merged
rgacogne merged 1 commit into
PowerDNS:masterfrom
rgacogne:ddist-ebpf-add-range-rule
May 5, 2026
Merged

dnsdist: Fix BPFFilter::addRangeRule#17287
rgacogne merged 1 commit into
PowerDNS:masterfrom
rgacogne:ddist-ebpf-add-range-rule

Conversation

@rgacogne

@rgacogne rgacogne commented May 4, 2026

Copy link
Copy Markdown
Member

Short description

Reported by Prasanna Dabi (thanks!):

"The eBPF DDoS mitigation implementation in dnsdist contains a critical logic error that prevents new range-based block rules from being applied. When the BPFFilter::addRangeRule() function is called to block a subnet, it first checks the eBPF map to determine if the rule already exists. If the subnet is not currently in the map, the bpf_lookup_elem call returns -1. In this failure state, the local CounterAndActionValue value struct remains in its default, zeroed-out state, where the action field is automatically set to BPFFilter::MatchAction::Pass.

The conditional check intended to skip redundant rules contains a logic typo: it evaluates value.action == BPFFilter::MatchAction::Pass instead of comparing the requested action parameter.Because the default state of the unpopulated struct is always Pass, the condition (res == -1 && value.action == BPFFilter::MatchAction::Pass) evaluates to true for every new rule attempt.This causes the daemon to throw a std::runtime_error and reject the mitigation."

Checklist

I have:

  • read the CONTRIBUTING.md document
  • read and accepted the Developer Certificate of Origin document, including the AI Policy, and added a "Signed-off-by" to my commits
  • compiled this code
  • tested this code
  • included documentation (including possible behaviour changes)
  • documented the code
  • added or modified regression test(s)
  • added or modified unit test(s)

Reported by Prasanna Dabi (thanks!):
"The eBPF DDoS mitigation implementation in dnsdist contains a critical logic error that prevents new range-based block rules from being applied. When the BPFFilter::addRangeRule() function is called to block a subnet, it first checks the eBPF map to determine if the rule already exists. If the subnet is not currently in the map, the bpf_lookup_elem call returns -1. In this failure state, the local CounterAndActionValue value struct remains in its default, zeroed-out state, where the action field is automatically set to BPFFilter::MatchAction::Pass.

The conditional check intended to skip redundant rules contains a logic typo: it evaluates value.action == BPFFilter::MatchAction::Pass instead of comparing the requested action parameter.Because the default state of the unpopulated struct is always Pass, the condition (res == -1 && value.action == BPFFilter::MatchAction::Pass) evaluates to true for every new rule attempt.This causes the daemon to throw a std::runtime_error and reject the mitigation."

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
@rgacogne
rgacogne merged commit eac4af2 into PowerDNS:master May 5, 2026
165 of 167 checks passed
@rgacogne
rgacogne deleted the ddist-ebpf-add-range-rule branch May 5, 2026 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants