Normalize and correct sock_addr verdict handling - #5546
Shankar Seal (shankarseal) merged 5 commits into
Conversation
Centralize sock_addr classify preconditions and translate verdicts to WFP actions only at each exit path. Preserve connect-authorization cache cleanup and connect-redirect's specialized action semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f80bc76a-92b4-4658-9ce2-ca11c31b615c
There was a problem hiding this comment.
🔵 Needs a closer look
It changes kernel networking classification logic (verdict/action/right handling) and warrants careful human validation despite only minor nits found.
Pull request overview
This PR normalizes sock_addr WFP classify callback behavior in netebpfext by standardizing default verdicts, write-right handling, and program-invocation result mapping, then translating final verdicts to WFP actions in a consistent exit path.
Changes:
- Introduces shared helpers to centralize
FWPS_RIGHT_ACTION_WRITEchecks, active filter-context validation, and program-result→verdict normalization. - Updates
sock_addrclassify callbacks to default toBPF_SOCK_ADDR_VERDICT_PROCEED_SOFT, skip program invocation without write rights, and apply verdicts via common exit logic. - Refactors CONNECT_REDIRECT to apply action decisions via a dedicated helper and prevents verdict-cache operations before the socket context is initialized.
File summaries
| File | Description |
|---|---|
| netebpfext/net_ebpf_ext_sock_addr.c | Centralizes sock_addr verdict/action handling and normalizes classification behavior across callbacks. |
Review details
Suppressed comments (2)
netebpfext/net_ebpf_ext_sock_addr.c:2541
- incoming_metadata_values is used later (e.g., transportEndpointHandle and field copy), so UNREFERENCED_PARAMETER(incoming_metadata_values) is inaccurate and should be removed to avoid confusion.
UNREFERENCED_PARAMETER(incoming_metadata_values);
netebpfext/net_ebpf_ext_sock_addr.c:2353
- incoming_metadata_values is referenced later (e.g., used for transportEndpointHandle logging and passed into _net_ebpf_extension_sock_addr_copy_wfp_connection_fields), so UNREFERENCED_PARAMETER(incoming_metadata_values) is inaccurate and should be removed to avoid confusion.
UNREFERENCED_PARAMETER(incoming_metadata_values);
- Files reviewed: 1/1 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
doxygen fix and remove incorrect `UNREFERENCED_PARAMETER` Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Replace the write-right and filter-context helpers with bail macros, and perform connect-authorization cache cleanup before the no-write exit. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f80bc76a-92b4-4658-9ce2-ca11c31b615c
There was a problem hiding this comment.
🔵 Needs a closer look
Moderate regression-test gaps remain for write-right handling and fail-closed listen errors.
Review details
Suppressed comments (2)
netebpfext/net_ebpf_ext_sock_addr.c:30
- These new gates implement the PR's key FWPS_RIGHT_ACTION_WRITE behavior, but the existing netebpfext_unit coverage never supplies a classify output with the write right revoked (the tests explicitly note that this state cannot be inspected). There is therefore no regression test that dispatch is skipped and the pre-existing action is preserved, especially for connect-authorization cache cleanup; add a simulator or integration case covering both outcomes.
#define BAIL_ON_NO_WRITE_RIGHT(classify_output, action_write_allowed) \
do { \
(action_write_allowed) = (((classify_output)->rights & FWPS_RIGHT_ACTION_WRITE) != 0); \
if (!(action_write_allowed)) { \
EBPF_EXT_LOG_MESSAGE( \
netebpfext/net_ebpf_ext_sock_addr.c:2280
- The new failure mapping for the listen callback is not covered by the existing sock_addr tests:
sock_addr_listen_invokeexercises soft permit, reject, and hard permit, but unlikesock_addr_invokeit never setsSOCK_ADDR_TEST_ACTION_FAILURE. Add IPv4/IPv6 assertions that a listen program invocation failure becomes a block with the write right revoked, so this required fail-closed behavior cannot regress.
program_result = net_ebpf_extension_hook_expand_stack_and_invoke_programs(
sock_addr_ctx, &filter_context->base, &program_verdict);
verdict = _net_ebpf_extension_sock_addr_get_program_verdict(program_result, program_verdict, verdict);
- Files reviewed: 1/1 changed files
- Comments generated: 0 new
- Review effort level: Lite
Improve shared diagnostics and documentation, add program invocation failure traces, and standardize verdict/result naming across classify callbacks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f80bc76a-92b4-4658-9ce2-ca11c31b615c
There was a problem hiding this comment.
🔵 Needs a closer look
Moderate findings require coverage for write-right handling and listen invocation failures.
Review details
Suppressed comments (2)
netebpfext/net_ebpf_ext_sock_addr.c:32
- This new gate implements the PR's key
FWPS_RIGHT_ACTION_WRITEcontract, but the existing sock_addr tests never drive a classify output with the write right revoked or verify that the eBPF callback is skipped and the prior action is preserved; the test suite even notes that this state is not asserted directly attests/netebpfext_unit/netebpfext_unit.cpp:287-293. Add a usersim/integration case (including connect-authorization cache cleanup) so this central behavior cannot regress.
#define BAIL_ON_NO_WRITE_RIGHT(classify_output, action_write_allowed) \
do { \
(action_write_allowed) = (((classify_output)->rights & FWPS_RIGHT_ACTION_WRITE) != 0); \
if (!(action_write_allowed)) { \
EBPF_EXT_LOG_MESSAGE( \
netebpfext/net_ebpf_ext_sock_addr.c:2309
- The new fail-closed mapping for listen invocation errors is not covered by the existing
sock_addr_listen_invoketest: it exercises soft permit, reject, and hard permit, but neverSOCK_ADDR_TEST_ACTION_FAILURE. Add IPv4 and IPv6 assertions that an invocation failure reaches this path and produces a block with the write right revoked.
program_result = net_ebpf_extension_hook_expand_stack_and_invoke_programs(
sock_addr_ctx, &filter_context->base, &program_verdict);
NET_EBPF_EXT_LOG_SOCK_ADDR_PROGRAM_INVOCATION_FAILURE(program_result);
effective_verdict =
_net_ebpf_extension_sock_addr_get_effective_verdict(program_result, program_verdict, effective_verdict);
- Files reviewed: 1/1 changed files
- Comments generated: 0 new
- Review effort level: Lite
Restore the original destination before caching an unapplied REJECT so CONNECT_AUTHORIZATION can find and enforce it. Add IPv4 and IPv6 regression coverage for destination rewrite followed by REJECT. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f80bc76a-92b4-4658-9ce2-ca11c31b615c
Description
Normalize verdict and WFP action handling across all
sock_addrclassify callbacks.BPF_SOCK_ADDR_VERDICT_PROCEED_SOFT.FWPS_RIGHT_ACTION_WRITEis absent, preserving the existing WFP action rather than issuing a veto.EBPF_SUCCESSuses the returned or accumulated program verdict.EBPF_OBJECT_NOT_FOUNDpreserves the current verdict.BPF_SOCK_ADDR_VERDICT_REJECT.PROCEED_SOFTreturnsFWP_ACTION_PERMITwhile retaining the write right.PROCEED_HARDreturnsFWP_ACTION_PERMITand clears the write right.FWP_ACTION_BLOCKand clear the write right.CONTINUE, while redirects and cached rejections return terminatingPERMIT.Closes #5544.
Testing
drivers\netebpfextbuild.tests\netebpfext_unitbuild.netebpfext_unit: 494 assertions in 25 test cases.