summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-11 05:25:23 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-11 05:25:23 +0300
commitf0dc7f9c6dd99891611fca5849cbc4c6965b690e (patch)
treef5ab92b43851aa0aadea1f73170fabc1b2bfeb37 /kernel
parent1aaccb5fa0eac996adde53538ca4b87a0b229ab7 (diff)
parent867f816badc01e6da655028810d468c9f935b37c (diff)
downloadlinux-f0dc7f9c6dd99891611fca5849cbc4c6965b690e.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix several bpfilter/UMH bugs, in particular make the UMH build not depend upon X86 specific Kconfig symbols. From Alexei Starovoitov. 2) Fix handling of modified context pointer in bpf verifier, from Daniel Borkmann. 3) Kill regression in ifdown/ifup sequences for hv_netvsc driver, from Dexuan Cui. 4) When the bonding primary member name changes, we have to re-evaluate the bond->force_primary setting, from Xiangning Yu. 5) Eliminate possible padding beyone end of SKB in cdc_ncm driver, from Bjørn Mork. 6) RX queue length reported for UDP sockets in procfs and socket diag are inaccurate, from Paolo Abeni. 7) Fix br_fdb_find_port() locking, from Petr Machata. 8) Limit sk_rcvlowat values properly in TCP, from Soheil Hassas Yeganeh. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (23 commits) tcp: limit sk_rcvlowat by the maximum receive buffer net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620 socket: close race condition between sock_close() and sockfs_setattr() net: bridge: Fix locking in br_fdb_find_port() udp: fix rx queue len reported by diag and proc interface cdc_ncm: avoid padding beyond end of skb net/sched: act_simple: fix parsing of TCA_DEF_DATA net: fddi: fix a possible null-ptr-deref net: aquantia: fix unsigned numvecs comparison with less than zero net: stmmac: fix build failure due to missing COMMON_CLK dependency bpfilter: fix race in pipe access bpf, xdp: fix crash in xdp_umem_unaccount_pages xsk: Fix umem fill/completion queue mmap on 32-bit tools/bpf: fix selftest get_cgroup_id_user bpfilter: fix OUTPUT_FORMAT umh: fix race condition net: mscc: ocelot: Fix uninitialized error in ocelot_netdevice_event() bonding: re-evaluate force_primary when the primary slave name changes ip_tunnel: Fix name string concatenate in __ip_tunnel_create() hv_netvsc: Fix a network regression after ifdown/ifup ...
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/verifier.c48
-rw-r--r--kernel/umh.c3
2 files changed, 32 insertions, 19 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d6403b5166f4..cced0c1e63e2 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1617,6 +1617,30 @@ static int get_callee_stack_depth(struct bpf_verifier_env *env,
}
#endif
+static int check_ctx_reg(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg, int regno)
+{
+ /* Access to ctx or passing it to a helper is only allowed in
+ * its original, unmodified form.
+ */
+
+ if (reg->off) {
+ verbose(env, "dereference of modified ctx ptr R%d off=%d disallowed\n",
+ regno, reg->off);
+ return -EACCES;
+ }
+
+ if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
+ char tn_buf[48];
+
+ tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
+ verbose(env, "variable ctx access var_off=%s disallowed\n", tn_buf);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
/* truncate register to smaller size (in bytes)
* must be called with size < BPF_REG_SIZE
*/
@@ -1686,24 +1710,11 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
verbose(env, "R%d leaks addr into ctx\n", value_regno);
return -EACCES;
}
- /* ctx accesses must be at a fixed offset, so that we can
- * determine what type of data were returned.
- */
- if (reg->off) {
- verbose(env,
- "dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n",
- regno, reg->off, off - reg->off);
- return -EACCES;
- }
- if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
- char tn_buf[48];
- tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
- verbose(env,
- "variable ctx access var_off=%s off=%d size=%d",
- tn_buf, off, size);
- return -EACCES;
- }
+ err = check_ctx_reg(env, reg, regno);
+ if (err < 0)
+ return err;
+
err = check_ctx_access(env, insn_idx, off, size, t, &reg_type);
if (!err && t == BPF_READ && value_regno >= 0) {
/* ctx access returns either a scalar, or a
@@ -1984,6 +1995,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
expected_type = PTR_TO_CTX;
if (type != expected_type)
goto err_type;
+ err = check_ctx_reg(env, reg, regno);
+ if (err < 0)
+ return err;
} else if (arg_type_is_mem_ptr(arg_type)) {
expected_type = PTR_TO_STACK;
/* One exception here. In case function allows for NULL to be
diff --git a/kernel/umh.c b/kernel/umh.c
index 30db93fd7e39..c449858946af 100644
--- a/kernel/umh.c
+++ b/kernel/umh.c
@@ -99,6 +99,7 @@ static int call_usermodehelper_exec_async(void *data)
commit_creds(new);
+ sub_info->pid = task_pid_nr(current);
if (sub_info->file)
retval = do_execve_file(sub_info->file,
sub_info->argv, sub_info->envp);
@@ -191,8 +192,6 @@ static void call_usermodehelper_exec_work(struct work_struct *work)
if (pid < 0) {
sub_info->retval = pid;
umh_complete(sub_info);
- } else {
- sub_info->pid = pid;
}
}
}