Skip to content

Commit 717ae03

Browse files
committed
Merge: bpf: Fix bpf_sysctl_get_name prototype
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1144 JIRA: https://issues.redhat.com/browse/RHEL-93930 First patch fixes bpf_sysctl_get_name prototype. Second converts the selftest that uncovered the issue to prog_tests. The last one reintroduced the patch that revealed the issue. Signed-off-by: Jerome Marchand <jmarchan@redhat.com> Approved-by: Viktor Malik <vmalik@redhat.com> Approved-by: Gregory Bell <grbell@redhat.com> Merged-by: Julio Faracco <jfaracco@redhat.com>
2 parents 7303bc1 + 4fc5df8 commit 717ae03

17 files changed

+53
-88
lines changed

kernel/bpf/cgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2087,7 +2087,7 @@ static const struct bpf_func_proto bpf_sysctl_get_name_proto = {
20872087
.gpl_only = false,
20882088
.ret_type = RET_INTEGER,
20892089
.arg1_type = ARG_PTR_TO_CTX,
2090-
.arg2_type = ARG_PTR_TO_MEM,
2090+
.arg2_type = ARG_PTR_TO_MEM | MEM_WRITE,
20912091
.arg3_type = ARG_CONST_SIZE,
20922092
.arg4_type = ARG_ANYTHING,
20932093
};

kernel/bpf/verifier.c

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5306,7 +5306,7 @@ enum bpf_access_src {
53065306
static int check_stack_range_initialized(struct bpf_verifier_env *env,
53075307
int regno, int off, int access_size,
53085308
bool zero_size_allowed,
5309-
enum bpf_access_src type,
5309+
enum bpf_access_type type,
53105310
struct bpf_call_arg_meta *meta);
53115311

53125312
static struct bpf_reg_state *reg_state(struct bpf_verifier_env *env, int regno)
@@ -5339,7 +5339,7 @@ static int check_stack_read_var_off(struct bpf_verifier_env *env,
53395339
/* Note that we pass a NULL meta, so raw access will not be permitted.
53405340
*/
53415341
err = check_stack_range_initialized(env, ptr_regno, off, size,
5342-
false, ACCESS_DIRECT, NULL);
5342+
false, BPF_READ, NULL);
53435343
if (err)
53445344
return err;
53455345

@@ -7193,7 +7193,7 @@ static int check_stack_slot_within_bounds(struct bpf_verifier_env *env,
71937193
static int check_stack_access_within_bounds(
71947194
struct bpf_verifier_env *env,
71957195
int regno, int off, int access_size,
7196-
enum bpf_access_src src, enum bpf_access_type type)
7196+
enum bpf_access_type type)
71977197
{
71987198
struct bpf_reg_state *regs = cur_regs(env);
71997199
struct bpf_reg_state *reg = regs + regno;
@@ -7202,10 +7202,7 @@ static int check_stack_access_within_bounds(
72027202
int err;
72037203
char *err_extra;
72047204

7205-
if (src == ACCESS_HELPER)
7206-
/* We don't know if helpers are reading or writing (or both). */
7207-
err_extra = " indirect access to";
7208-
else if (type == BPF_READ)
7205+
if (type == BPF_READ)
72097206
err_extra = " read from";
72107207
else
72117208
err_extra = " write to";
@@ -7423,7 +7420,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
74237420

74247421
} else if (reg->type == PTR_TO_STACK) {
74257422
/* Basic bounds checks. */
7426-
err = check_stack_access_within_bounds(env, regno, off, size, ACCESS_DIRECT, t);
7423+
err = check_stack_access_within_bounds(env, regno, off, size, t);
74277424
if (err)
74287425
return err;
74297426

@@ -7643,13 +7640,11 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
76437640
static int check_stack_range_initialized(
76447641
struct bpf_verifier_env *env, int regno, int off,
76457642
int access_size, bool zero_size_allowed,
7646-
enum bpf_access_src type, struct bpf_call_arg_meta *meta)
7643+
enum bpf_access_type type, struct bpf_call_arg_meta *meta)
76477644
{
76487645
struct bpf_reg_state *reg = reg_state(env, regno);
76497646
struct bpf_func_state *state = func(env, reg);
76507647
int err, min_off, max_off, i, j, slot, spi;
7651-
char *err_extra = type == ACCESS_HELPER ? " indirect" : "";
7652-
enum bpf_access_type bounds_check_type;
76537648
/* Some accesses can write anything into the stack, others are
76547649
* read-only.
76557650
*/
@@ -7660,18 +7655,10 @@ static int check_stack_range_initialized(
76607655
return -EACCES;
76617656
}
76627657

7663-
if (type == ACCESS_HELPER) {
7664-
/* The bounds checks for writes are more permissive than for
7665-
* reads. However, if raw_mode is not set, we'll do extra
7666-
* checks below.
7667-
*/
7668-
bounds_check_type = BPF_WRITE;
7658+
if (type == BPF_WRITE)
76697659
clobber = true;
7670-
} else {
7671-
bounds_check_type = BPF_READ;
7672-
}
7673-
err = check_stack_access_within_bounds(env, regno, off, access_size,
7674-
type, bounds_check_type);
7660+
7661+
err = check_stack_access_within_bounds(env, regno, off, access_size, type);
76757662
if (err)
76767663
return err;
76777664

@@ -7688,8 +7675,8 @@ static int check_stack_range_initialized(
76887675
char tn_buf[48];
76897676

76907677
tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
7691-
verbose(env, "R%d%s variable offset stack access prohibited for !root, var_off=%s\n",
7692-
regno, err_extra, tn_buf);
7678+
verbose(env, "R%d variable offset stack access prohibited for !root, var_off=%s\n",
7679+
regno, tn_buf);
76937680
return -EACCES;
76947681
}
76957682
/* Only initialized buffer on stack is allowed to be accessed
@@ -7770,14 +7757,14 @@ static int check_stack_range_initialized(
77707757
}
77717758

77727759
if (tnum_is_const(reg->var_off)) {
7773-
verbose(env, "invalid%s read from stack R%d off %d+%d size %d\n",
7774-
err_extra, regno, min_off, i - min_off, access_size);
7760+
verbose(env, "invalid read from stack R%d off %d+%d size %d\n",
7761+
regno, min_off, i - min_off, access_size);
77757762
} else {
77767763
char tn_buf[48];
77777764

77787765
tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
7779-
verbose(env, "invalid%s read from stack R%d var_off %s+%d size %d\n",
7780-
err_extra, regno, tn_buf, i - min_off, access_size);
7766+
verbose(env, "invalid read from stack R%d var_off %s+%d size %d\n",
7767+
regno, tn_buf, i - min_off, access_size);
77817768
}
77827769
return -EACCES;
77837770
mark:
@@ -7852,7 +7839,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
78527839
return check_stack_range_initialized(
78537840
env,
78547841
regno, reg->off, access_size,
7855-
zero_size_allowed, ACCESS_HELPER, meta);
7842+
zero_size_allowed, access_type, meta);
78567843
case PTR_TO_BTF_ID:
78577844
return check_ptr_to_btf_access(env, regs, regno, reg->off,
78587845
access_size, BPF_READ, -1);

tools/testing/selftests/bpf/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ flow_dissector_load
2323
test_tcpnotify_user
2424
test_libbpf
2525
test_tcp_check_syncookie_user
26-
test_sysctl
2726
xdping
2827
test_cpp
2928
*.d

tools/testing/selftests/bpf/Makefile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ endif
7070
# Order correspond to 'make run_tests' order
7171
TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_progs \
7272
test_sock test_sockmap \
73-
test_tcpnotify_user test_sysctl \
73+
test_tcpnotify_user \
7474
test_progs-no_alu32
7575
TEST_INST_SUBDIRS := no_alu32
7676

@@ -220,7 +220,7 @@ ifeq ($(VMLINUX_BTF),)
220220
$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
221221
endif
222222

223-
# Define simple and short `make test_progs`, `make test_sysctl`, etc targets
223+
# Define simple and short `make test_progs`, `make test_maps`, etc targets
224224
# to build individual tests.
225225
# NOTE: Semicolon at the end is critical to override lib.mk's default static
226226
# rule for binaries.
@@ -330,7 +330,6 @@ $(OUTPUT)/test_sock: $(CGROUP_HELPERS) $(TESTING_HELPERS)
330330
$(OUTPUT)/test_sockmap: $(CGROUP_HELPERS) $(TESTING_HELPERS)
331331
$(OUTPUT)/test_tcpnotify_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) $(TRACE_HELPERS)
332332
$(OUTPUT)/test_sock_fields: $(CGROUP_HELPERS) $(TESTING_HELPERS)
333-
$(OUTPUT)/test_sysctl: $(CGROUP_HELPERS) $(TESTING_HELPERS)
334333
$(OUTPUT)/test_tag: $(TESTING_HELPERS)
335334
$(OUTPUT)/test_lirc_mode2_user: $(TESTING_HELPERS)
336335
$(OUTPUT)/xdping: $(TESTING_HELPERS)

tools/testing/selftests/bpf/test_sysctl.c renamed to tools/testing/selftests/bpf/prog_tests/test_sysctl.c

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,8 @@
11
// SPDX-License-Identifier: GPL-2.0
22
// Copyright (c) 2019 Facebook
33

4-
#include <fcntl.h>
5-
#include <stdint.h>
6-
#include <stdio.h>
7-
#include <stdlib.h>
8-
#include <string.h>
9-
#include <unistd.h>
10-
11-
#include <linux/filter.h>
12-
13-
#include <bpf/bpf.h>
14-
#include <bpf/libbpf.h>
15-
16-
#include <bpf/bpf_endian.h>
17-
#include "bpf_util.h"
4+
#include "test_progs.h"
185
#include "cgroup_helpers.h"
19-
#include "testing_helpers.h"
206

217
#define CG_PATH "/foo"
228
#define MAX_INSNS 512
@@ -1608,26 +1594,19 @@ static int run_tests(int cgfd)
16081594
return fails ? -1 : 0;
16091595
}
16101596

1611-
int main(int argc, char **argv)
1597+
void test_sysctl(void)
16121598
{
1613-
int cgfd = -1;
1614-
int err = 0;
1599+
int cgfd;
16151600

16161601
cgfd = cgroup_setup_and_join(CG_PATH);
1617-
if (cgfd < 0)
1618-
goto err;
1602+
if (!ASSERT_OK_FD(cgfd < 0, "create_cgroup"))
1603+
goto out;
16191604

1620-
/* Use libbpf 1.0 API mode */
1621-
libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1605+
if (!ASSERT_OK(run_tests(cgfd), "run_tests"))
1606+
goto out;
16221607

1623-
if (run_tests(cgfd))
1624-
goto err;
1625-
1626-
goto out;
1627-
err:
1628-
err = -1;
16291608
out:
16301609
close(cgfd);
16311610
cleanup_cgroup_environment();
1632-
return err;
1611+
return;
16331612
}

tools/testing/selftests/bpf/progs/dynptr_fail.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ int ringbuf_invalid_api(void *ctx)
192192

193193
/* Can't add a dynptr to a map */
194194
SEC("?raw_tp")
195-
__failure __msg("invalid indirect read from stack")
195+
__failure __msg("invalid read from stack")
196196
int add_dynptr_to_map1(void *ctx)
197197
{
198198
struct bpf_dynptr ptr;
@@ -210,7 +210,7 @@ int add_dynptr_to_map1(void *ctx)
210210

211211
/* Can't add a struct with an embedded dynptr to a map */
212212
SEC("?raw_tp")
213-
__failure __msg("invalid indirect read from stack")
213+
__failure __msg("invalid read from stack")
214214
int add_dynptr_to_map2(void *ctx)
215215
{
216216
struct test_info x;
@@ -398,7 +398,7 @@ int data_slice_missing_null_check2(void *ctx)
398398
* dynptr argument
399399
*/
400400
SEC("?raw_tp")
401-
__failure __msg("invalid indirect read from stack")
401+
__failure __msg("invalid read from stack")
402402
int invalid_helper1(void *ctx)
403403
{
404404
struct bpf_dynptr ptr;

tools/testing/selftests/bpf/progs/test_global_func10.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ __noinline int foo(const struct Big *big)
2626
}
2727

2828
SEC("cgroup_skb/ingress")
29-
__failure __msg("invalid indirect access to stack")
29+
__failure __msg("invalid read from stack")
3030
int global_func10(struct __sk_buff *skb)
3131
{
3232
const struct Small small = {.x = skb->len };

tools/testing/selftests/bpf/progs/uninit_stack.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ __naked int helper_uninit_to_misc(void *ctx)
7070
r1 = r10; \
7171
r1 += -128; \
7272
r2 = 32; \
73-
call %[bpf_trace_printk]; \
73+
r3 = 0; \
74+
call %[bpf_probe_read_user]; \
7475
/* Call to dummy() forces print_verifier_state(..., true), \
7576
* thus showing the stack state, matched by __msg(). \
7677
*/ \
@@ -79,7 +80,7 @@ __naked int helper_uninit_to_misc(void *ctx)
7980
exit; \
8081
"
8182
:
82-
: __imm(bpf_trace_printk),
83+
: __imm(bpf_probe_read_user),
8384
__imm(dummy)
8485
: __clobber_all);
8586
}

tools/testing/selftests/bpf/progs/verifier_basic_stack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ __naked void stack_out_of_bounds(void)
2828
SEC("socket")
2929
__description("uninitialized stack1")
3030
__success __log_level(4) __msg("stack depth 8")
31-
__failure_unpriv __msg_unpriv("invalid indirect read from stack")
31+
__failure_unpriv __msg_unpriv("invalid read from stack")
3232
__naked void uninitialized_stack1(void)
3333
{
3434
asm volatile (" \

tools/testing/selftests/bpf/progs/verifier_const_or.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ __naked void constant_should_keep_constant_type(void)
2525

2626
SEC("tracepoint")
2727
__description("constant register |= constant should not bypass stack boundary checks")
28-
__failure __msg("invalid indirect access to stack R1 off=-48 size=58")
28+
__failure __msg("invalid write to stack R1 off=-48 size=58")
2929
__naked void not_bypass_stack_boundary_checks_1(void)
3030
{
3131
asm volatile (" \
@@ -62,7 +62,7 @@ __naked void register_should_keep_constant_type(void)
6262

6363
SEC("tracepoint")
6464
__description("constant register |= constant register should not bypass stack boundary checks")
65-
__failure __msg("invalid indirect access to stack R1 off=-48 size=58")
65+
__failure __msg("invalid write to stack R1 off=-48 size=58")
6666
__naked void not_bypass_stack_boundary_checks_2(void)
6767
{
6868
asm volatile (" \

0 commit comments

Comments
 (0)