Skip to content

Commit 5f27b3f

Browse files
committed
bpf: Replace PTR_TO_XXX_OR_NULL with PTR_TO_XXX | PTR_MAYBE_NULL
jira VULN-136 cve-pre CVE-2022-0500 commit-author Hao Luo <[email protected]> commit c25b2ae upstream-diff This kernel doesn't have map_uid in bpf_reg_state so a minor conflict was resolved while cherry picking. This kernel is also missing some fields in bpf_verifier_env so a minor conflict was resolved there as well We have introduced a new type to make bpf_reg composable, by allocating bits in the type to represent flags. One of the flags is PTR_MAYBE_NULL which indicates a pointer may be NULL. This patch switches the qualified reg_types to use this flag. The reg_types changed in this patch include: 1. PTR_TO_MAP_VALUE_OR_NULL 2. PTR_TO_SOCKET_OR_NULL 3. PTR_TO_SOCK_COMMON_OR_NULL 4. PTR_TO_TCP_SOCK_OR_NULL 5. PTR_TO_BTF_ID_OR_NULL 6. PTR_TO_MEM_OR_NULL 7. PTR_TO_RDONLY_BUF_OR_NULL 8. PTR_TO_RDWR_BUF_OR_NULL Signed-off-by: Hao Luo <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit c25b2ae) Signed-off-by: Brett Mastbergen <[email protected]>
1 parent a85fa58 commit 5f27b3f

File tree

7 files changed

+147
-187
lines changed

7 files changed

+147
-187
lines changed

include/linux/bpf.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,18 +446,15 @@ enum bpf_reg_type {
446446
PTR_TO_CTX, /* reg points to bpf_context */
447447
CONST_PTR_TO_MAP, /* reg points to struct bpf_map */
448448
PTR_TO_MAP_VALUE, /* reg points to map element value */
449-
PTR_TO_MAP_VALUE_OR_NULL,/* points to map elem value or NULL */
449+
PTR_TO_MAP_KEY, /* reg points to a map element key */
450450
PTR_TO_STACK, /* reg == frame_pointer + offset */
451451
PTR_TO_PACKET_META, /* skb->data - meta_len */
452452
PTR_TO_PACKET, /* reg points to skb->data */
453453
PTR_TO_PACKET_END, /* skb->data + headlen */
454454
PTR_TO_FLOW_KEYS, /* reg points to bpf_flow_keys */
455455
PTR_TO_SOCKET, /* reg points to struct bpf_sock */
456-
PTR_TO_SOCKET_OR_NULL, /* reg points to struct bpf_sock or NULL */
457456
PTR_TO_SOCK_COMMON, /* reg points to sock_common */
458-
PTR_TO_SOCK_COMMON_OR_NULL, /* reg points to sock_common or NULL */
459457
PTR_TO_TCP_SOCK, /* reg points to struct tcp_sock */
460-
PTR_TO_TCP_SOCK_OR_NULL, /* reg points to struct tcp_sock or NULL */
461458
PTR_TO_TP_BUFFER, /* reg points to a writable raw tp's buffer */
462459
PTR_TO_XDP_SOCK, /* reg points to struct xdp_sock */
463460
/* PTR_TO_BTF_ID points to a kernel struct that does not need
@@ -475,18 +472,21 @@ enum bpf_reg_type {
475472
* been checked for null. Used primarily to inform the verifier
476473
* an explicit null check is required for this struct.
477474
*/
478-
PTR_TO_BTF_ID_OR_NULL,
479475
PTR_TO_MEM, /* reg points to valid memory region */
480-
PTR_TO_MEM_OR_NULL, /* reg points to valid memory region or NULL */
481476
PTR_TO_RDONLY_BUF, /* reg points to a readonly buffer */
482-
PTR_TO_RDONLY_BUF_OR_NULL, /* reg points to a readonly buffer or NULL */
483477
PTR_TO_RDWR_BUF, /* reg points to a read/write buffer */
484-
PTR_TO_RDWR_BUF_OR_NULL, /* reg points to a read/write buffer or NULL */
485478
PTR_TO_PERCPU_BTF_ID, /* reg points to a percpu kernel variable */
486479
PTR_TO_FUNC, /* reg points to a bpf program function */
487-
PTR_TO_MAP_KEY, /* reg points to a map element key */
488480
__BPF_REG_TYPE_MAX,
489481

482+
/* Extended reg_types. */
483+
PTR_TO_MAP_VALUE_OR_NULL = PTR_MAYBE_NULL | PTR_TO_MAP_VALUE,
484+
PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | PTR_TO_SOCKET,
485+
PTR_TO_SOCK_COMMON_OR_NULL = PTR_MAYBE_NULL | PTR_TO_SOCK_COMMON,
486+
PTR_TO_TCP_SOCK_OR_NULL = PTR_MAYBE_NULL | PTR_TO_TCP_SOCK,
487+
PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | PTR_TO_BTF_ID,
488+
PTR_TO_MEM_OR_NULL = PTR_MAYBE_NULL | PTR_TO_MEM,
489+
490490
/* This must be the last entry. Its purpose is to ensure the enum is
491491
* wide enough to hold the higher bits reserved for bpf_type_flag.
492492
*/

include/linux/bpf_verifier.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* that converting umax_value to int cannot overflow.
1919
*/
2020
#define BPF_MAX_VAR_SIZ (1 << 29)
21+
/* size of type_str_buf in bpf_verifier. */
22+
#define TYPE_STR_BUF_LEN 64
2123

2224
/* Liveness marks, used for registers and spilled-regs (in stack slots).
2325
* Read marks propagate upwards until they find a write mark; they record that
@@ -452,6 +454,8 @@ struct bpf_verifier_env {
452454
/* longest register parentage chain walked for liveness marking */
453455
u32 longest_mark_read_walk;
454456
bpfptr_t fd_array;
457+
/* buffer used in reg_type_str() to generate reg_type string */
458+
char type_str_buf[TYPE_STR_BUF_LEN];
455459
};
456460

457461
__printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log,

kernel/bpf/btf.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4753,10 +4753,13 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
47534753
/* check for PTR_TO_RDONLY_BUF_OR_NULL or PTR_TO_RDWR_BUF_OR_NULL */
47544754
for (i = 0; i < prog->aux->ctx_arg_info_size; i++) {
47554755
const struct bpf_ctx_arg_aux *ctx_arg_info = &prog->aux->ctx_arg_info[i];
4756+
u32 type, flag;
47564757

4758+
type = base_type(ctx_arg_info->reg_type);
4759+
flag = type_flag(ctx_arg_info->reg_type);
47574760
if (ctx_arg_info->offset == off &&
4758-
(ctx_arg_info->reg_type == PTR_TO_RDONLY_BUF_OR_NULL ||
4759-
ctx_arg_info->reg_type == PTR_TO_RDWR_BUF_OR_NULL)) {
4761+
(type == PTR_TO_RDWR_BUF || type == PTR_TO_RDONLY_BUF) &&
4762+
(flag & PTR_MAYBE_NULL)) {
47604763
info->reg_type = ctx_arg_info->reg_type;
47614764
return true;
47624765
}

kernel/bpf/map_iter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ static const struct bpf_iter_reg bpf_map_elem_reg_info = {
174174
.ctx_arg_info_size = 2,
175175
.ctx_arg_info = {
176176
{ offsetof(struct bpf_iter__bpf_map_elem, key),
177-
PTR_TO_RDONLY_BUF_OR_NULL },
177+
PTR_TO_RDONLY_BUF | PTR_MAYBE_NULL },
178178
{ offsetof(struct bpf_iter__bpf_map_elem, value),
179-
PTR_TO_RDWR_BUF_OR_NULL },
179+
PTR_TO_RDWR_BUF | PTR_MAYBE_NULL },
180180
},
181181
};
182182

0 commit comments

Comments
 (0)