Received: by 10.213.65.68 with SMTP id h4csp2164245imn; Thu, 29 Mar 2018 19:45:45 -0700 (PDT) X-Google-Smtp-Source: AIpwx48WZUHtkld85kUCIK3v+3MG68LyNJ+5j9zRW4pAPLxjs8aik40Zc4xjH/R9iVLL5xf/Ifmv X-Received: by 2002:a17:902:e5:: with SMTP id a92-v6mr10857381pla.26.1522377945028; Thu, 29 Mar 2018 19:45:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522377944; cv=none; d=google.com; s=arc-20160816; b=JVAU8rKHHOuBM4z53AUPHH7nRN5ygG7cHOECgz6n3665x3eQi368TMXpuWeH3rxAoB 6MxZz6GQHnju21OK1daz5U3eSFU6edOO4O9E/7d9xrJzmy2L8tvZL62j7tBRJkEVGeo9 4hQSY9XdjVK4UZ+jaDOCS6dtdHExWwWwbcoMKu7ohdDrt4KXXgw0090i0nH9c8NkIgeX JUXTMbM+SLV16DnpBs34Is6tcvxWJ8hPLA1BH63OvXRi6GpSmHs2mnQl+SEiW/dsVtdA wdwjhKyUtNE/Vy/1cyu8R+k4yqVeUAd6n3tmbmQQk2mtTc8GMDaFbpD5bVjRHjAtxh1I jCrg== 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=TIOWrbDRJ5DIKoU6WGSjiHLo/px8Y6QlESH/ZAxIo6A=; b=XXfPeBGffQfywGZw/mdgRLcGnphN7ovY7tqVihwHZF9BfZ7+uuiBELzFY1pzh7SQbj 9jkPBXJJNI6ey0EzlQ7+55BTk2bS5bNFT5FGP1nZAOenZDCq+P3cznoSjZxtP434pKaX tTRO0W6dN5vcLzfjfFF875JH94e8xP5i9cAGEH1Q0PDtEjDJvFwLX6O/VOM2TWcBuUE3 ggSsWOdZEjiLl6xZL8Ml82Rf9sG2N4SEetYM9XRmFJN5wJVViSBLQ07xL8Tl2ZeLZO0X 4zcVfN0r/MMYHSSu00QohXbVGhUxUsH6U9URzhXcdho151azqu1hXNUeO8ppCb76Y6zw BSug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=JYIeTXD/; 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 p1-v6si7174118plb.745.2018.03.29.19.45.31; Thu, 29 Mar 2018 19:45:44 -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=JYIeTXD/; 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 S1752511AbeC3CoV (ORCPT + 99 others); Thu, 29 Mar 2018 22:44:21 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:10676 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751215AbeC3CoT (ORCPT ); Thu, 29 Mar 2018 22:44:19 -0400 Received: from epcas1p2.samsung.com (unknown [182.195.41.46]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20180330024417epoutp02aa64c27e3176a86a89f6d2636c1fcd7c~gkphbae2n1640416404epoutp02O; Fri, 30 Mar 2018 02:44:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20180330024417epoutp02aa64c27e3176a86a89f6d2636c1fcd7c~gkphbae2n1640416404epoutp02O DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1522377857; bh=TIOWrbDRJ5DIKoU6WGSjiHLo/px8Y6QlESH/ZAxIo6A=; h=From:To:Cc:Subject:Date:References:From; b=JYIeTXD/S1ALxaSLH4/lWIUJHxFiz6nITZYxDXq1E/evWlIhTj8a7NTpOrlHarqHP Yz/WCSy2IAcvE1Nasuqq3L9hnDfM7+vVOMv4d1gGuEPYmai/sfEfAKt90sktpgFCRJ Fh5ct7/oy3/VZe285Im7TcveQsOV82QAkB5Buv6Q= Received: from epsmges2p4.samsung.com (unknown [182.195.40.94]) by epcas1p1.samsung.com (KnoxPortal) with ESMTP id 20180330024416epcas1p1072b08f01c4a22f3cbf6214930b28187~gkphJzCkw3169531695epcas1p1a; Fri, 30 Mar 2018 02:44:16 +0000 (GMT) Received: from epcas2p2.samsung.com ( [182.195.41.54]) by epsmges2p4.samsung.com (Symantec Messaging Gateway) with SMTP id 23.2B.04082.084ADBA5; Fri, 30 Mar 2018 11:44:16 +0900 (KST) Received: from epsmgms2p2new.samsung.com (unknown [182.195.42.143]) by epcas2p2.samsung.com (KnoxPortal) with ESMTP id 20180330024416epcas2p2f566f43a8f5af8b4ebc17659e3cf0ecf~gkpg4OkSn2858328583epcas2p2A; Fri, 30 Mar 2018 02:44:16 +0000 (GMT) X-AuditID: b6c32a48-8d9ff70000000ff2-3c-5abda48026d6 Received: from epmmp1.local.host ( [203.254.227.16]) by epsmgms2p2new.samsung.com (Symantec Messaging Gateway) with SMTP id 4E.7A.03827.084ADBA5; Fri, 30 Mar 2018 11:44:16 +0900 (KST) Received: from localhost.localdomain ([10.253.107.61]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P6D00I9EU9OS330@mmp1.samsung.com>; Fri, 30 Mar 2018 11:44:16 +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 v3] staging: vt6655: check for memory allocation failures Date: Fri, 30 Mar 2018 11:44:04 +0900 Message-id: <1522377844-23591-1-git-send-email-ji_hun.kim@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrOKsWRmVeSWpSXmKPExsWy7bCmmW7Dkr1RBps36Fusm7iQyeLM+7NM FnvO/GK3uD/hEatF8+L1bBb9p7czWix7cJrRYustaYvLu+awWZzcJm+xpesHqwO3R3Pje1aP e/sOs3jsnHWX3WP/3DXsHnu3ZHn0bVnF6PF5k1wAe1SqTUZqYkpqkUJqXnJ+SmZeuq2Sd3C8 c7ypmYGhrqGlhbmSQl5ibqqtkotPgK5bZg7QhUoKZYk5pUChgMTiYiV9O5ui/NKSVIWM/OIS W6VoQ0MjPUMDcz0jIyM9E/NYKyNToJKE1Iy+P1cYC6Y4VfT/mcbawPjBtIuRk0NCwETi4PU5 LF2MXBxCAjsYJSZNPMUG4XxnlPhw6yAbTNWlFeeZIBK7GSW23XnACOH8YJT4N/seE0gVm4Cm xMbua4wgtohAiMSKHdvA5jILXGKUWLx2JTNIQljAU+Lay5lgDSwCqhIfTt1iB7F5Bdwk5n58 xwKxTk7i5LHJrBD2HDaJrVNkIWwXiX9TzzJC2MISr45vYYewpSWerdoIFa+WWHBlB9ScGomb /5cyQdjGEr09F8BuYBbgk+g4/BeolwMozivR0SYEUeIhcfvaJ6iRjhKzPj0FKxcSiJXo3PGP ZQKj5AJGhlWMYqkFxbnpqcVGBSZ6xYm5xaV56XrJ+bmbGMGJRstjB+OBcz6HGAU4GJV4eBVY 9kYJsSaWFVfmHmKU4GBWEuEtnwoU4k1JrKxKLcqPLyrNSS0+xGgKDI2JzFKiyfnAJJhXEm9o YmlgYmZmaG5kamCuJM7bFuASJSSQnliSmp2aWpBaBNPHxMEp1cC4X9KZoTCP3X7tGUcfJr9l +yom/S0SL2VcKXx0zXX7C1VHlsUf32vH8XP1/rkLDjTV9/0Iqv/67MiHtIWxe4Xim4O+dt30 5xZwqzF4VHMv7zL3kivVz5JSFkqGBAlrTvLys5E4vLPgBZdSS3RWwLPXKvNP1PTV3rqZm/Nu 4vt991fey8opub1IiaU4I9FQi7moOBEA+yjzjEoDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprALMWRmVeSWpSXmKPExsVy+t9jAd2GJXujDJp6pC3WTVzIZHHm/Vkm iz1nfrFb3J/wiNWiefF6Nov+09sZLZY9OM1osfWWtMXlXXPYLE5uk7fY0vWD1YHbo7nxPavH vX2HWTx2zrrL7rF/7hp2j71bsjz6tqxi9Pi8SS6APYrLJiU1J7MstUjfLoEro+/PFcaCKU4V /X+msTYwfjDtYuTkkBAwkbi04jxTFyMXh5DATkaJOd+vsUM4Pxgl9r3byAZSxSagKbGx+xoj iC0iECLxv/kqI0gRs8AlRontj+eCJYQFPCWuvZzJBGKzCKhKfDh1ix3E5hVwk5j78R0LxDo5 iZPHJrNOYORawMiwilEytaA4Nz232KjAKC+1XK84Mbe4NC9dLzk/dxMjMJy2Hdbq38H4eEn8 IUYBDkYlHt4Ktr1RQqyJZcWVuYcYJTiYlUR4y6cChXhTEiurUovy44tKc1KLDzFKc7AoifPy 5x+LFBJITyxJzU5NLUgtgskycXBKNTDOfPj5X3YLm3Xeye5frp/VhVJTEt4t2f1u6/2J19yL dHdVqKw6scp5gc15ha8O0wLNfrZvje/XfKL5OKrptb2cya6udy9vz7xb9+uIdVpayY0bE5XN LRvlopp1Z7TYWbusDS0JkIpUba3V01Rw7Al4UM078/AentzH7/8927Vwrd7FG8tebnqrxFKc kWioxVxUnAgAKiBi3CMCAAA= X-CMS-MailID: 20180330024416epcas2p2f566f43a8f5af8b4ebc17659e3cf0ecf X-Msg-Generator: CA CMS-TYPE: 102P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20180330024416epcas2p2f566f43a8f5af8b4ebc17659e3cf0ecf X-RootMTR: 20180330024416epcas2p2f566f43a8f5af8b4ebc17659e3cf0ecf 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. drivers/staging/vt6655/device_main.c | 114 +++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 32 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index fbc4bc6..0d55f34 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 error; + ret = device_init_rd1_ring(priv); + if (ret) + goto error; + ret = device_init_td0_ring(priv); + if (ret) + goto error; + ret = device_init_td1_ring(priv); + if (ret) + goto error; device_init_registers(priv); @@ -1178,6 +1226,8 @@ static int vnt_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); return 0; +error: + return ret; } static void vnt_stop(struct ieee80211_hw *hw) -- 1.9.1