From 8c94ddbc139bf8511d79153a81191b07f8e03eb4 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Mon, 9 Nov 2015 17:21:05 -0800 Subject: [PATCH] net: mvneta: Fix memory use after free. After changing an interface's MTU, then bringing the interface down and back up again, I immediately saw tons of kernel messages like below. The reason for this bad behavior is mvneta_rxq_drop_pkts(), which calls dma_unmap_single() on already-freed memory. So we need to switch the order of those two operations. [ 152.388518] BUG: Bad page state in process ifconfig pfn:1b518 [ 152.388526] page:dff3dbc0 count:0 mapcount:0 mapping: (null) index:0x0 [ 152.395178] flags: 0x200(arch_1) [ 152.398441] page dumped because: PAGE_FLAGS_CHECK_AT_PREP flag set [ 152.398446] bad because of flags: [ 152.398450] flags: 0x200(arch_1) [ 152.401716] Modules linked in: [ 152.401728] CPU: 0 PID: 1453 Comm: ifconfig Tainted: P B O 4.1.12.armada.1 #1 [ 152.401733] Hardware name: Marvell Armada 370/XP (Device Tree) [ 152.401749] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 152.401762] [] (show_stack) from [] (dump_stack+0x74/0x90) [ 152.401772] [] (dump_stack) from [] (bad_page+0xc4/0x124) [ 152.401783] [] (bad_page) from [] (get_page_from_freelist+0x4e4/0x644) [ 152.401794] [] (get_page_from_freelist) from [] (__alloc_pages_nodemask+0x148/0x784) [ 152.401805] [] (__alloc_pages_nodemask) from [] (kmalloc_order+0x10/0x20) [ 152.401818] [] (kmalloc_order) from [] (mvneta_rx_refill+0xc4/0xe8) [ 152.401830] [] (mvneta_rx_refill) from [] (mvneta_setup_rxqs+0x298/0x39c) [ 152.401842] [] (mvneta_setup_rxqs) from [] (mvneta_open+0x3c/0x150) [ 152.401853] [] (mvneta_open) from [] (__dev_open+0xac/0x124) [ 152.401864] [] (__dev_open) from [] (__dev_change_flags+0x8c/0x148) [ 152.401875] [] (__dev_change_flags) from [] (dev_change_flags+0x18/0x48) [ 152.401886] [] (dev_change_flags) from [] (devinet_ioctl+0x620/0x6d0) [ 152.401897] [] (devinet_ioctl) from [] (sock_ioctl+0x64/0x288) [ 152.401908] [] (sock_ioctl) from [] (do_vfs_ioctl+0x78/0x608) [ 152.401918] [] (do_vfs_ioctl) from [] (SyS_ioctl+0x64/0x74) [ 152.401930] [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x3c) Signed-off-by: Justin Maggard Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index a47496a020d9..e84c7f2634d3 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1493,9 +1493,9 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp, struct mvneta_rx_desc *rx_desc = rxq->descs + i; void *data = (void *)rx_desc->buf_cookie; - mvneta_frag_free(pp, data); dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); + mvneta_frag_free(pp, data); } if (rx_done)