Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51cb67c0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull networking fixes from David Miller:
 "As usual, there are a couple straggler bug fixes:

   1) qlcnic_alloc_mbx_args() error returns are not checked in qlcnic
      driver.  Fix from Insu Yun.

   2) SKB refcounting bug in connector, from Florian Westphal.

   3) vrf_get_saddr() has to propagate fib_lookup() errors to it's
      callers, from David Ahern.

   4) Fix AF_UNIX splice/bind deadlock, from Rainer Weikusat.

   5) qdisc_rcu_free() fails to free the per-cpu qstats.  Fix from John
      Fastabend.

   6) vmxnet3 driver passes wrong page to dma_map_page(), fix from
     Shrikrishna Khare.

   7) Don't allow zero cwnd in tcp_cwnd_reduction(), from Yuchung Cheng"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  tcp: fix zero cwnd in tcp_cwnd_reduction
  Driver: Vmxnet3: Fix regression caused by 5738a09d
  net: qmi_wwan: Add WeTelecom-WPD600N
  mkiss: fix scribble on freed memory
  net: possible use after free in dst_release
  net: sched: fix missing free per cpu on qstats
  ARM: net: bpf: fix zero right shift
  6pack: fix free memory scribbles
  net: filter: make JITs zero A for SKF_AD_ALU_XOR_X
  bridge: Only call /sbin/bridge-stp for the initial network namespace
  af_unix: Fix splice-bind deadlock
  net: Propagate lookup failure in l3mdev_get_saddr to caller
  r8152: add reset_resume function
  connector: bump skb->users before callback invocation
  cxgb4: correctly handling failed allocation
  qlcnic: correctly handle qlcnic_alloc_mbx_args
parents ee9a7d2c 8b8a321f
Loading
Loading
Loading
Loading
+3 −16
Original line number Diff line number Diff line
@@ -187,19 +187,6 @@ static inline int mem_words_used(struct jit_ctx *ctx)
	return fls(ctx->seen & SEEN_MEM);
}

static inline bool is_load_to_a(u16 inst)
{
	switch (inst) {
	case BPF_LD | BPF_W | BPF_LEN:
	case BPF_LD | BPF_W | BPF_ABS:
	case BPF_LD | BPF_H | BPF_ABS:
	case BPF_LD | BPF_B | BPF_ABS:
		return true;
	default:
		return false;
	}
}

static void jit_fill_hole(void *area, unsigned int size)
{
	u32 *ptr;
@@ -211,7 +198,6 @@ static void jit_fill_hole(void *area, unsigned int size)
static void build_prologue(struct jit_ctx *ctx)
{
	u16 reg_set = saved_regs(ctx);
	u16 first_inst = ctx->skf->insns[0].code;
	u16 off;

#ifdef CONFIG_FRAME_POINTER
@@ -241,7 +227,7 @@ static void build_prologue(struct jit_ctx *ctx)
		emit(ARM_MOV_I(r_X, 0), ctx);

	/* do not leak kernel data to userspace */
	if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
	if (bpf_needs_clear_a(&ctx->skf->insns[0]))
		emit(ARM_MOV_I(r_A, 0), ctx);

	/* stack space for the BPF_MEM words */
@@ -770,6 +756,7 @@ static int build_body(struct jit_ctx *ctx)
		case BPF_ALU | BPF_RSH | BPF_K:
			if (unlikely(k > 31))
				return -1;
			if (k)
				emit(ARM_LSR_I(r_A, r_A, k), ctx);
			break;
		case BPF_ALU | BPF_RSH | BPF_X:
+1 −15
Original line number Diff line number Diff line
@@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num)
	return num;
}

static bool is_load_to_a(u16 inst)
{
	switch (inst) {
	case BPF_LD | BPF_W | BPF_LEN:
	case BPF_LD | BPF_W | BPF_ABS:
	case BPF_LD | BPF_H | BPF_ABS:
	case BPF_LD | BPF_B | BPF_ABS:
		return true;
	default:
		return false;
	}
}

static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
{
	int i = 0, real_off = 0;
@@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)

static void build_prologue(struct jit_ctx *ctx)
{
	u16 first_inst = ctx->skf->insns[0].code;
	int sp_off;

	/* Calculate the total offset for the stack pointer */
@@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx)
		emit_jit_reg_move(r_X, r_zero, ctx);

	/* Do not leak kernel data to userspace */
	if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
	if (bpf_needs_clear_a(&ctx->skf->insns[0]))
		emit_jit_reg_move(r_A, r_zero, ctx);
}

+2 −11
Original line number Diff line number Diff line
@@ -78,19 +78,10 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
		PPC_LI(r_X, 0);
	}

	switch (filter[0].code) {
	case BPF_RET | BPF_K:
	case BPF_LD | BPF_W | BPF_LEN:
	case BPF_LD | BPF_W | BPF_ABS:
	case BPF_LD | BPF_H | BPF_ABS:
	case BPF_LD | BPF_B | BPF_ABS:
		/* first instruction sets A register (or is RET 'constant') */
		break;
	default:
	/* make sure we dont leak kernel information to user */
	if (bpf_needs_clear_a(&filter[0]))
		PPC_LI(r_A, 0);
}
}

static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
{
+2 −15
Original line number Diff line number Diff line
@@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp)
		}
		emit_reg_move(O7, r_saved_O7);

		switch (filter[0].code) {
		case BPF_RET | BPF_K:
		case BPF_LD | BPF_W | BPF_LEN:
		case BPF_LD | BPF_W | BPF_ABS:
		case BPF_LD | BPF_H | BPF_ABS:
		case BPF_LD | BPF_B | BPF_ABS:
			/* The first instruction sets the A register (or is
			 * a "RET 'constant'")
			 */
			break;
		default:
			/* Make sure we dont leak kernel information to the
			 * user.
			 */
		/* Make sure we dont leak kernel information to the user. */
		if (bpf_needs_clear_a(&filter[0]))
			emit_clear(r_A); /* A = 0 */
		}

		for (i = 0; i < flen; i++) {
			unsigned int K = filter[i].k;
+3 −8
Original line number Diff line number Diff line
@@ -179,26 +179,21 @@ static int cn_call_callback(struct sk_buff *skb)
 *
 * It checks skb, netlink header and msg sizes, and calls callback helper.
 */
static void cn_rx_skb(struct sk_buff *__skb)
static void cn_rx_skb(struct sk_buff *skb)
{
	struct nlmsghdr *nlh;
	struct sk_buff *skb;
	int len, err;

	skb = skb_get(__skb);

	if (skb->len >= NLMSG_HDRLEN) {
		nlh = nlmsg_hdr(skb);
		len = nlmsg_len(nlh);

		if (len < (int)sizeof(struct cn_msg) ||
		    skb->len < nlh->nlmsg_len ||
		    len > CONNECTOR_MAX_MSG_SIZE) {
			kfree_skb(skb);
		    len > CONNECTOR_MAX_MSG_SIZE)
			return;
		}

		err = cn_call_callback(skb);
		err = cn_call_callback(skb_get(skb));
		if (err < 0)
			kfree_skb(skb);
	}
Loading