Skip to content

Commit 6396026

Browse files
committed
bpf: Check correct cred for CAP_SYSLOG in bpf_dump_raw_ok()
When evaluating access control over kallsyms visibility, credentials at open() time need to be used, not the "current" creds (though in BPF's case, this has likely always been the same). Plumb access to associated file->f_cred down through bpf_dump_raw_ok() and its callers now that kallsysm_show_value() has been refactored to take struct cred. Cc: Alexei Starovoitov <[email protected]> Cc: Daniel Borkmann <[email protected]> Cc: [email protected] Cc: [email protected] Fixes: 7105e82 ("bpf: allow for correlation of maps and helpers in dump") Signed-off-by: Kees Cook <[email protected]>
1 parent 60f7bb6 commit 6396026

File tree

3 files changed

+24
-19
lines changed

3 files changed

+24
-19
lines changed

include/linux/filter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -884,12 +884,12 @@ void bpf_jit_compile(struct bpf_prog *prog);
884884
bool bpf_jit_needs_zext(void);
885885
bool bpf_helper_changes_pkt_data(void *func);
886886

887-
static inline bool bpf_dump_raw_ok(void)
887+
static inline bool bpf_dump_raw_ok(const struct cred *cred)
888888
{
889889
/* Reconstruction of call-sites is dependent on kallsyms,
890890
* thus make dump the same restriction.
891891
*/
892-
return kallsyms_show_value(current_cred());
892+
return kallsyms_show_value(cred);
893893
}
894894

895895
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,

kernel/bpf/syscall.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3139,7 +3139,8 @@ static const struct bpf_map *bpf_map_from_imm(const struct bpf_prog *prog,
31393139
return NULL;
31403140
}
31413141

3142-
static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
3142+
static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog,
3143+
const struct cred *f_cred)
31433144
{
31443145
const struct bpf_map *map;
31453146
struct bpf_insn *insns;
@@ -3165,7 +3166,7 @@ static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
31653166
code == (BPF_JMP | BPF_CALL_ARGS)) {
31663167
if (code == (BPF_JMP | BPF_CALL_ARGS))
31673168
insns[i].code = BPF_JMP | BPF_CALL;
3168-
if (!bpf_dump_raw_ok())
3169+
if (!bpf_dump_raw_ok(f_cred))
31693170
insns[i].imm = 0;
31703171
continue;
31713172
}
@@ -3221,7 +3222,8 @@ static int set_info_rec_size(struct bpf_prog_info *info)
32213222
return 0;
32223223
}
32233224

3224-
static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
3225+
static int bpf_prog_get_info_by_fd(struct file *file,
3226+
struct bpf_prog *prog,
32253227
const union bpf_attr *attr,
32263228
union bpf_attr __user *uattr)
32273229
{
@@ -3290,11 +3292,11 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
32903292
struct bpf_insn *insns_sanitized;
32913293
bool fault;
32923294

3293-
if (prog->blinded && !bpf_dump_raw_ok()) {
3295+
if (prog->blinded && !bpf_dump_raw_ok(file->f_cred)) {
32943296
info.xlated_prog_insns = 0;
32953297
goto done;
32963298
}
3297-
insns_sanitized = bpf_insn_prepare_dump(prog);
3299+
insns_sanitized = bpf_insn_prepare_dump(prog, file->f_cred);
32983300
if (!insns_sanitized)
32993301
return -ENOMEM;
33003302
uinsns = u64_to_user_ptr(info.xlated_prog_insns);
@@ -3328,7 +3330,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
33283330
}
33293331

33303332
if (info.jited_prog_len && ulen) {
3331-
if (bpf_dump_raw_ok()) {
3333+
if (bpf_dump_raw_ok(file->f_cred)) {
33323334
uinsns = u64_to_user_ptr(info.jited_prog_insns);
33333335
ulen = min_t(u32, info.jited_prog_len, ulen);
33343336

@@ -3363,7 +3365,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
33633365
ulen = info.nr_jited_ksyms;
33643366
info.nr_jited_ksyms = prog->aux->func_cnt ? : 1;
33653367
if (ulen) {
3366-
if (bpf_dump_raw_ok()) {
3368+
if (bpf_dump_raw_ok(file->f_cred)) {
33673369
unsigned long ksym_addr;
33683370
u64 __user *user_ksyms;
33693371
u32 i;
@@ -3394,7 +3396,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
33943396
ulen = info.nr_jited_func_lens;
33953397
info.nr_jited_func_lens = prog->aux->func_cnt ? : 1;
33963398
if (ulen) {
3397-
if (bpf_dump_raw_ok()) {
3399+
if (bpf_dump_raw_ok(file->f_cred)) {
33983400
u32 __user *user_lens;
33993401
u32 func_len, i;
34003402

@@ -3451,7 +3453,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
34513453
else
34523454
info.nr_jited_line_info = 0;
34533455
if (info.nr_jited_line_info && ulen) {
3454-
if (bpf_dump_raw_ok()) {
3456+
if (bpf_dump_raw_ok(file->f_cred)) {
34553457
__u64 __user *user_linfo;
34563458
u32 i;
34573459

@@ -3497,7 +3499,8 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
34973499
return 0;
34983500
}
34993501

3500-
static int bpf_map_get_info_by_fd(struct bpf_map *map,
3502+
static int bpf_map_get_info_by_fd(struct file *file,
3503+
struct bpf_map *map,
35013504
const union bpf_attr *attr,
35023505
union bpf_attr __user *uattr)
35033506
{
@@ -3540,7 +3543,8 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
35403543
return 0;
35413544
}
35423545

3543-
static int bpf_btf_get_info_by_fd(struct btf *btf,
3546+
static int bpf_btf_get_info_by_fd(struct file *file,
3547+
struct btf *btf,
35443548
const union bpf_attr *attr,
35453549
union bpf_attr __user *uattr)
35463550
{
@@ -3555,7 +3559,8 @@ static int bpf_btf_get_info_by_fd(struct btf *btf,
35553559
return btf_get_info_by_fd(btf, attr, uattr);
35563560
}
35573561

3558-
static int bpf_link_get_info_by_fd(struct bpf_link *link,
3562+
static int bpf_link_get_info_by_fd(struct file *file,
3563+
struct bpf_link *link,
35593564
const union bpf_attr *attr,
35603565
union bpf_attr __user *uattr)
35613566
{
@@ -3608,15 +3613,15 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
36083613
return -EBADFD;
36093614

36103615
if (f.file->f_op == &bpf_prog_fops)
3611-
err = bpf_prog_get_info_by_fd(f.file->private_data, attr,
3616+
err = bpf_prog_get_info_by_fd(f.file, f.file->private_data, attr,
36123617
uattr);
36133618
else if (f.file->f_op == &bpf_map_fops)
3614-
err = bpf_map_get_info_by_fd(f.file->private_data, attr,
3619+
err = bpf_map_get_info_by_fd(f.file, f.file->private_data, attr,
36153620
uattr);
36163621
else if (f.file->f_op == &btf_fops)
3617-
err = bpf_btf_get_info_by_fd(f.file->private_data, attr, uattr);
3622+
err = bpf_btf_get_info_by_fd(f.file, f.file->private_data, attr, uattr);
36183623
else if (f.file->f_op == &bpf_link_fops)
3619-
err = bpf_link_get_info_by_fd(f.file->private_data,
3624+
err = bpf_link_get_info_by_fd(f.file, f.file->private_data,
36203625
attr, uattr);
36213626
else
36223627
err = -EINVAL;

net/core/sysctl_net_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write,
274274
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
275275
if (write && !ret) {
276276
if (jit_enable < 2 ||
277-
(jit_enable == 2 && bpf_dump_raw_ok())) {
277+
(jit_enable == 2 && bpf_dump_raw_ok(current_cred()))) {
278278
*(int *)table->data = jit_enable;
279279
if (jit_enable == 2)
280280
pr_warn("bpf_jit_enable = 2 was set! NEVER use this in production, only for JIT debugging!\n");

0 commit comments

Comments
 (0)