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

Closed
wants to merge 1 commit into 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 3 times, most recently from 0f543ec to d1427b7 Compare May 22, 2025 21:14
@kernel-patches-daemon-bpf kernel-patches-daemon-bpf bot force-pushed the bpf-next_base branch 4 times, most recently from e85324d to 61c8df2 Compare May 23, 2025 20:32
As is, it appears as if ptr alu is allowed for everything except
PTR_TO_{STACK,MAP_VALUE} if one only looks at sanitize_check_bounds().
However, this is misleading as the function 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, 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
  Spectre v4) that goes into the alu op. The ptr reg can not be subject
  to v4-based value confusion due to the nospec added. Thus, in this
  case it would have been fine to also skip sanitize_check_bounds().

* We are on a speculative path (`vstate->speculative`). In the second
  "commit" phase, sanitize_ptr_alu() always just returns 0. This makes
  sense because there are no alu sanitization limits to be learned from
  speculative paths. Furthermore, because the sanitization will ensure
  that ptr arith stays in (architectural) bounds, the
  sanitize_check_bounds() on the spec. path could also be skipped.

TODO, through case two, is it fine that we allow alu with other ptr type
(non-stack/ap) on spec path

retrieve_ptr_limit() only allows the ALU op if the involved ptr reg (can
be either src or dst 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() also
runs for all relevant cases and prevents unsafe ops.

We therefore allow unsanitized ptr arith with 64-bit 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 between sanitize_check_bounds() and
retrieve_ptr_limit(), add a verifier_bug_if() to make sure they stay in
sync.

Further background info:

* There are two calls to sanitize_ptr_alu(), on the first call we spawn
  the path to simulate truncation and

TODO, why spawn the path before simulating the alu op
TODO, why two calls to sanitize_ptr_alu

Signed-off-by: Luis Gerhorst <[email protected]>
@kernel-patches-daemon-bpf
Copy link

Automatically cleaning up stale PR; feel free to reopen if needed

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