diff mbox series

[v1,bpf-next,2/7] bpf: Consider non-owning refs trusted

Message ID 20230801203630.3581291-3-davemarchevsky@fb.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series BPF Refcount followups 3: bpf_mem_free_rcu refcounted nodes | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1415 this patch: 1415
netdev/cc_maintainers warning 8 maintainers not CCed: kpsingh@kernel.org martin.lau@linux.dev john.fastabend@gmail.com sdf@google.com song@kernel.org yonghong.song@linux.dev jolsa@kernel.org haoluo@google.com
netdev/build_clang success Errors and warnings before: 1377 this patch: 1377
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 1438 this patch: 1438
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain_full }}
bpf/vmtest-bpf-next-VM_Test-2 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 fail Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-7 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-8 success Logs for veristat

Commit Message

Dave Marchevsky Aug. 1, 2023, 8:36 p.m. UTC
Recent discussions around default kptr "trustedness" led to changes such
as commit 6fcd486b3a0a ("bpf: Refactor RCU enforcement in the
verifier."). One of the conclusions of those discussions, as expressed
in code and comments in that patch, is that we'd like to move away from
'raw' PTR_TO_BTF_ID without some type flag or other register state
indicating trustedness. Although PTR_TRUSTED and PTR_UNTRUSTED flags mark
this state explicitly, the verifier currently considers trustedness
implied by other register state. For example, owning refs to graph
collection nodes must have a nonzero ref_obj_id, so they pass the
is_trusted_reg check despite having no explicit PTR_{UN}TRUSTED flag.
This patch makes trustedness of non-owning refs to graph collection
nodes explicit as well.

By definition, non-owning refs are currently trusted. Although the ref
has no control over pointee lifetime, due to non-owning ref clobbering
rules (see invalidate_non_owning_refs) dereferencing a non-owning ref is
safe in the critical section controlled by bpf_spin_lock associated with
its owning collection.

Note that the previous statement does not hold true for nodes with shared
ownership due to the use-after-free issue that this series is
addressing. True shared ownership was disabled by commit 7deca5eae833
("bpf: Disable bpf_refcount_acquire kfunc calls until race conditions are fixed"),
though, so the statement holds for now. Further patches in the series will change
the trustedness state of non-owning refs before re-enabling
bpf_refcount_acquire.

Let's add NON_OWN_REF type flag to BPF_REG_TRUSTED_MODIFIERS such that a
non-owning ref reg state would pass is_trusted_reg check. Somewhat
surprisingly, this doesn't result in any change to user-visible
functionality elsewhere in the verifier: graph collection nodes are all
marked MEM_ALLOC, which tends to be handled in separate codepaths from
"raw" PTR_TO_BTF_ID. Regardless, let's be explicit here and document the
current state of things before changing it elsewhere in the series.

Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>
---
 include/linux/bpf_verifier.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Yonghong Song Aug. 2, 2023, 4:11 a.m. UTC | #1
On 8/1/23 1:36 PM, Dave Marchevsky wrote:
> Recent discussions around default kptr "trustedness" led to changes such
> as commit 6fcd486b3a0a ("bpf: Refactor RCU enforcement in the
> verifier."). One of the conclusions of those discussions, as expressed
> in code and comments in that patch, is that we'd like to move away from
> 'raw' PTR_TO_BTF_ID without some type flag or other register state
> indicating trustedness. Although PTR_TRUSTED and PTR_UNTRUSTED flags mark
> this state explicitly, the verifier currently considers trustedness
> implied by other register state. For example, owning refs to graph
> collection nodes must have a nonzero ref_obj_id, so they pass the
> is_trusted_reg check despite having no explicit PTR_{UN}TRUSTED flag.
> This patch makes trustedness of non-owning refs to graph collection
> nodes explicit as well.
> 
> By definition, non-owning refs are currently trusted. Although the ref
> has no control over pointee lifetime, due to non-owning ref clobbering
> rules (see invalidate_non_owning_refs) dereferencing a non-owning ref is
> safe in the critical section controlled by bpf_spin_lock associated with
> its owning collection.
> 
> Note that the previous statement does not hold true for nodes with shared
> ownership due to the use-after-free issue that this series is
> addressing. True shared ownership was disabled by commit 7deca5eae833
> ("bpf: Disable bpf_refcount_acquire kfunc calls until race conditions are fixed"),
> though, so the statement holds for now. Further patches in the series will change
> the trustedness state of non-owning refs before re-enabling
> bpf_refcount_acquire.
> 
> Let's add NON_OWN_REF type flag to BPF_REG_TRUSTED_MODIFIERS such that a
> non-owning ref reg state would pass is_trusted_reg check. Somewhat
> surprisingly, this doesn't result in any change to user-visible
> functionality elsewhere in the verifier: graph collection nodes are all
> marked MEM_ALLOC, which tends to be handled in separate codepaths from
> "raw" PTR_TO_BTF_ID. Regardless, let's be explicit here and document the
> current state of things before changing it elsewhere in the series.
> 
> Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com>

Acked-by: Yonghong Song <yonghong.song@linux.dev>
diff mbox series

Patch

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index f70f9ac884d2..b6e58dab8e27 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -745,7 +745,7 @@  static inline bool bpf_prog_check_recur(const struct bpf_prog *prog)
 	}
 }
 
-#define BPF_REG_TRUSTED_MODIFIERS (MEM_ALLOC | PTR_TRUSTED)
+#define BPF_REG_TRUSTED_MODIFIERS (MEM_ALLOC | PTR_TRUSTED | NON_OWN_REF)
 
 static inline bool bpf_type_has_unsafe_modifiers(u32 type)
 {