~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
  3 
  4 #include <vmlinux.h>
  5 #include <bpf/bpf_helpers.h>
  6 #include <bpf/bpf_tracing.h>
  7 #include <bpf/bpf_core_read.h>
  8 #include "bpf_misc.h"
  9 #include "xdp_metadata.h"
 10 #include "bpf_kfuncs.h"
 11 
 12 extern struct task_struct *bpf_task_acquire(struct task_struct *p) __ksym __weak;
 13 extern void bpf_task_release(struct task_struct *p) __ksym __weak;
 14 
 15 __weak int subprog_trusted_task_nullable(struct task_struct *task __arg_trusted __arg_nullable)
 16 {
 17         if (!task)
 18                 return 0;
 19         return task->pid + task->tgid;
 20 }
 21 
 22 __weak int subprog_trusted_task_nullable_extra_layer(struct task_struct *task __arg_trusted __arg_nullable)
 23 {
 24         return subprog_trusted_task_nullable(task) + subprog_trusted_task_nullable(NULL);
 25 }
 26 
 27 SEC("?tp_btf/task_newtask")
 28 __success __log_level(2)
 29 __msg("Validating subprog_trusted_task_nullable() func#1...")
 30 __msg(": R1=trusted_ptr_or_null_task_struct(")
 31 int trusted_task_arg_nullable(void *ctx)
 32 {
 33         struct task_struct *t1 = bpf_get_current_task_btf();
 34         struct task_struct *t2 = bpf_task_acquire(t1);
 35         int res = 0;
 36 
 37         /* known NULL */
 38         res += subprog_trusted_task_nullable(NULL);
 39 
 40         /* known non-NULL */
 41         res += subprog_trusted_task_nullable(t1);
 42         res += subprog_trusted_task_nullable_extra_layer(t1);
 43 
 44         /* unknown if NULL or not */
 45         res += subprog_trusted_task_nullable(t2);
 46         res += subprog_trusted_task_nullable_extra_layer(t2);
 47 
 48         if (t2) {
 49                 /* known non-NULL after explicit NULL check, just in case */
 50                 res += subprog_trusted_task_nullable(t2);
 51                 res += subprog_trusted_task_nullable_extra_layer(t2);
 52 
 53                 bpf_task_release(t2);
 54         }
 55 
 56         return res;
 57 }
 58 
 59 __weak int subprog_trusted_task_nonnull(struct task_struct *task __arg_trusted)
 60 {
 61         return task->pid + task->tgid;
 62 }
 63 
 64 SEC("?kprobe")
 65 __failure __log_level(2)
 66 __msg("R1 type=scalar expected=ptr_, trusted_ptr_, rcu_ptr_")
 67 __msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')")
 68 int trusted_task_arg_nonnull_fail1(void *ctx)
 69 {
 70         return subprog_trusted_task_nonnull(NULL);
 71 }
 72 
 73 SEC("?tp_btf/task_newtask")
 74 __failure __log_level(2)
 75 __msg("R1 type=ptr_or_null_ expected=ptr_, trusted_ptr_, rcu_ptr_")
 76 __msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')")
 77 int trusted_task_arg_nonnull_fail2(void *ctx)
 78 {
 79         struct task_struct *t = bpf_get_current_task_btf();
 80         struct task_struct *nullable;
 81         int res;
 82 
 83         nullable = bpf_task_acquire(t);
 84 
 85          /* should fail, PTR_TO_BTF_ID_OR_NULL */
 86         res = subprog_trusted_task_nonnull(nullable);
 87 
 88         if (nullable)
 89                 bpf_task_release(nullable);
 90 
 91         return res;
 92 }
 93 
 94 SEC("?kprobe")
 95 __success __log_level(2)
 96 __msg("Validating subprog_trusted_task_nonnull() func#1...")
 97 __msg(": R1=trusted_ptr_task_struct(")
 98 int trusted_task_arg_nonnull(void *ctx)
 99 {
100         struct task_struct *t = bpf_get_current_task_btf();
101 
102         return subprog_trusted_task_nonnull(t);
103 }
104 
105 struct task_struct___local {} __attribute__((preserve_access_index));
106 
107 __weak int subprog_nullable_task_flavor(
108         struct task_struct___local *task __arg_trusted __arg_nullable)
109 {
110         char buf[16];
111 
112         if (!task)
113                 return 0;
114 
115         return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0);
116 }
117 
118 SEC("?uprobe.s")
119 __success __log_level(2)
120 __msg("Validating subprog_nullable_task_flavor() func#1...")
121 __msg(": R1=trusted_ptr_or_null_task_struct(")
122 int flavor_ptr_nullable(void *ctx)
123 {
124         struct task_struct___local *t = (void *)bpf_get_current_task_btf();
125 
126         return subprog_nullable_task_flavor(t);
127 }
128 
129 __weak int subprog_nonnull_task_flavor(struct task_struct___local *task __arg_trusted)
130 {
131         char buf[16];
132 
133         return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0);
134 }
135 
136 SEC("?uprobe.s")
137 __success __log_level(2)
138 __msg("Validating subprog_nonnull_task_flavor() func#1...")
139 __msg(": R1=trusted_ptr_task_struct(")
140 int flavor_ptr_nonnull(void *ctx)
141 {
142         struct task_struct *t = bpf_get_current_task_btf();
143 
144         return subprog_nonnull_task_flavor((void *)t);
145 }
146 
147 __weak int subprog_trusted_destroy(struct task_struct *task __arg_trusted)
148 {
149         bpf_task_release(task); /* should be rejected */
150 
151         return 0;
152 }
153 
154 SEC("?tp_btf/task_newtask")
155 __failure __log_level(2)
156 __msg("release kernel function bpf_task_release expects refcounted PTR_TO_BTF_ID")
157 int BPF_PROG(trusted_destroy_fail, struct task_struct *task, u64 clone_flags)
158 {
159         return subprog_trusted_destroy(task);
160 }
161 
162 __weak int subprog_trusted_acq_rel(struct task_struct *task __arg_trusted)
163 {
164         struct task_struct *owned;
165 
166         owned = bpf_task_acquire(task);
167         if (!owned)
168                 return 0;
169 
170         bpf_task_release(owned); /* this one is OK, we acquired it locally */
171 
172         return 0;
173 }
174 
175 SEC("?tp_btf/task_newtask")
176 __success __log_level(2)
177 int BPF_PROG(trusted_acq_rel, struct task_struct *task, u64 clone_flags)
178 {
179         return subprog_trusted_acq_rel(task);
180 }
181 
182 char _license[] SEC("license") = "GPL";
183 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php