Commit 26d6506a authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'Dynptr refactorings'

Kumar Kartikeya Dwivedi says:

====================

This is part 1 of https://lore.kernel.org/bpf/20221018135920.726360-1-memxor@gmail.com.
This thread also gives some background on why the refactor is being done:
https://lore.kernel.org/bpf/CAEf4Bzb4beTHgVo+G+jehSj8oCeAjRbRcm6MRe=Gr+cajRBwEw@mail.gmail.com

As requested in patch 6 by Alexei, it only includes patches which
refactors the code, on top of which further fixes will be made in part
2. The refactor itself fixes another issue as a side effect. No
functional change is intended (except a few modified log messages).

Changelog:
----------
v1 -> v2
v1: https://lore.kernel.org/bpf/20221115000130.1967465-1-memxor@gmail.com

 * Address feedback from Joanne and David, add acks

Fixes v1 -> v1
Fixes v1: https://lore.kernel.org/bpf/20221018135920.726360-1-memxor@gmail.com

 * Collect acks from Joanne and David
 * Fix misc nits pointed out by Joanne, David
 * Split move of reg->off alignment check for dynptr into separate
   change (Alexei)
====================
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 6798152b 292064cc
...@@ -775,7 +775,7 @@ enum bpf_reg_type { ...@@ -775,7 +775,7 @@ enum bpf_reg_type {
PTR_TO_MEM, /* reg points to valid memory region */ PTR_TO_MEM, /* reg points to valid memory region */
PTR_TO_BUF, /* reg points to a read/write buffer */ PTR_TO_BUF, /* reg points to a read/write buffer */
PTR_TO_FUNC, /* reg points to a bpf program function */ PTR_TO_FUNC, /* reg points to a bpf program function */
PTR_TO_DYNPTR, /* reg points to a dynptr */ CONST_PTR_TO_DYNPTR, /* reg points to a const struct bpf_dynptr */
__BPF_REG_TYPE_MAX, __BPF_REG_TYPE_MAX,
/* Extended reg_types. */ /* Extended reg_types. */
...@@ -2828,7 +2828,7 @@ void bpf_dynptr_init(struct bpf_dynptr_kern *ptr, void *data, ...@@ -2828,7 +2828,7 @@ void bpf_dynptr_init(struct bpf_dynptr_kern *ptr, void *data,
enum bpf_dynptr_type type, u32 offset, u32 size); enum bpf_dynptr_type type, u32 offset, u32 size);
void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr); void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr);
int bpf_dynptr_check_size(u32 size); int bpf_dynptr_check_size(u32 size);
u32 bpf_dynptr_get_size(struct bpf_dynptr_kern *ptr); u32 bpf_dynptr_get_size(const struct bpf_dynptr_kern *ptr);
#ifdef CONFIG_BPF_LSM #ifdef CONFIG_BPF_LSM
void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype); void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype);
......
...@@ -615,11 +615,9 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env, ...@@ -615,11 +615,9 @@ int check_func_arg_reg_off(struct bpf_verifier_env *env,
enum bpf_arg_type arg_type); enum bpf_arg_type arg_type);
int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg, int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
u32 regno, u32 mem_size); u32 regno, u32 mem_size);
bool is_dynptr_reg_valid_init(struct bpf_verifier_env *env, struct bpf_call_arg_meta;
struct bpf_reg_state *reg); int process_dynptr_func(struct bpf_verifier_env *env, int regno,
bool is_dynptr_type_expected(struct bpf_verifier_env *env, enum bpf_arg_type arg_type, struct bpf_call_arg_meta *meta);
struct bpf_reg_state *reg,
enum bpf_arg_type arg_type);
/* this lives here instead of in bpf.h because it needs to dereference tgt_prog */ /* this lives here instead of in bpf.h because it needs to dereference tgt_prog */
static inline u64 bpf_trampoline_compute_key(const struct bpf_prog *tgt_prog, static inline u64 bpf_trampoline_compute_key(const struct bpf_prog *tgt_prog,
......
...@@ -5293,7 +5293,7 @@ union bpf_attr { ...@@ -5293,7 +5293,7 @@ union bpf_attr {
* Return * Return
* Nothing. Always succeeds. * Nothing. Always succeeds.
* *
* long bpf_dynptr_read(void *dst, u32 len, struct bpf_dynptr *src, u32 offset, u64 flags) * long bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr *src, u32 offset, u64 flags)
* Description * Description
* Read *len* bytes from *src* into *dst*, starting from *offset* * Read *len* bytes from *src* into *dst*, starting from *offset*
* into *src*. * into *src*.
...@@ -5303,7 +5303,7 @@ union bpf_attr { ...@@ -5303,7 +5303,7 @@ union bpf_attr {
* of *src*'s data, -EINVAL if *src* is an invalid dynptr or if * of *src*'s data, -EINVAL if *src* is an invalid dynptr or if
* *flags* is not 0. * *flags* is not 0.
* *
* long bpf_dynptr_write(struct bpf_dynptr *dst, u32 offset, void *src, u32 len, u64 flags) * long bpf_dynptr_write(const struct bpf_dynptr *dst, u32 offset, void *src, u32 len, u64 flags)
* Description * Description
* Write *len* bytes from *src* into *dst*, starting from *offset* * Write *len* bytes from *src* into *dst*, starting from *offset*
* into *dst*. * into *dst*.
...@@ -5313,7 +5313,7 @@ union bpf_attr { ...@@ -5313,7 +5313,7 @@ union bpf_attr {
* of *dst*'s data, -EINVAL if *dst* is an invalid dynptr or if *dst* * of *dst*'s data, -EINVAL if *dst* is an invalid dynptr or if *dst*
* is a read-only dynptr or if *flags* is not 0. * is a read-only dynptr or if *flags* is not 0.
* *
* void *bpf_dynptr_data(struct bpf_dynptr *ptr, u32 offset, u32 len) * void *bpf_dynptr_data(const struct bpf_dynptr *ptr, u32 offset, u32 len)
* Description * Description
* Get a pointer to the underlying dynptr data. * Get a pointer to the underlying dynptr data.
* *
...@@ -5414,7 +5414,7 @@ union bpf_attr { ...@@ -5414,7 +5414,7 @@ union bpf_attr {
* Drain samples from the specified user ring buffer, and invoke * Drain samples from the specified user ring buffer, and invoke
* the provided callback for each such sample: * the provided callback for each such sample:
* *
* long (\*callback_fn)(struct bpf_dynptr \*dynptr, void \*ctx); * long (\*callback_fn)(const struct bpf_dynptr \*dynptr, void \*ctx);
* *
* If **callback_fn** returns 0, the helper will continue to try * If **callback_fn** returns 0, the helper will continue to try
* and drain the next sample, up to a maximum of * and drain the next sample, up to a maximum of
......
...@@ -1404,7 +1404,7 @@ static const struct bpf_func_proto bpf_kptr_xchg_proto = { ...@@ -1404,7 +1404,7 @@ static const struct bpf_func_proto bpf_kptr_xchg_proto = {
#define DYNPTR_SIZE_MASK 0xFFFFFF #define DYNPTR_SIZE_MASK 0xFFFFFF
#define DYNPTR_RDONLY_BIT BIT(31) #define DYNPTR_RDONLY_BIT BIT(31)
static bool bpf_dynptr_is_rdonly(struct bpf_dynptr_kern *ptr) static bool bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr)
{ {
return ptr->size & DYNPTR_RDONLY_BIT; return ptr->size & DYNPTR_RDONLY_BIT;
} }
...@@ -1414,7 +1414,7 @@ static void bpf_dynptr_set_type(struct bpf_dynptr_kern *ptr, enum bpf_dynptr_typ ...@@ -1414,7 +1414,7 @@ static void bpf_dynptr_set_type(struct bpf_dynptr_kern *ptr, enum bpf_dynptr_typ
ptr->size |= type << DYNPTR_TYPE_SHIFT; ptr->size |= type << DYNPTR_TYPE_SHIFT;
} }
u32 bpf_dynptr_get_size(struct bpf_dynptr_kern *ptr) u32 bpf_dynptr_get_size(const struct bpf_dynptr_kern *ptr)
{ {
return ptr->size & DYNPTR_SIZE_MASK; return ptr->size & DYNPTR_SIZE_MASK;
} }
...@@ -1438,7 +1438,7 @@ void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr) ...@@ -1438,7 +1438,7 @@ void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr)
memset(ptr, 0, sizeof(*ptr)); memset(ptr, 0, sizeof(*ptr));
} }
static int bpf_dynptr_check_off_len(struct bpf_dynptr_kern *ptr, u32 offset, u32 len) static int bpf_dynptr_check_off_len(const struct bpf_dynptr_kern *ptr, u32 offset, u32 len)
{ {
u32 size = bpf_dynptr_get_size(ptr); u32 size = bpf_dynptr_get_size(ptr);
...@@ -1483,7 +1483,7 @@ static const struct bpf_func_proto bpf_dynptr_from_mem_proto = { ...@@ -1483,7 +1483,7 @@ static const struct bpf_func_proto bpf_dynptr_from_mem_proto = {
.arg4_type = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT, .arg4_type = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT,
}; };
BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, struct bpf_dynptr_kern *, src, BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, const struct bpf_dynptr_kern *, src,
u32, offset, u64, flags) u32, offset, u64, flags)
{ {
int err; int err;
...@@ -1495,7 +1495,11 @@ BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, struct bpf_dynptr_kern *, src ...@@ -1495,7 +1495,11 @@ BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, struct bpf_dynptr_kern *, src
if (err) if (err)
return err; return err;
memcpy(dst, src->data + src->offset + offset, len); /* Source and destination may possibly overlap, hence use memmove to
* copy the data. E.g. bpf_dynptr_from_mem may create two dynptr
* pointing to overlapping PTR_TO_MAP_VALUE regions.
*/
memmove(dst, src->data + src->offset + offset, len);
return 0; return 0;
} }
...@@ -1506,12 +1510,12 @@ static const struct bpf_func_proto bpf_dynptr_read_proto = { ...@@ -1506,12 +1510,12 @@ static const struct bpf_func_proto bpf_dynptr_read_proto = {
.ret_type = RET_INTEGER, .ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_UNINIT_MEM, .arg1_type = ARG_PTR_TO_UNINIT_MEM,
.arg2_type = ARG_CONST_SIZE_OR_ZERO, .arg2_type = ARG_CONST_SIZE_OR_ZERO,
.arg3_type = ARG_PTR_TO_DYNPTR, .arg3_type = ARG_PTR_TO_DYNPTR | MEM_RDONLY,
.arg4_type = ARG_ANYTHING, .arg4_type = ARG_ANYTHING,
.arg5_type = ARG_ANYTHING, .arg5_type = ARG_ANYTHING,
}; };
BPF_CALL_5(bpf_dynptr_write, struct bpf_dynptr_kern *, dst, u32, offset, void *, src, BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u32, offset, void *, src,
u32, len, u64, flags) u32, len, u64, flags)
{ {
int err; int err;
...@@ -1523,7 +1527,11 @@ BPF_CALL_5(bpf_dynptr_write, struct bpf_dynptr_kern *, dst, u32, offset, void *, ...@@ -1523,7 +1527,11 @@ BPF_CALL_5(bpf_dynptr_write, struct bpf_dynptr_kern *, dst, u32, offset, void *,
if (err) if (err)
return err; return err;
memcpy(dst->data + dst->offset + offset, src, len); /* Source and destination may possibly overlap, hence use memmove to
* copy the data. E.g. bpf_dynptr_from_mem may create two dynptr
* pointing to overlapping PTR_TO_MAP_VALUE regions.
*/
memmove(dst->data + dst->offset + offset, src, len);
return 0; return 0;
} }
...@@ -1532,14 +1540,14 @@ static const struct bpf_func_proto bpf_dynptr_write_proto = { ...@@ -1532,14 +1540,14 @@ static const struct bpf_func_proto bpf_dynptr_write_proto = {
.func = bpf_dynptr_write, .func = bpf_dynptr_write,
.gpl_only = false, .gpl_only = false,
.ret_type = RET_INTEGER, .ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_DYNPTR, .arg1_type = ARG_PTR_TO_DYNPTR | MEM_RDONLY,
.arg2_type = ARG_ANYTHING, .arg2_type = ARG_ANYTHING,
.arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY,
.arg4_type = ARG_CONST_SIZE_OR_ZERO, .arg4_type = ARG_CONST_SIZE_OR_ZERO,
.arg5_type = ARG_ANYTHING, .arg5_type = ARG_ANYTHING,
}; };
BPF_CALL_3(bpf_dynptr_data, struct bpf_dynptr_kern *, ptr, u32, offset, u32, len) BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u32, len)
{ {
int err; int err;
...@@ -1560,7 +1568,7 @@ static const struct bpf_func_proto bpf_dynptr_data_proto = { ...@@ -1560,7 +1568,7 @@ static const struct bpf_func_proto bpf_dynptr_data_proto = {
.func = bpf_dynptr_data, .func = bpf_dynptr_data,
.gpl_only = false, .gpl_only = false,
.ret_type = RET_PTR_TO_DYNPTR_MEM_OR_NULL, .ret_type = RET_PTR_TO_DYNPTR_MEM_OR_NULL,
.arg1_type = ARG_PTR_TO_DYNPTR, .arg1_type = ARG_PTR_TO_DYNPTR | MEM_RDONLY,
.arg2_type = ARG_ANYTHING, .arg2_type = ARG_ANYTHING,
.arg3_type = ARG_CONST_ALLOC_SIZE_OR_ZERO, .arg3_type = ARG_CONST_ALLOC_SIZE_OR_ZERO,
}; };
......
This diff is collapsed.
...@@ -752,6 +752,7 @@ class PrinterHelpers(Printer): ...@@ -752,6 +752,7 @@ class PrinterHelpers(Printer):
'struct bpf_timer', 'struct bpf_timer',
'struct mptcp_sock', 'struct mptcp_sock',
'struct bpf_dynptr', 'struct bpf_dynptr',
'const struct bpf_dynptr',
'struct iphdr', 'struct iphdr',
'struct ipv6hdr', 'struct ipv6hdr',
} }
......
...@@ -5293,7 +5293,7 @@ union bpf_attr { ...@@ -5293,7 +5293,7 @@ union bpf_attr {
* Return * Return
* Nothing. Always succeeds. * Nothing. Always succeeds.
* *
* long bpf_dynptr_read(void *dst, u32 len, struct bpf_dynptr *src, u32 offset, u64 flags) * long bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr *src, u32 offset, u64 flags)
* Description * Description
* Read *len* bytes from *src* into *dst*, starting from *offset* * Read *len* bytes from *src* into *dst*, starting from *offset*
* into *src*. * into *src*.
...@@ -5303,7 +5303,7 @@ union bpf_attr { ...@@ -5303,7 +5303,7 @@ union bpf_attr {
* of *src*'s data, -EINVAL if *src* is an invalid dynptr or if * of *src*'s data, -EINVAL if *src* is an invalid dynptr or if
* *flags* is not 0. * *flags* is not 0.
* *
* long bpf_dynptr_write(struct bpf_dynptr *dst, u32 offset, void *src, u32 len, u64 flags) * long bpf_dynptr_write(const struct bpf_dynptr *dst, u32 offset, void *src, u32 len, u64 flags)
* Description * Description
* Write *len* bytes from *src* into *dst*, starting from *offset* * Write *len* bytes from *src* into *dst*, starting from *offset*
* into *dst*. * into *dst*.
...@@ -5313,7 +5313,7 @@ union bpf_attr { ...@@ -5313,7 +5313,7 @@ union bpf_attr {
* of *dst*'s data, -EINVAL if *dst* is an invalid dynptr or if *dst* * of *dst*'s data, -EINVAL if *dst* is an invalid dynptr or if *dst*
* is a read-only dynptr or if *flags* is not 0. * is a read-only dynptr or if *flags* is not 0.
* *
* void *bpf_dynptr_data(struct bpf_dynptr *ptr, u32 offset, u32 len) * void *bpf_dynptr_data(const struct bpf_dynptr *ptr, u32 offset, u32 len)
* Description * Description
* Get a pointer to the underlying dynptr data. * Get a pointer to the underlying dynptr data.
* *
...@@ -5414,7 +5414,7 @@ union bpf_attr { ...@@ -5414,7 +5414,7 @@ union bpf_attr {
* Drain samples from the specified user ring buffer, and invoke * Drain samples from the specified user ring buffer, and invoke
* the provided callback for each such sample: * the provided callback for each such sample:
* *
* long (\*callback_fn)(struct bpf_dynptr \*dynptr, void \*ctx); * long (\*callback_fn)(const struct bpf_dynptr \*dynptr, void \*ctx);
* *
* If **callback_fn** returns 0, the helper will continue to try * If **callback_fn** returns 0, the helper will continue to try
* and drain the next sample, up to a maximum of * and drain the next sample, up to a maximum of
......
...@@ -18,11 +18,8 @@ static struct { ...@@ -18,11 +18,8 @@ static struct {
const char *expected_verifier_err_msg; const char *expected_verifier_err_msg;
int expected_runtime_err; int expected_runtime_err;
} kfunc_dynptr_tests[] = { } kfunc_dynptr_tests[] = {
{"dynptr_type_not_supp", {"not_valid_dynptr", "Expected an initialized dynptr as arg #1", 0},
"arg#0 pointer type STRUCT bpf_dynptr_kern points to unsupported dynamic pointer type", 0}, {"not_ptr_to_stack", "arg#0 expected pointer to stack or dynptr_ptr", 0},
{"not_valid_dynptr",
"arg#0 pointer type STRUCT bpf_dynptr_kern must be valid and initialized", 0},
{"not_ptr_to_stack", "arg#0 expected pointer to stack", 0},
{"dynptr_data_null", NULL, -EBADMSG}, {"dynptr_data_null", NULL, -EBADMSG},
}; };
......
...@@ -673,9 +673,11 @@ static struct { ...@@ -673,9 +673,11 @@ static struct {
{"user_ringbuf_callback_write_forbidden", "invalid mem access 'dynptr_ptr'"}, {"user_ringbuf_callback_write_forbidden", "invalid mem access 'dynptr_ptr'"},
{"user_ringbuf_callback_null_context_write", "invalid mem access 'scalar'"}, {"user_ringbuf_callback_null_context_write", "invalid mem access 'scalar'"},
{"user_ringbuf_callback_null_context_read", "invalid mem access 'scalar'"}, {"user_ringbuf_callback_null_context_read", "invalid mem access 'scalar'"},
{"user_ringbuf_callback_discard_dynptr", "arg 1 is an unacquired reference"}, {"user_ringbuf_callback_discard_dynptr", "cannot release unowned const bpf_dynptr"},
{"user_ringbuf_callback_submit_dynptr", "arg 1 is an unacquired reference"}, {"user_ringbuf_callback_submit_dynptr", "cannot release unowned const bpf_dynptr"},
{"user_ringbuf_callback_invalid_return", "At callback return the register R0 has value"}, {"user_ringbuf_callback_invalid_return", "At callback return the register R0 has value"},
{"user_ringbuf_callback_reinit_dynptr_mem", "Dynptr has to be an uninitialized dynptr"},
{"user_ringbuf_callback_reinit_dynptr_ringbuf", "Dynptr has to be an uninitialized dynptr"},
}; };
#define SUCCESS_TEST(_func) { _func, #_func } #define SUCCESS_TEST(_func) { _func, #_func }
......
...@@ -32,18 +32,6 @@ int err, pid; ...@@ -32,18 +32,6 @@ int err, pid;
char _license[] SEC("license") = "GPL"; char _license[] SEC("license") = "GPL";
SEC("?lsm.s/bpf")
int BPF_PROG(dynptr_type_not_supp, int cmd, union bpf_attr *attr,
unsigned int size)
{
char write_data[64] = "hello there, world!!";
struct bpf_dynptr ptr;
bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(write_data), 0, &ptr);
return bpf_verify_pkcs7_signature(&ptr, &ptr, NULL);
}
SEC("?lsm.s/bpf") SEC("?lsm.s/bpf")
int BPF_PROG(not_valid_dynptr, int cmd, union bpf_attr *attr, unsigned int size) int BPF_PROG(not_valid_dynptr, int cmd, union bpf_attr *attr, unsigned int size)
{ {
......
...@@ -18,6 +18,13 @@ struct { ...@@ -18,6 +18,13 @@ struct {
__uint(type, BPF_MAP_TYPE_USER_RINGBUF); __uint(type, BPF_MAP_TYPE_USER_RINGBUF);
} user_ringbuf SEC(".maps"); } user_ringbuf SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 2);
} ringbuf SEC(".maps");
static int map_value;
static long static long
bad_access1(struct bpf_dynptr *dynptr, void *context) bad_access1(struct bpf_dynptr *dynptr, void *context)
{ {
...@@ -32,7 +39,7 @@ bad_access1(struct bpf_dynptr *dynptr, void *context) ...@@ -32,7 +39,7 @@ bad_access1(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to read before the pointer. * not be able to read before the pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_bad_access1(void *ctx) int user_ringbuf_callback_bad_access1(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, bad_access1, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, bad_access1, NULL, 0);
...@@ -54,7 +61,7 @@ bad_access2(struct bpf_dynptr *dynptr, void *context) ...@@ -54,7 +61,7 @@ bad_access2(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to read past the end of the pointer. * not be able to read past the end of the pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_bad_access2(void *ctx) int user_ringbuf_callback_bad_access2(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, bad_access2, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, bad_access2, NULL, 0);
...@@ -73,7 +80,7 @@ write_forbidden(struct bpf_dynptr *dynptr, void *context) ...@@ -73,7 +80,7 @@ write_forbidden(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to write to that pointer. * not be able to write to that pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_write_forbidden(void *ctx) int user_ringbuf_callback_write_forbidden(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, write_forbidden, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, write_forbidden, NULL, 0);
...@@ -92,7 +99,7 @@ null_context_write(struct bpf_dynptr *dynptr, void *context) ...@@ -92,7 +99,7 @@ null_context_write(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to write to that pointer. * not be able to write to that pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_null_context_write(void *ctx) int user_ringbuf_callback_null_context_write(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, null_context_write, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, null_context_write, NULL, 0);
...@@ -113,7 +120,7 @@ null_context_read(struct bpf_dynptr *dynptr, void *context) ...@@ -113,7 +120,7 @@ null_context_read(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to write to that pointer. * not be able to write to that pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_null_context_read(void *ctx) int user_ringbuf_callback_null_context_read(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, null_context_read, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, null_context_read, NULL, 0);
...@@ -132,7 +139,7 @@ try_discard_dynptr(struct bpf_dynptr *dynptr, void *context) ...@@ -132,7 +139,7 @@ try_discard_dynptr(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to read past the end of the pointer. * not be able to read past the end of the pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_discard_dynptr(void *ctx) int user_ringbuf_callback_discard_dynptr(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, try_discard_dynptr, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, try_discard_dynptr, NULL, 0);
...@@ -151,7 +158,7 @@ try_submit_dynptr(struct bpf_dynptr *dynptr, void *context) ...@@ -151,7 +158,7 @@ try_submit_dynptr(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to read past the end of the pointer. * not be able to read past the end of the pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_submit_dynptr(void *ctx) int user_ringbuf_callback_submit_dynptr(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, try_submit_dynptr, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, try_submit_dynptr, NULL, 0);
...@@ -168,10 +175,38 @@ invalid_drain_callback_return(struct bpf_dynptr *dynptr, void *context) ...@@ -168,10 +175,38 @@ invalid_drain_callback_return(struct bpf_dynptr *dynptr, void *context)
/* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should /* A callback that accesses a dynptr in a bpf_user_ringbuf_drain callback should
* not be able to write to that pointer. * not be able to write to that pointer.
*/ */
SEC("?raw_tp/sys_nanosleep") SEC("?raw_tp/")
int user_ringbuf_callback_invalid_return(void *ctx) int user_ringbuf_callback_invalid_return(void *ctx)
{ {
bpf_user_ringbuf_drain(&user_ringbuf, invalid_drain_callback_return, NULL, 0); bpf_user_ringbuf_drain(&user_ringbuf, invalid_drain_callback_return, NULL, 0);
return 0; return 0;
} }
static long
try_reinit_dynptr_mem(struct bpf_dynptr *dynptr, void *context)
{
bpf_dynptr_from_mem(&map_value, 4, 0, dynptr);
return 0;
}
static long
try_reinit_dynptr_ringbuf(struct bpf_dynptr *dynptr, void *context)
{
bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, dynptr);
return 0;
}
SEC("?raw_tp/")
int user_ringbuf_callback_reinit_dynptr_mem(void *ctx)
{
bpf_user_ringbuf_drain(&user_ringbuf, try_reinit_dynptr_mem, NULL, 0);
return 0;
}
SEC("?raw_tp/")
int user_ringbuf_callback_reinit_dynptr_ringbuf(void *ctx)
{
bpf_user_ringbuf_drain(&user_ringbuf, try_reinit_dynptr_ringbuf, NULL, 0);
return 0;
}
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
}, },
.prog_type = BPF_PROG_TYPE_SCHED_CLS, .prog_type = BPF_PROG_TYPE_SCHED_CLS,
.result = REJECT, .result = REJECT,
.errstr = "arg#0 expected pointer to ctx, but got PTR", .errstr = "R1 must have zero offset when passed to release func or trusted arg to kfunc",
.fixup_kfunc_btf_id = { .fixup_kfunc_btf_id = {
{ "bpf_kfunc_call_test_pass_ctx", 2 }, { "bpf_kfunc_call_test_pass_ctx", 2 },
}, },
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
}, },
.fixup_map_ringbuf = { 1 }, .fixup_map_ringbuf = { 1 },
.result = REJECT, .result = REJECT,
.errstr = "dereference of modified ringbuf_mem ptr R1", .errstr = "R1 must have zero offset when passed to release func",
}, },
{ {
"ringbuf: invalid reservation offset 2", "ringbuf: invalid reservation offset 2",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment