Thread (15 messages) 15 messages, 3 authors, 2021-10-26

Re: [PATCH bpf-next v2 2/3] bpf: Introduce ARG_PTR_TO_WRITABLE_MEM

From: Andrii Nakryiko <hidden>
Date: 2021-10-26 18:53:26

On Tue, Oct 26, 2021 at 10:51 AM Hao Luo [off-list ref] wrote:
On Mon, Oct 25, 2021 at 10:06 PM Andrii Nakryiko
[off-list ref] wrote:
quoted
On Mon, Oct 25, 2021 at 4:13 PM Hao Luo [off-list ref] wrote:
quoted
Some helper functions may modify its arguments, for example,
bpf_d_path, bpf_get_stack etc. Previously, their argument types
were marked as ARG_PTR_TO_MEM, which is compatible with read-only
mem types, such as PTR_TO_RDONLY_BUF. Therefore it's legitimate
to modify a read-only memory by passing it into one of such helper
functions.

This patch introduces a new arg type ARG_PTR_TO_WRITABLE_MEM to
annotate the arguments that may be modified by the helpers. For
arguments that are of ARG_PTR_TO_MEM, it's ok to take any mem type,
while for ARG_PTR_TO_WRITABLE_MEM, readonly mem reg types are not
acceptable.

In short, when a helper may modify its input parameter, use
ARG_PTR_TO_WRITABLE_MEM instead of ARG_PTR_TO_MEM.
This is inconsistent with the other uses where we have something
that's writable by default and mark it as RDONLY if it's read-only.
Same here, why not keep ARG_PTR_TO_MEM to mean "writable memory", and
add ARG_PTR_TO_RDONLY_MEM for helpers that are not writing into the
memory? It will also be safer default: if helper defines
ARG_PTR_TO_MEM but never writes to it, worst thing that can happen
would be that you won't be able to pass REG_PTR_TO_RDONLY_MEM into it
without fixing helper definition. The other way is more dangerous. If
ARG_PTR_TO_MEM means read-only mem and helper forgot this distinction
and actually writes into the memory, then we are in much bigger
trouble.
My original implementation was adding ARG_PTR_TO_RDONLY_MEM. But I
find it's not intuitive for developers when adding helpers. The
majority of PTR_TO_MEM arguments are read-only. When adding a new
helper, I would expect the default arg type (that is, ARG_PTR_TO_MEM)
to match the default case (that is, read-only argument). Requiring
explicitly adding RDONLY to most cases seems a little unintuitive to
me.

But other than that, I agree that narrowing ARG_PTR_TO_MEM down to
writable memory fosters more strict checks and safer behavior. But
when people add helpers, they are clearly aware which argument will be
modified and which will not. IMHO I do trust that the developers and
the reviewers can choose the right type at the review time. :)
I don't trust myself, and neither should you :) See 5b029a32cfe4
("bpf: Fix ringbuf helper function compatibility") as an example of
the things that shouldn't have happened, but slipped through my own
testing and code review anyway. And there were multiple cases where we
accidentally enabled stuff that we shouldn't or didn't check something
that should have been prevented.

All that is to say that if we can have safer behavior by default (not
as enforced by humans), then it's better. In this sense,
ARG_PTR_TO_MEM meaning writable access is safer, because even if we
accidentally forget to mark some input as ARG_PTR_TO_RDONLY_MEM, worst
thing is that users won't be able to use helper in some situation and
hopefully will report this and we'll fix it. The alternative is that a
helper declares the argument as read-only memory (accidentally,
because it's shorter enum and sort of default), but actually does the
write to that memory. Now we have a much bigger issue.
quoted
quoted
So far the difference between ARG_PTR_TO_MEM and ARG_PTR_TO_WRITABLE_MEM
is PTR_TO_RDONLY_BUF and PTR_TO_RDONLY_MEM. PTR_TO_RDONLY_BUF is
only used in bpf_iter prog as the type of key, which hasn't been
used in the affected helper functions. PTR_TO_RDONLY_MEM currently
has no consumers.

Signed-off-by: Hao Luo <redacted>
---
 Changes since v1:
  - new patch, introduced ARG_PTR_TO_WRITABLE_MEM to differentiate
    read-only and read-write mem arg types.
[...]
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help