Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Browse files Browse the repository at this point in the history
Daniel Borkmann says:

====================
pull-request: bpf 2020-01-07

The following pull-request contains BPF updates for your *net* tree.

We've added 2 non-merge commits during the last 1 day(s) which contain
a total of 2 files changed, 16 insertions(+), 4 deletions(-).

The main changes are:

1) Fix a use-after-free in cgroup BPF due to auto-detachment, from Roman Gushchin.

2) Fix skb out-of-bounds access in ld_abs/ind instruction, from Daniel Borkmann.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 7, 2020
2 parents 481a7d1 + 6d4f151 commit 96b11e9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
11 changes: 9 additions & 2 deletions kernel/bpf/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ void cgroup_bpf_offline(struct cgroup *cgrp)
*/
static void cgroup_bpf_release(struct work_struct *work)
{
struct cgroup *cgrp = container_of(work, struct cgroup,
bpf.release_work);
struct cgroup *p, *cgrp = container_of(work, struct cgroup,
bpf.release_work);
enum bpf_cgroup_storage_type stype;
struct bpf_prog_array *old_array;
unsigned int type;
Expand Down Expand Up @@ -65,6 +65,9 @@ static void cgroup_bpf_release(struct work_struct *work)

mutex_unlock(&cgroup_mutex);

for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p))
cgroup_bpf_put(p);

percpu_ref_exit(&cgrp->bpf.refcnt);
cgroup_put(cgrp);
}
Expand Down Expand Up @@ -199,13 +202,17 @@ int cgroup_bpf_inherit(struct cgroup *cgrp)
*/
#define NR ARRAY_SIZE(cgrp->bpf.effective)
struct bpf_prog_array *arrays[NR] = {};
struct cgroup *p;
int ret, i;

ret = percpu_ref_init(&cgrp->bpf.refcnt, cgroup_bpf_release_fn, 0,
GFP_KERNEL);
if (ret)
return ret;

for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p))
cgroup_bpf_get(p);

for (i = 0; i < NR; i++)
INIT_LIST_HEAD(&cgrp->bpf.progs[i]);

Expand Down
9 changes: 7 additions & 2 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -6264,6 +6264,7 @@ static bool may_access_skb(enum bpf_prog_type type)
static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
{
struct bpf_reg_state *regs = cur_regs(env);
static const int ctx_reg = BPF_REG_6;
u8 mode = BPF_MODE(insn->code);
int i, err;

Expand Down Expand Up @@ -6297,7 +6298,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
}

/* check whether implicit source operand (register R6) is readable */
err = check_reg_arg(env, BPF_REG_6, SRC_OP);
err = check_reg_arg(env, ctx_reg, SRC_OP);
if (err)
return err;

Expand All @@ -6316,7 +6317,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
return -EINVAL;
}

if (regs[BPF_REG_6].type != PTR_TO_CTX) {
if (regs[ctx_reg].type != PTR_TO_CTX) {
verbose(env,
"at the time of BPF_LD_ABS|IND R6 != pointer to skb\n");
return -EINVAL;
Expand All @@ -6329,6 +6330,10 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
return err;
}

err = check_ctx_reg(env, &regs[ctx_reg], ctx_reg);
if (err < 0)
return err;

/* reset caller saved regs to unreadable */
for (i = 0; i < CALLER_SAVED_REGS; i++) {
mark_reg_not_init(env, regs, caller_saved[i]);
Expand Down

0 comments on commit 96b11e9

Please sign in to comment.