forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
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>
This commit is contained in:
commit
96b11e9358
@ -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;
|
||||
@ -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);
|
||||
}
|
||||
@ -199,6 +202,7 @@ 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,
|
||||
@ -206,6 +210,9 @@ int cgroup_bpf_inherit(struct cgroup *cgrp)
|
||||
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]);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
@ -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, ®s[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]);
|
||||
|
Loading…
Reference in New Issue
Block a user