Received: by 10.213.65.68 with SMTP id h4csp2271062imn; Thu, 29 Mar 2018 22:53:37 -0700 (PDT) X-Google-Smtp-Source: AIpwx49JV2q3tUtyOzXZtC1dZq4DtLvjD8XoQwdhCh2yLkvHSupsn7RrCp9jYVweoP+YczdZuw0a X-Received: by 10.101.75.12 with SMTP id r12mr7523707pgq.36.1522389217541; Thu, 29 Mar 2018 22:53:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522389217; cv=none; d=google.com; s=arc-20160816; b=tUXg0vjLPMmI0cIgyXjyNipaeSrjGSJ0Mk0RK/4NTWlK6H3bQqQ1Yd0MCmb//MPfYo oXD7Yzt7KtoCLySSIrNZVQgp2+IcbuqL/88xg1RxF4spcuMhPWyqYg5MU58zg0m7UgP1 KvD1RI8/JkQX5sYnR6hxw9RBBkPSplHUWcWc3JsURCSm8Th4TcUMMslu93BnckZ9sL5A 7gi3oBscE9v2Pcxtqf6Hh5+dqzS8e4Bk9YRcGWp87LwN9soYzD54qtBLw5/L4bNnEajU xmuqBbXs0YR/Wa7ovIMWL3Ak0TpkWaawoWnvlD0nNo29Lt7yqSWn9wf2yxAD25Z/hYrs YluQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:dlp-filter:cms-type:message-id :date:subject:cc:to:from:dkim-signature:dkim-filter :arc-authentication-results; bh=+04agKBZZtylaItf2OCXy5/Elyuo7tDNe+2NU/s8ZO8=; b=pNExppyz4k47hKpqj+ZHNgFjYuaoj5Gaslq3r3etVPkjWODMbfUqWJtsUO8Cx3bJL5 3h431DAUAyaas8r54Jny8SU7pyCjjKnC4rq+gZowgIoJCmPxJxdIKkOohFimmIwXfws5 e14N1gGQBnvi4yJ7NGYFFLF/V/Ky/HoahEG7QviAwqgL2y1me+ST4ypVh0NsLM/tObg4 DovXHw6KX3ikm37pmrzo/9VWxmGSeSmzOPsyQh5UX0sII9bdiOBU+W9PZDj5KW0z8Txe kFMUoHW6zn4QjnU8lFFLSuS3uOxSgBF6dxeE/8SnE+QV617CAjnXFF6c63UBZtitpFZo D4tg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=vIcrmMGo; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c66si5204403pga.494.2018.03.29.22.53.23; Thu, 29 Mar 2018 22:53:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=vIcrmMGo; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751361AbeC3FwO (ORCPT + 99 others); Fri, 30 Mar 2018 01:52:14 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:19298 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750764AbeC3FwM (ORCPT ); Fri, 30 Mar 2018 01:52:12 -0400 Received: from epcas1p2.samsung.com (unknown [182.195.41.46]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20180330055210epoutp040c3db843a36f6bc38ec16ecdf1bec9a6~gnNk2OH0S1769517695epoutp04a; Fri, 30 Mar 2018 05:52:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20180330055210epoutp040c3db843a36f6bc38ec16ecdf1bec9a6~gnNk2OH0S1769517695epoutp04a DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1522389130; bh=+04agKBZZtylaItf2OCXy5/Elyuo7tDNe+2NU/s8ZO8=; h=From:To:Cc:Subject:Date:References:From; b=vIcrmMGosBkCxRfgjYggPV4hJruPJMU7ftmvG8wU2U5s4NHlnhSW9jJzdu3kSC55W 5u2sstsXkw1XcoCdvHsfgxIl506zECJae0EMhA+sGgUTv3r/Ql/o8vPd3HjtZBBB/K kdSesjrZK8EtfWvEuDlXYKQCV+nINMblkkgGTJeQ= Received: from epsmges1p2.samsung.com (unknown [182.195.40.60]) by epcas1p3.samsung.com (KnoxPortal) with ESMTP id 20180330055210epcas1p3fcad0867fb8c819c9c17822f76b710a6~gnNkjOe7i2664826648epcas1p3K; Fri, 30 Mar 2018 05:52:10 +0000 (GMT) Received: from epcas1p1.samsung.com ( [182.195.41.45]) by epsmges1p2.samsung.com (Symantec Messaging Gateway) with SMTP id 3E.D0.04034.880DDBA5; Fri, 30 Mar 2018 14:52:08 +0900 (KST) Received: from epsmgms2p1new.samsung.com (unknown [182.195.42.142]) by epcas1p1.samsung.com (KnoxPortal) with ESMTP id 20180330055207epcas1p14d562f44802bac86a8a7cd95fe2d009f~gnNiN5cOT1555415554epcas1p1K; Fri, 30 Mar 2018 05:52:07 +0000 (GMT) X-AuditID: b6c32a36-f6fff70000000fc2-02-5abdd088dd44 Received: from epmmp2 ( [203.254.227.17]) by epsmgms2p1new.samsung.com (Symantec Messaging Gateway) with SMTP id D9.11.03849.780DDBA5; Fri, 30 Mar 2018 14:52:07 +0900 (KST) Received: from localhost.localdomain ([10.253.107.61]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P6E00F9Y2YNM660@mmp2.samsung.com>; Fri, 30 Mar 2018 14:52:07 +0900 (KST) From: Ji-Hun Kim To: gregkh@linuxfoundation.org, baijiaju1990@gmail.com, forest@alittletooquiet.net Cc: dartnorris@gmail.com, santhameena13@gmail.com, julia.lawall@lip6.fr, ji_hun.kim@samsung.com, y.k.oh@samsung.com, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org Subject: [PATCH v4 1/2] staging: vt6655: check for memory allocation failures Date: Fri, 30 Mar 2018 14:51:54 +0900 Message-id: <1522389115-1124-1-git-send-email-ji_hun.kim@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrGKsWRmVeSWpSXmKPExsWy7bCmrm7Hhb1RBkuv8Fmsm7iQyeLM+7NM FnvO/GK3uD/hEatF8+L1bBb9p7czWix7cJrRYustaYvLu+awWZzcJm+xpesHqwO3R3Pje1aP e/sOs3jsnHWX3WP/3DXsHnu3ZHn0bVnF6PF5k1wAe1SqTUZqYkpqkUJqXnJ+SmZeuq2Sd3C8 c7ypmYGhrqGlhbmSQl5ibqqtkotPgK5bZg7QhUoKZYk5pUChgMTiYiV9O5ui/NKSVIWM/OIS W6VoQ0MjPUMDcz0jIyM9E/NYKyNToJKE1Iz7P1pYCu65VBw4+Yu1gXGqRRcjJ4eEgInE90+3 GLsYuTiEBHYwSnyae50JwvnOKNEx8wg7TNXi2z1QVRsYJZ7NaWOHcH4wSvxbfpcRpIpNQFNi Y/c1MFtEIERixY5tLCBFzAKXGCUWr13JDJIQFvCX6OyaygpiswioSny7MZUFxOYVcJU4/mgt G8Q6OYmTxyazgjRLCMxhk+i90wOVcJH4u/wRC4QtLPHq+BagMziAbGmJS0dtIcLVEguu7IAq qZG4+X8pE4RtLNHbcwHsBmYBPol3X3tYIVp5JTrahCBKPCT2vnvJCmE7SkybNA2sREggVuLW W8cJjJILGBlWMYqlFhTnpqcWGxYY6RUn5haX5qXrJefnbmIEpxktsx2Mi875HGIU4GBU4uFV YNkbJcSaWFZcmXuIUYKDWUmE1+okUIg3JbGyKrUoP76oNCe1+BCjKTAwJjJLiSbnA1NgXkm8 oYmlgYmZkampoYGFiZI4b0CAS5SQQHpiSWp2ampBahFMHxMHp1QDY9CCeBt3x1WJzE76CtGr Nk+++d3s9UazLeG2axUW5netdWQ3a1RO8Zizaa1kZIDNH9me/S83z7r7cLr46vW9+3pZamRv VUrPaT18dQLXF/4wsZcPK9Xal3zvz3PaurdH53/pO9sJ1zaXiiWUMPApx3l869Hq35h85rH9 TYGJEc7v3be7ymUIKrEUZyQaajEXFScCAPFjuZ9JAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupnluLIzCtJLcpLzFFi42I5/e+xoG77hb1RBpOWmFmsm7iQyeLM+7NM FnvO/GK3uD/hEatF8+L1bBb9p7czWix7cJrRYustaYvLu+awWZzcJm+xpesHqwO3R3Pje1aP e/sOs3jsnHWX3WP/3DXsHnu3ZHn0bVnF6PF5k1wAexSXTUpqTmZZapG+XQJXxv0fLSwF91wq Dpz8xdrAONWii5GTQ0LARGLx7R7GLkYuDiGBdYwSZ/YuZwVJCAn8YJS4Mk0HxGYT0JTY2H2N EcQWEQiR+N98FayBWeASo8T2x3PBEsICvhIHnk9nBrFZBFQlvt2YygJi8wq4Shx/tJYNYpuc xMljk1knMHItYGRYxSiZWlCcm55bbFRgmJdarlecmFtcmpeul5yfu4kRGEzbDmv17WC8vyT+ EKMAB6MSD28F294oIdbEsuLK3EOMEhzMSiK8VieBQrwpiZVVqUX58UWlOanFhxilOViUxHlv 5x2LFBJITyxJzU5NLUgtgskycXBKNTBO8FjvnPp+mvwRo3cGHjJrPPLW9uZzJHt8isw8HB4X 7B8667eaQMaD9Ym+x82fLX4eYJg8p2Tp673Xpu0q5ClJ3VjLeelqyoqpsxQDZm9m/7RbTiJ0 55JV3utWeoZ6SPgamDxcEvB4zt6/LVL7HE8l/5o3TzxpwnN7p20s5Sfkbhuvya/5puGjxFKc kWioxVxUnAgASaFrjiICAAA= X-CMS-MailID: 20180330055207epcas1p14d562f44802bac86a8a7cd95fe2d009f X-Msg-Generator: CA CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20180330055207epcas1p14d562f44802bac86a8a7cd95fe2d009f X-RootMTR: 20180330055207epcas1p14d562f44802bac86a8a7cd95fe2d009f References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There are no null pointer checking on rd_info and td_info values which are allocated by kzalloc. It has potential null pointer dereferencing issues. Implement error handling code on device_init_rd*, device_init_td* and vnt_start for the allocation failures. Signed-off-by: Ji-Hun Kim --- Changes v2: - Delete WARN_ON which can makes crashes on some machines. - Instead of return directly, goto freeing function for freeing previously allocated memory in the for loop after kzalloc() failed. - In the freeing function, add if statement for freeing to only allocated values. Changes v3: - Modify return type of device_init_rd*, device_init_td*. Then add returns error code at those functions and vnt_start as well. Changes v4: - Fix potential memory leaks from error handling code of device init functions in vnt_start(). drivers/staging/vt6655/device_main.c | 121 ++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 32 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index fbc4bc6..c9752df 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -124,10 +124,10 @@ static void device_free_info(struct vnt_private *priv); static void device_print_info(struct vnt_private *priv); -static void device_init_rd0_ring(struct vnt_private *priv); -static void device_init_rd1_ring(struct vnt_private *priv); -static void device_init_td0_ring(struct vnt_private *priv); -static void device_init_td1_ring(struct vnt_private *priv); +static int device_init_rd0_ring(struct vnt_private *priv); +static int device_init_rd1_ring(struct vnt_private *priv); +static int device_init_td0_ring(struct vnt_private *priv); +static int device_init_td1_ring(struct vnt_private *priv); static int device_rx_srv(struct vnt_private *priv, unsigned int idx); static int device_tx_srv(struct vnt_private *priv, unsigned int idx); @@ -528,18 +528,22 @@ static void device_free_rings(struct vnt_private *priv) priv->tx0_bufs, priv->tx_bufs_dma0); } -static void device_init_rd0_ring(struct vnt_private *priv) +static int device_init_rd0_ring(struct vnt_private *priv) { int i; dma_addr_t curr = priv->rd0_pool_dma; struct vnt_rx_desc *desc; + int ret = 0; /* Init the RD0 ring entries */ for (i = 0; i < priv->opts.rx_descs0; i ++, curr += sizeof(struct vnt_rx_desc)) { desc = &priv->aRD0Ring[i]; desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL); - + if (!desc->rd_info) { + ret = -ENOMEM; + goto error; + } if (!device_alloc_rx_buf(priv, desc)) dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); @@ -550,20 +554,29 @@ static void device_init_rd0_ring(struct vnt_private *priv) if (i > 0) priv->aRD0Ring[i-1].next_desc = cpu_to_le32(priv->rd0_pool_dma); priv->pCurrRD[0] = &priv->aRD0Ring[0]; + + return 0; +error: + device_free_rd0_ring(priv); + return ret; } -static void device_init_rd1_ring(struct vnt_private *priv) +static int device_init_rd1_ring(struct vnt_private *priv) { int i; dma_addr_t curr = priv->rd1_pool_dma; struct vnt_rx_desc *desc; + int ret = 0; /* Init the RD1 ring entries */ for (i = 0; i < priv->opts.rx_descs1; i ++, curr += sizeof(struct vnt_rx_desc)) { desc = &priv->aRD1Ring[i]; desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL); - + if (!desc->rd_info) { + ret = -ENOMEM; + goto error; + } if (!device_alloc_rx_buf(priv, desc)) dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); @@ -574,6 +587,11 @@ static void device_init_rd1_ring(struct vnt_private *priv) if (i > 0) priv->aRD1Ring[i-1].next_desc = cpu_to_le32(priv->rd1_pool_dma); priv->pCurrRD[1] = &priv->aRD1Ring[0]; + + return 0; +error: + device_free_rd1_ring(priv); + return ret; } static void device_free_rd0_ring(struct vnt_private *priv) @@ -584,12 +602,12 @@ static void device_free_rd0_ring(struct vnt_private *priv) struct vnt_rx_desc *desc = &priv->aRD0Ring[i]; struct vnt_rd_info *rd_info = desc->rd_info; - dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, - priv->rx_buf_sz, DMA_FROM_DEVICE); - - dev_kfree_skb(rd_info->skb); - - kfree(desc->rd_info); + if (rd_info) { + dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, + priv->rx_buf_sz, DMA_FROM_DEVICE); + dev_kfree_skb(rd_info->skb); + kfree(desc->rd_info); + } } } @@ -601,27 +619,31 @@ static void device_free_rd1_ring(struct vnt_private *priv) struct vnt_rx_desc *desc = &priv->aRD1Ring[i]; struct vnt_rd_info *rd_info = desc->rd_info; - dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, - priv->rx_buf_sz, DMA_FROM_DEVICE); - - dev_kfree_skb(rd_info->skb); - - kfree(desc->rd_info); + if (rd_info) { + dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, + priv->rx_buf_sz, DMA_FROM_DEVICE); + dev_kfree_skb(rd_info->skb); + kfree(desc->rd_info); + } } } -static void device_init_td0_ring(struct vnt_private *priv) +static int device_init_td0_ring(struct vnt_private *priv) { int i; dma_addr_t curr; struct vnt_tx_desc *desc; + int ret = 0; curr = priv->td0_pool_dma; for (i = 0; i < priv->opts.tx_descs[0]; i++, curr += sizeof(struct vnt_tx_desc)) { desc = &priv->apTD0Rings[i]; desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL); - + if (!desc->td_info) { + ret = -ENOMEM; + goto error; + } desc->td_info->buf = priv->tx0_bufs + i * PKT_BUF_SZ; desc->td_info->buf_dma = priv->tx_bufs_dma0 + i * PKT_BUF_SZ; @@ -632,13 +654,19 @@ static void device_init_td0_ring(struct vnt_private *priv) if (i > 0) priv->apTD0Rings[i-1].next_desc = cpu_to_le32(priv->td0_pool_dma); priv->apTailTD[0] = priv->apCurrTD[0] = &priv->apTD0Rings[0]; + + return 0; +error: + device_free_td0_ring(priv); + return ret; } -static void device_init_td1_ring(struct vnt_private *priv) +static int device_init_td1_ring(struct vnt_private *priv) { int i; dma_addr_t curr; struct vnt_tx_desc *desc; + int ret = 0; /* Init the TD ring entries */ curr = priv->td1_pool_dma; @@ -646,7 +674,10 @@ static void device_init_td1_ring(struct vnt_private *priv) i++, curr += sizeof(struct vnt_tx_desc)) { desc = &priv->apTD1Rings[i]; desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL); - + if (!desc->td_info) { + ret = -ENOMEM; + goto error; + } desc->td_info->buf = priv->tx1_bufs + i * PKT_BUF_SZ; desc->td_info->buf_dma = priv->tx_bufs_dma1 + i * PKT_BUF_SZ; @@ -657,6 +688,11 @@ static void device_init_td1_ring(struct vnt_private *priv) if (i > 0) priv->apTD1Rings[i-1].next_desc = cpu_to_le32(priv->td1_pool_dma); priv->apTailTD[1] = priv->apCurrTD[1] = &priv->apTD1Rings[0]; + + return 0; +error: + device_free_td1_ring(priv); + return ret; } static void device_free_td0_ring(struct vnt_private *priv) @@ -667,8 +703,10 @@ static void device_free_td0_ring(struct vnt_private *priv) struct vnt_tx_desc *desc = &priv->apTD0Rings[i]; struct vnt_td_info *td_info = desc->td_info; - dev_kfree_skb(td_info->skb); - kfree(desc->td_info); + if (td_info) { + dev_kfree_skb(td_info->skb); + kfree(desc->td_info); + } } } @@ -680,8 +718,10 @@ static void device_free_td1_ring(struct vnt_private *priv) struct vnt_tx_desc *desc = &priv->apTD1Rings[i]; struct vnt_td_info *td_info = desc->td_info; - dev_kfree_skb(td_info->skb); - kfree(desc->td_info); + if (td_info) { + dev_kfree_skb(td_info->skb); + kfree(desc->td_info); + } } } @@ -1165,10 +1205,18 @@ static int vnt_start(struct ieee80211_hw *hw) } dev_dbg(&priv->pcid->dev, "call device init rd0 ring\n"); - device_init_rd0_ring(priv); - device_init_rd1_ring(priv); - device_init_td0_ring(priv); - device_init_td1_ring(priv); + ret = device_init_rd0_ring(priv); + if (ret) + goto err_init_rd0_ring; + ret = device_init_rd1_ring(priv); + if (ret) + goto err_init_rd1_ring; + ret = device_init_td0_ring(priv); + if (ret) + goto err_init_td0_ring; + ret = device_init_td1_ring(priv); + if (ret) + goto err_init_td1_ring; device_init_registers(priv); @@ -1178,6 +1226,15 @@ static int vnt_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); return 0; + +err_init_td1_ring: + device_free_td0_ring(priv); +err_init_td0_ring: + device_free_rd1_ring(priv); +err_init_rd1_ring: + device_free_rd0_ring(priv); +err_init_rd0_ring: + return ret; } static void vnt_stop(struct ieee80211_hw *hw) -- 1.9.1