Skip to content

draft: sanitize_check_bounds test #8966

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

Open
wants to merge 1 commit into
base: bpf-next_base
Choose a base branch
from

Conversation

luisgerhorst
Copy link
Contributor

No description provided.

@luisgerhorst luisgerhorst force-pushed the scb branch 3 times, most recently from 9028adc to 7e17351 Compare May 20, 2025 20:38
@kernel-patches-daemon-bpf kernel-patches-daemon-bpf bot force-pushed the bpf-next_base branch 2 times, most recently from 49174bd to f3a4188 Compare May 20, 2025 23:25
@kernel-patches-daemon-bpf kernel-patches-daemon-bpf bot force-pushed the bpf-next_base branch 3 times, most recently from 9857a0f to b93b30b Compare May 22, 2025 16:34
@luisgerhorst luisgerhorst force-pushed the scb branch 2 times, most recently from 3ecbfab to 0f543ec Compare May 22, 2025 21:03
As is, it appears as if ptr alu is allowed for everything except
PTR_TO_{STACK,MAP_VALUE} if one only reads sanitize_check_bounds().
However, this is misleading as it only works together with
retrieve_ptr_limit() and the two must be kept in sync. This patch
documents the interdependency and adds a check to ensure they stay in
sync.

Because the preceeding switch returns -EACCES for every opcode except
for ADD/SUB, the sanitize_needed() following the sanitize_check_bounds()
call is always true if reached. This means, unless
sanitize_check_bounds() detected that the pointer goes OOB because of
the ADD/SUB (and returns -EACCES), sanitize_ptr_alu() always executes
after sanitize_check_bounds().

In sanitize_ptr_alu(commit_window = true), we always run
retrieve_ptr_limit() unless:
* can_skip_alu_sanititation() is true, i.e., noteably
  `BPF_SRC(insn->code) == BPF_K`. BPF_K is fine because it means that
  there is no scalar register (which could be subject to spec. scalar
  confusion due to v4) that goes into the alu op. The ptr reg can not be
  subject to v4-based value confusion due to the nospec added.
* We are on a speculative path (`vstate->speculative`). This is because
  there are no alu sanitization limits to be learned from speculative
  paths.

retrieve_ptr_limit() only allows the ALU op if the involved ptr reg (can
be either rhs or lhs for ADD) is PTR_TO_STACK or PTR_TO_MAP_VALUE.
Otherwise it returns -EOPNOTSUPP.

In summary, sanitize_check_bounds() returning 0 for
non-PTR_TO_{STACK,MAP_VALUE} is fine because retrieve_ptr_limit() still
prevents the unsafe ops.

We allow unsanitized ptr arith with ADD/SUB for
* ptr -=/+= imm32, i.e. `BPF_SRC(insn->code) == BPF_K`
* PTR_TO_{STACK,MAP_VALUE} -= scalar
* PTR_TO_{STACK,MAP_VALUE} += scalar
* scalar += PTR_TO_{STACK,MAP_VALUE}
if the requirements from retrieve_ptr_limit() AND
sanitize_check_bounds() hold.

To document this interdependency and ensure they stay in sync, add a
verifier_bug_if().

Signed-off-by: Luis Gerhorst <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant