All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Eric Dumazet <edumazet@google.com>,
	Dmitry Vyukov <dvyukov@google.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.9 02/72] net_sched: fix error recovery at qdisc creation
Date: Wed, 19 Jul 2017 12:23:56 +0200	[thread overview]
Message-ID: <20170719102436.133985685@linuxfoundation.org> (raw)
In-Reply-To: <20170719102435.760649060@linuxfoundation.org>

4.9-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

commit 87b60cfacf9f17cf71933c6e33b66e68160af71d upstream.

Dmitry reported uses after free in qdisc code [1]

The problem here is that ops->init() can return an error.

qdisc_create_dflt() then call ops->destroy(),
while qdisc_create() does _not_ call it.

Four qdisc chose to call their own ops->destroy(), assuming their caller
would not.

This patch makes sure qdisc_create() calls ops->destroy()
and fixes the four qdisc to avoid double free.

[1]
BUG: KASAN: use-after-free in mq_destroy+0x242/0x290 net/sched/sch_mq.c:33 at addr ffff8801d415d440
Read of size 8 by task syz-executor2/5030
CPU: 0 PID: 5030 Comm: syz-executor2 Not tainted 4.3.5-smp-DEV #119
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
 0000000000000046 ffff8801b435b870 ffffffff81bbbed4 ffff8801db000400
 ffff8801d415d440 ffff8801d415dc40 ffff8801c4988510 ffff8801b435b898
 ffffffff816682b1 ffff8801b435b928 ffff8801d415d440 ffff8801c49880c0
Call Trace:
 [<ffffffff81bbbed4>] __dump_stack lib/dump_stack.c:15 [inline]
 [<ffffffff81bbbed4>] dump_stack+0x6c/0x98 lib/dump_stack.c:51
 [<ffffffff816682b1>] kasan_object_err+0x21/0x70 mm/kasan/report.c:158
 [<ffffffff81668524>] print_address_description mm/kasan/report.c:196 [inline]
 [<ffffffff81668524>] kasan_report_error+0x1b4/0x4b0 mm/kasan/report.c:285
 [<ffffffff81668953>] kasan_report mm/kasan/report.c:305 [inline]
 [<ffffffff81668953>] __asan_report_load8_noabort+0x43/0x50 mm/kasan/report.c:326
 [<ffffffff82527b02>] mq_destroy+0x242/0x290 net/sched/sch_mq.c:33
 [<ffffffff82524bdd>] qdisc_destroy+0x12d/0x290 net/sched/sch_generic.c:953
 [<ffffffff82524e30>] qdisc_create_dflt+0xf0/0x120 net/sched/sch_generic.c:848
 [<ffffffff8252550d>] attach_default_qdiscs net/sched/sch_generic.c:1029 [inline]
 [<ffffffff8252550d>] dev_activate+0x6ad/0x880 net/sched/sch_generic.c:1064
 [<ffffffff824b1db1>] __dev_open+0x221/0x320 net/core/dev.c:1403
 [<ffffffff824b24ce>] __dev_change_flags+0x15e/0x3e0 net/core/dev.c:6858
 [<ffffffff824b27de>] dev_change_flags+0x8e/0x140 net/core/dev.c:6926
 [<ffffffff824f5bf6>] dev_ifsioc+0x446/0x890 net/core/dev_ioctl.c:260
 [<ffffffff824f61fa>] dev_ioctl+0x1ba/0xb80 net/core/dev_ioctl.c:546
 [<ffffffff82430509>] sock_do_ioctl+0x99/0xb0 net/socket.c:879
 [<ffffffff82430d30>] sock_ioctl+0x2a0/0x390 net/socket.c:958
 [<ffffffff816f3b68>] vfs_ioctl fs/ioctl.c:44 [inline]
 [<ffffffff816f3b68>] do_vfs_ioctl+0x8a8/0xe50 fs/ioctl.c:611
 [<ffffffff816f41a4>] SYSC_ioctl fs/ioctl.c:626 [inline]
 [<ffffffff816f41a4>] SyS_ioctl+0x94/0xc0 fs/ioctl.c:617
 [<ffffffff8123e357>] entry_SYSCALL_64_fastpath+0x12/0x17

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 net/sched/sch_api.c    |    2 ++
 net/sched/sch_hhf.c    |    8 ++++++--
 net/sched/sch_mq.c     |   10 +++-------
 net/sched/sch_mqprio.c |   19 ++++++-------------
 net/sched/sch_sfq.c    |    3 ++-
 5 files changed, 19 insertions(+), 23 deletions(-)

--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1008,6 +1008,8 @@ static struct Qdisc *qdisc_create(struct
 
 		return sch;
 	}
+	/* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
+	ops->destroy(sch);
 err_out3:
 	dev_put(dev);
 	kfree((char *) sch - sch->padded);
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -627,7 +627,9 @@ static int hhf_init(struct Qdisc *sch, s
 			q->hhf_arrays[i] = hhf_zalloc(HHF_ARRAYS_LEN *
 						      sizeof(u32));
 			if (!q->hhf_arrays[i]) {
-				hhf_destroy(sch);
+				/* Note: hhf_destroy() will be called
+				 * by our caller.
+				 */
 				return -ENOMEM;
 			}
 		}
@@ -638,7 +640,9 @@ static int hhf_init(struct Qdisc *sch, s
 			q->hhf_valid_bits[i] = hhf_zalloc(HHF_ARRAYS_LEN /
 							  BITS_PER_BYTE);
 			if (!q->hhf_valid_bits[i]) {
-				hhf_destroy(sch);
+				/* Note: hhf_destroy() will be called
+				 * by our caller.
+				 */
 				return -ENOMEM;
 			}
 		}
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -52,7 +52,7 @@ static int mq_init(struct Qdisc *sch, st
 	/* pre-allocate qdiscs, attachment can't fail */
 	priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
 			       GFP_KERNEL);
-	if (priv->qdiscs == NULL)
+	if (!priv->qdiscs)
 		return -ENOMEM;
 
 	for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
@@ -60,18 +60,14 @@ static int mq_init(struct Qdisc *sch, st
 		qdisc = qdisc_create_dflt(dev_queue, get_default_qdisc_ops(dev, ntx),
 					  TC_H_MAKE(TC_H_MAJ(sch->handle),
 						    TC_H_MIN(ntx + 1)));
-		if (qdisc == NULL)
-			goto err;
+		if (!qdisc)
+			return -ENOMEM;
 		priv->qdiscs[ntx] = qdisc;
 		qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 	}
 
 	sch->flags |= TCQ_F_MQROOT;
 	return 0;
-
-err:
-	mq_destroy(sch);
-	return -ENOMEM;
 }
 
 static void mq_attach(struct Qdisc *sch)
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -118,10 +118,8 @@ static int mqprio_init(struct Qdisc *sch
 	/* pre-allocate qdisc, attachment can't fail */
 	priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
 			       GFP_KERNEL);
-	if (priv->qdiscs == NULL) {
-		err = -ENOMEM;
-		goto err;
-	}
+	if (!priv->qdiscs)
+		return -ENOMEM;
 
 	for (i = 0; i < dev->num_tx_queues; i++) {
 		dev_queue = netdev_get_tx_queue(dev, i);
@@ -129,10 +127,9 @@ static int mqprio_init(struct Qdisc *sch
 					  get_default_qdisc_ops(dev, i),
 					  TC_H_MAKE(TC_H_MAJ(sch->handle),
 						    TC_H_MIN(i + 1)));
-		if (qdisc == NULL) {
-			err = -ENOMEM;
-			goto err;
-		}
+		if (!qdisc)
+			return -ENOMEM;
+
 		priv->qdiscs[i] = qdisc;
 		qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
 	}
@@ -148,7 +145,7 @@ static int mqprio_init(struct Qdisc *sch
 		priv->hw_owned = 1;
 		err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
 		if (err)
-			goto err;
+			return err;
 	} else {
 		netdev_set_num_tc(dev, qopt->num_tc);
 		for (i = 0; i < qopt->num_tc; i++)
@@ -162,10 +159,6 @@ static int mqprio_init(struct Qdisc *sch
 
 	sch->flags |= TCQ_F_MQROOT;
 	return 0;
-
-err:
-	mqprio_destroy(sch);
-	return err;
 }
 
 static void mqprio_attach(struct Qdisc *sch)
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -742,9 +742,10 @@ static int sfq_init(struct Qdisc *sch, s
 	q->ht = sfq_alloc(sizeof(q->ht[0]) * q->divisor);
 	q->slots = sfq_alloc(sizeof(q->slots[0]) * q->maxflows);
 	if (!q->ht || !q->slots) {
-		sfq_destroy(sch);
+		/* Note: sfq_destroy() will be called by our caller */
 		return -ENOMEM;
 	}
+
 	for (i = 0; i < q->divisor; i++)
 		q->ht[i] = SFQ_EMPTY_SLOT;
 

  parent reply	other threads:[~2017-07-19 10:42 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-19 10:23 [PATCH 4.9 00/72] 4.9.39-stable review Greg Kroah-Hartman
2017-07-19 10:23 ` [PATCH 4.9 01/72] xen-netfront: Rework the fix for Rx stall during OOM and network stress Greg Kroah-Hartman
2017-07-19 10:23 ` Greg Kroah-Hartman [this message]
2017-07-19 10:23 ` [PATCH 4.9 03/72] net: sched: Fix one possible panic when no destroy callback Greg Kroah-Hartman
2017-07-19 10:23 ` [PATCH 4.9 04/72] net/phy: micrel: configure intterupts after autoneg workaround Greg Kroah-Hartman
2017-07-19 10:23 ` [PATCH 4.9 05/72] ipv6: avoid unregistering inet6_dev for loopback Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 06/72] net: dp83640: Avoid NULL pointer dereference Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 07/72] tcp: reset sk_rx_dst in tcp_disconnect() Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 08/72] net: prevent sign extension in dev_get_stats() Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 09/72] bridge: mdb: fix leak on complete_info ptr on fail path Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 10/72] rocker: move dereference before free Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 11/72] bpf: prevent leaking pointer via xadd on unpriviledged Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 13/72] net/mlx5: Cancel delayed recovery work when unloading the driver Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 14/72] liquidio: fix bug in soft reset failure detection Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 15/72] net/mlx5e: Fix TX carrier errors report in get stats ndo Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 16/72] ipv6: dad: dont remove dynamic addresses if link is down Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 17/72] vxlan: fix hlist corruption Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 18/72] net: core: Fix slab-out-of-bounds in netdev_stats_to_stats64 Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 20/72] vrf: fix bug_on triggered by rx when destroying a vrf Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 21/72] rds: tcp: use sock_create_lite() to create the accept socket Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 23/72] brcmfmac: Fix a memory leak in error handling path in brcmf_cfg80211_attach Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 24/72] brcmfmac: Fix glom_skb leak in brcmf_sdiod_recv_chain Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 25/72] sfc: dont read beyond unicast address list Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 26/72] cfg80211: Define nla_policy for NL80211_ATTR_LOCAL_MESH_POWER_MODE Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 27/72] cfg80211: Validate frequencies nested in NL80211_ATTR_SCAN_FREQUENCIES Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 28/72] cfg80211: Check if PMKID attribute is of expected size Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 29/72] cfg80211: Check if NAN service ID " Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 30/72] irqchip/gic-v3: Fix out-of-bound access in gic_set_affinity Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 31/72] parisc: Report SIGSEGV instead of SIGBUS when running out of stack Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 32/72] parisc: use compat_sys_keyctl() Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 33/72] parisc: DMA API: return error instead of BUG_ON for dma ops on non dma devs Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 34/72] parisc/mm: Ensure IRQs are off in switch_mm() Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 35/72] tools/lib/lockdep: Reduce MAX_LOCK_DEPTH to avoid overflowing lock_chain/: Depth Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 36/72] thp, mm: fix crash due race in MADV_FREE handling Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 37/72] kernel/extable.c: mark core_kernel_text notrace Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 38/72] mm/list_lru.c: fix list_lru_count_node() to be race free Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 39/72] fs/dcache.c: fix spin lockup issue on nlru->lock Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 40/72] checkpatch: silence perl 5.26.0 unescaped left brace warnings Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 41/72] binfmt_elf: use ELF_ET_DYN_BASE only for PIE Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 42/72] arm: move ELF_ET_DYN_BASE to 4MB Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 43/72] arm64: move ELF_ET_DYN_BASE to 4GB / 4MB Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 44/72] powerpc: " Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 45/72] s390: reduce ELF_ET_DYN_BASE Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 46/72] exec: Limit arg stack to at most 75% of _STK_LIM Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 47/72] ARM64: dts: marvell: armada37xx: Fix timer interrupt specifiers Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 48/72] vt: fix unchecked __put_user() in tioclinux ioctls Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 49/72] rcu: Add memory barriers for NOCB leader wakeup Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 50/72] nvmem: core: fix leaks on registration errors Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 51/72] mnt: In umount propagation reparent in a separate pass Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 52/72] mnt: In propgate_umount handle visiting mounts in any order Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 53/72] mnt: Make propagate_umount less slow for overlapping mount propagation trees Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 54/72] selftests/capabilities: Fix the test_execve test Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 57/72] crypto: atmel - only treat EBUSY as transient if backlog Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 58/72] crypto: sha1-ssse3 - Disable avx2 Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 61/72] Revert "sched/core: Optimize SCHED_SMT" Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 62/72] sched/fair, cpumask: Export for_each_cpu_wrap() Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 63/72] sched/topology: Fix building of overlapping sched-groups Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 64/72] sched/topology: Optimize build_group_mask() Greg Kroah-Hartman
2017-07-19 10:24 ` [PATCH 4.9 65/72] sched/topology: Fix overlapping sched_group_mask Greg Kroah-Hartman
2017-07-19 10:25 ` [PATCH 4.9 66/72] PM / wakeirq: Convert to SRCU Greg Kroah-Hartman
2017-07-19 10:25 ` [PATCH 4.9 67/72] PM / QoS: return -EINVAL for bogus strings Greg Kroah-Hartman
2017-07-19 10:25 ` [PATCH 4.9 68/72] tracing: Use SOFTIRQ_OFFSET for softirq dectection for more accurate results Greg Kroah-Hartman
2017-07-19 10:25 ` [PATCH 4.9 72/72] kvm: vmx: allow host to access guest MSR_IA32_BNDCFGS Greg Kroah-Hartman
2017-07-19 15:58 ` [PATCH 4.9 00/72] 4.9.39-stable review Sumit Semwal
2017-07-20  5:08   ` Greg Kroah-Hartman
2017-07-19 20:34 ` Guenter Roeck
2017-07-19 23:39 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170719102436.133985685@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=davem@davemloft.net \
    --cc=dvyukov@google.com \
    --cc=edumazet@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.