/[packages]/backports/8/kernel/current/SOURCES/bpf-replace-arg_xxx_or_null-with-arg_xxx-ptr_maybe_null.patch
ViewVC logotype

Contents of /backports/8/kernel/current/SOURCES/bpf-replace-arg_xxx_or_null-with-arg_xxx-ptr_maybe_null.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1781185 - (show annotations) (download)
Fri Feb 18 16:18:16 2022 UTC (2 years, 2 months ago) by tmb
File size: 8538 byte(s)
sync with cauldron 5.16.10-2.mga9
1 From foo@baz Thu Feb 17 08:07:01 PM CET 2022
2 From: Hao Luo <haoluo@google.com>
3 Date: Wed, 16 Feb 2022 14:52:02 -0800
4 Subject: bpf: Replace ARG_XXX_OR_NULL with ARG_XXX | PTR_MAYBE_NULL
5 To: Greg KH <gregkh@linuxfoundation.org>
6 Cc: Alexei Starovoitov <ast@kernel.org>, Andrii Nakryiko <andrii@kernel.org>, Daniel Borkmann <daniel@iogearbox.net>, laura@labbott.name, stable@vger.kernel.org, Hao Luo <haoluo@google.com>
7 Message-ID: <20220216225209.2196865-3-haoluo@google.com>
8
9 From: Hao Luo <haoluo@google.com>
10
11 commit 48946bd6a5d695c50b34546864b79c1f910a33c1 upstream.
12
13 We have introduced a new type to make bpf_arg composable, by
14 reserving high bits of bpf_arg to represent flags of a type.
15
16 One of the flags is PTR_MAYBE_NULL which indicates a pointer
17 may be NULL. When applying this flag to an arg_type, it means
18 the arg can take NULL pointer. This patch switches the
19 qualified arg_types to use this flag. The arg_types changed
20 in this patch include:
21
22 1. ARG_PTR_TO_MAP_VALUE_OR_NULL
23 2. ARG_PTR_TO_MEM_OR_NULL
24 3. ARG_PTR_TO_CTX_OR_NULL
25 4. ARG_PTR_TO_SOCKET_OR_NULL
26 5. ARG_PTR_TO_ALLOC_MEM_OR_NULL
27 6. ARG_PTR_TO_STACK_OR_NULL
28
29 This patch does not eliminate the use of these arg_types, instead
30 it makes them an alias to the 'ARG_XXX | PTR_MAYBE_NULL'.
31
32 Signed-off-by: Hao Luo <haoluo@google.com>
33 Signed-off-by: Alexei Starovoitov <ast@kernel.org>
34 Link: https://lore.kernel.org/bpf/20211217003152.48334-3-haoluo@google.com
35 Cc: stable@vger.kernel.org # 5.16.x
36 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
37 ---
38 include/linux/bpf.h | 15 +++++++++------
39 kernel/bpf/verifier.c | 39 ++++++++++++++-------------------------
40 2 files changed, 23 insertions(+), 31 deletions(-)
41
42 --- a/include/linux/bpf.h
43 +++ b/include/linux/bpf.h
44 @@ -331,13 +331,11 @@ enum bpf_arg_type {
45 ARG_PTR_TO_MAP_KEY, /* pointer to stack used as map key */
46 ARG_PTR_TO_MAP_VALUE, /* pointer to stack used as map value */
47 ARG_PTR_TO_UNINIT_MAP_VALUE, /* pointer to valid memory used to store a map value */
48 - ARG_PTR_TO_MAP_VALUE_OR_NULL, /* pointer to stack used as map value or NULL */
49
50 /* the following constraints used to prototype bpf_memcmp() and other
51 * functions that access data on eBPF program stack
52 */
53 ARG_PTR_TO_MEM, /* pointer to valid memory (stack, packet, map value) */
54 - ARG_PTR_TO_MEM_OR_NULL, /* pointer to valid memory or NULL */
55 ARG_PTR_TO_UNINIT_MEM, /* pointer to memory does not need to be initialized,
56 * helper function must fill all bytes or clear
57 * them in error case.
58 @@ -347,26 +345,31 @@ enum bpf_arg_type {
59 ARG_CONST_SIZE_OR_ZERO, /* number of bytes accessed from memory or 0 */
60
61 ARG_PTR_TO_CTX, /* pointer to context */
62 - ARG_PTR_TO_CTX_OR_NULL, /* pointer to context or NULL */
63 ARG_ANYTHING, /* any (initialized) argument is ok */
64 ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */
65 ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */
66 ARG_PTR_TO_INT, /* pointer to int */
67 ARG_PTR_TO_LONG, /* pointer to long */
68 ARG_PTR_TO_SOCKET, /* pointer to bpf_sock (fullsock) */
69 - ARG_PTR_TO_SOCKET_OR_NULL, /* pointer to bpf_sock (fullsock) or NULL */
70 ARG_PTR_TO_BTF_ID, /* pointer to in-kernel struct */
71 ARG_PTR_TO_ALLOC_MEM, /* pointer to dynamically allocated memory */
72 - ARG_PTR_TO_ALLOC_MEM_OR_NULL, /* pointer to dynamically allocated memory or NULL */
73 ARG_CONST_ALLOC_SIZE_OR_ZERO, /* number of allocated bytes requested */
74 ARG_PTR_TO_BTF_ID_SOCK_COMMON, /* pointer to in-kernel sock_common or bpf-mirrored bpf_sock */
75 ARG_PTR_TO_PERCPU_BTF_ID, /* pointer to in-kernel percpu type */
76 ARG_PTR_TO_FUNC, /* pointer to a bpf program function */
77 - ARG_PTR_TO_STACK_OR_NULL, /* pointer to stack or NULL */
78 + ARG_PTR_TO_STACK, /* pointer to stack */
79 ARG_PTR_TO_CONST_STR, /* pointer to a null terminated read-only string */
80 ARG_PTR_TO_TIMER, /* pointer to bpf_timer */
81 __BPF_ARG_TYPE_MAX,
82
83 + /* Extended arg_types. */
84 + ARG_PTR_TO_MAP_VALUE_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_MAP_VALUE,
85 + ARG_PTR_TO_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_MEM,
86 + ARG_PTR_TO_CTX_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_CTX,
87 + ARG_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET,
88 + ARG_PTR_TO_ALLOC_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_ALLOC_MEM,
89 + ARG_PTR_TO_STACK_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_STACK,
90 +
91 /* This must be the last entry. Its purpose is to ensure the enum is
92 * wide enough to hold the higher bits reserved for bpf_type_flag.
93 */
94 --- a/kernel/bpf/verifier.c
95 +++ b/kernel/bpf/verifier.c
96 @@ -472,14 +472,9 @@ static bool arg_type_may_be_refcounted(e
97 return type == ARG_PTR_TO_SOCK_COMMON;
98 }
99
100 -static bool arg_type_may_be_null(enum bpf_arg_type type)
101 +static bool type_may_be_null(u32 type)
102 {
103 - return type == ARG_PTR_TO_MAP_VALUE_OR_NULL ||
104 - type == ARG_PTR_TO_MEM_OR_NULL ||
105 - type == ARG_PTR_TO_CTX_OR_NULL ||
106 - type == ARG_PTR_TO_SOCKET_OR_NULL ||
107 - type == ARG_PTR_TO_ALLOC_MEM_OR_NULL ||
108 - type == ARG_PTR_TO_STACK_OR_NULL;
109 + return type & PTR_MAYBE_NULL;
110 }
111
112 /* Determine whether the function releases some resources allocated by another
113 @@ -4963,9 +4958,8 @@ static int process_timer_func(struct bpf
114
115 static bool arg_type_is_mem_ptr(enum bpf_arg_type type)
116 {
117 - return type == ARG_PTR_TO_MEM ||
118 - type == ARG_PTR_TO_MEM_OR_NULL ||
119 - type == ARG_PTR_TO_UNINIT_MEM;
120 + return base_type(type) == ARG_PTR_TO_MEM ||
121 + base_type(type) == ARG_PTR_TO_UNINIT_MEM;
122 }
123
124 static bool arg_type_is_mem_size(enum bpf_arg_type type)
125 @@ -5102,31 +5096,26 @@ static const struct bpf_reg_types *compa
126 [ARG_PTR_TO_MAP_KEY] = &map_key_value_types,
127 [ARG_PTR_TO_MAP_VALUE] = &map_key_value_types,
128 [ARG_PTR_TO_UNINIT_MAP_VALUE] = &map_key_value_types,
129 - [ARG_PTR_TO_MAP_VALUE_OR_NULL] = &map_key_value_types,
130 [ARG_CONST_SIZE] = &scalar_types,
131 [ARG_CONST_SIZE_OR_ZERO] = &scalar_types,
132 [ARG_CONST_ALLOC_SIZE_OR_ZERO] = &scalar_types,
133 [ARG_CONST_MAP_PTR] = &const_map_ptr_types,
134 [ARG_PTR_TO_CTX] = &context_types,
135 - [ARG_PTR_TO_CTX_OR_NULL] = &context_types,
136 [ARG_PTR_TO_SOCK_COMMON] = &sock_types,
137 #ifdef CONFIG_NET
138 [ARG_PTR_TO_BTF_ID_SOCK_COMMON] = &btf_id_sock_common_types,
139 #endif
140 [ARG_PTR_TO_SOCKET] = &fullsock_types,
141 - [ARG_PTR_TO_SOCKET_OR_NULL] = &fullsock_types,
142 [ARG_PTR_TO_BTF_ID] = &btf_ptr_types,
143 [ARG_PTR_TO_SPIN_LOCK] = &spin_lock_types,
144 [ARG_PTR_TO_MEM] = &mem_types,
145 - [ARG_PTR_TO_MEM_OR_NULL] = &mem_types,
146 [ARG_PTR_TO_UNINIT_MEM] = &mem_types,
147 [ARG_PTR_TO_ALLOC_MEM] = &alloc_mem_types,
148 - [ARG_PTR_TO_ALLOC_MEM_OR_NULL] = &alloc_mem_types,
149 [ARG_PTR_TO_INT] = &int_ptr_types,
150 [ARG_PTR_TO_LONG] = &int_ptr_types,
151 [ARG_PTR_TO_PERCPU_BTF_ID] = &percpu_btf_ptr_types,
152 [ARG_PTR_TO_FUNC] = &func_ptr_types,
153 - [ARG_PTR_TO_STACK_OR_NULL] = &stack_ptr_types,
154 + [ARG_PTR_TO_STACK] = &stack_ptr_types,
155 [ARG_PTR_TO_CONST_STR] = &const_str_ptr_types,
156 [ARG_PTR_TO_TIMER] = &timer_types,
157 };
158 @@ -5140,7 +5129,7 @@ static int check_reg_type(struct bpf_ver
159 const struct bpf_reg_types *compatible;
160 int i, j;
161
162 - compatible = compatible_reg_types[arg_type];
163 + compatible = compatible_reg_types[base_type(arg_type)];
164 if (!compatible) {
165 verbose(env, "verifier internal error: unsupported arg type %d\n", arg_type);
166 return -EFAULT;
167 @@ -5221,15 +5210,14 @@ static int check_func_arg(struct bpf_ver
168 return -EACCES;
169 }
170
171 - if (arg_type == ARG_PTR_TO_MAP_VALUE ||
172 - arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE ||
173 - arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL) {
174 + if (base_type(arg_type) == ARG_PTR_TO_MAP_VALUE ||
175 + base_type(arg_type) == ARG_PTR_TO_UNINIT_MAP_VALUE) {
176 err = resolve_map_arg_type(env, meta, &arg_type);
177 if (err)
178 return err;
179 }
180
181 - if (register_is_null(reg) && arg_type_may_be_null(arg_type))
182 + if (register_is_null(reg) && type_may_be_null(arg_type))
183 /* A NULL register has a SCALAR_VALUE type, so skip
184 * type checking.
185 */
186 @@ -5298,10 +5286,11 @@ skip_type_check:
187 err = check_helper_mem_access(env, regno,
188 meta->map_ptr->key_size, false,
189 NULL);
190 - } else if (arg_type == ARG_PTR_TO_MAP_VALUE ||
191 - (arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL &&
192 - !register_is_null(reg)) ||
193 - arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE) {
194 + } else if (base_type(arg_type) == ARG_PTR_TO_MAP_VALUE ||
195 + base_type(arg_type) == ARG_PTR_TO_UNINIT_MAP_VALUE) {
196 + if (type_may_be_null(arg_type) && register_is_null(reg))
197 + return 0;
198 +
199 /* bpf_map_xxx(..., map_ptr, ..., value) call:
200 * check [value, value + map->value_size) validity
201 */

  ViewVC Help
Powered by ViewVC 1.1.30