Received: by 10.213.65.68 with SMTP id h4csp535272imn; Wed, 4 Apr 2018 02:55:39 -0700 (PDT) X-Google-Smtp-Source: AIpwx48joT8U5sfCvAQkfx9J8AM4mLq4yrsKzdoerFr4T5e9L765IjuuuYMjr0rQDjctIKlny1vG X-Received: by 2002:a17:902:2be4:: with SMTP id l91-v6mr18338457plb.102.1522835739469; Wed, 04 Apr 2018 02:55:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522835739; cv=none; d=google.com; s=arc-20160816; b=eFHWsIjVci9GZ2lYPXx0HndK505r1lP2/1ES8zM0E12mQLjYXwkKxUZznbYIsREqh3 U28uNWoq3N1XljRo+4iXwWfzyXhCo9iCZ9iXUJxxDRArsrfPgtOMqXcwMJl0LbtQtcmw ogE8LTc/FDbdhBCkqFQfIykiM4qydg1Lw+8zKJVjYBFgWJ+Ogag5CEhu6da/beM14My+ nstxhlqHb1G97IKoWxQO4jk94G9MK+UqJGA15MhgyjGnjUMOIbM63S6fkx6H5T0Wy5Fh 0vpPXBqXW4lT4Td1WiyEsHlKoUMDhhx2K6/9zFvezx9hNyik+AlltpY83JjfD/UZk85V KM2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=5i7HrOGp/JNrYVpsAnenleP6zfBm5L5tcYP5wVkgLu0=; b=o8tTRTmo9zw2oxCNtuujeoyfczCaEziaah2OjZ6C/IzS8F0t0uu2R7JNTep26W5EW3 bvXjJrl4EJgjw2Gpd2ejwSMsU/xhmUGP1Hhafxb4omxMIdq4qhFLv54ykQna26WPav+g fhMFwBx4opEbIpsakZf34Tvex4vv5JwjSkMmIG2K755VNJwu/igNpxHsjyETmf7+Jjfe Yo6U/G8nR6wge0EkO7EHeLCoF9YSekZZETV8BlfYms/x/eCW4z1b3YJ4E1Ez0ubqEQjc gSdVFtYgw57wlFIsLYVHwsUVGgHXIfGN70EZMVs7QboJbst3nPPzsX3VX0uzZ3DTB+Wf cBBg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2017-10-26 header.b=n8aWcVcI; 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=oracle.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e11-v6si2727631plt.683.2018.04.04.02.55.25; Wed, 04 Apr 2018 02:55:39 -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=@oracle.com header.s=corp-2017-10-26 header.b=n8aWcVcI; 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=oracle.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751339AbeDDJxn (ORCPT + 99 others); Wed, 4 Apr 2018 05:53:43 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:44680 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751017AbeDDJxl (ORCPT ); Wed, 4 Apr 2018 05:53:41 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w349hNHE001574; Wed, 4 Apr 2018 09:53:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=date : from : to : cc : subject : message-id : references : mime-version : content-type : in-reply-to; s=corp-2017-10-26; bh=5i7HrOGp/JNrYVpsAnenleP6zfBm5L5tcYP5wVkgLu0=; b=n8aWcVcIKTu8nD1GFHUJA+ZaMbpwhKUPB+GaOuC33odXmEtwOzTzHQo9AWNjcVRPP6qi a0tC18kd3BgSxVOpnzGimwwfC7WMTdSEaxHz1AYqYhfgq4LNMMGCytMMoRQoF/iq5+LU 6ZpfxIoKADadbup95kjDGpgI+iDPnIHMbcNC2YznkUFF+g9OuU5rwM6RC24UQFM+MMwK M2I48xxdtdfSt9DIaJR26K1qlqSDYRnAm0Gy63fGHi5In518wMVKWXgixAL0bWdumYp9 uVc4rHwHVbRrL+kRH3QJwyWqhyK6leUOz17Q+3dAO3cjR77ujvqcmMO25lJy2Aqx8yTb yQ== Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp2130.oracle.com with ESMTP id 2h4vaw815a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 04 Apr 2018 09:53:32 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.14.4/8.14.4) with ESMTP id w349rUwM005944 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 4 Apr 2018 09:53:30 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w349rSfa003947; Wed, 4 Apr 2018 09:53:28 GMT Received: from mwanda (/197.254.35.146) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 04 Apr 2018 02:53:28 -0700 Date: Wed, 4 Apr 2018 12:53:19 +0300 From: Dan Carpenter To: Ji-Hun Kim Cc: gregkh@linuxfoundation.org, baijiaju1990@gmail.com, forest@alittletooquiet.net, devel@driverdev.osuosl.org, y.k.oh@samsung.com, kernel-janitors@vger.kernel.org, linux-kernel@vger.kernel.org, julia.lawall@lip6.fr, santhameena13@gmail.com Subject: Re: [PATCH v3] staging: vt6655: check for memory allocation failures Message-ID: <20180404095319.zshtp3cbyf6sxsfq@mwanda> References: <1522377844-23591-1-git-send-email-ji_hun.kim@samsung.com> <20180403104052.6wbomdguifrmlmpz@mwanda> <20180404072410.GA31134@ubuntu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180404072410.GA31134@ubuntu> User-Agent: NeoMutt/20170609 (1.8.3) X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8852 signatures=668697 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=2 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1711220000 definitions=main-1804040097 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Apr 04, 2018 at 04:24:10PM +0900, Ji-Hun Kim wrote: > > Since we only partially allocated the > > rd0 ring, device_free_rd0_ring() will crash when we do: > > > > dma_unmap_single(&priv->pcid->dev, rd_info->skb_dma, > > priv->rx_buf_sz, DMA_FROM_DEVICE); > > > > "rd_info" is NULL so rd_info->skb_dma is a NULL dereference. > > For dealing with this problem, I added below code on patch v3. I think it > would not make Null dereferencing issues, because it will not enter > dma_unmap_single(), if "rd_info" is Null. > > + 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); > + } > > I would appreciate for your opinions what would be better way for freeing > allocated "rd_info"s in the loop previously. Of course, that works for this particular bug but I'm not a fan of that approach... When I say "do nothing" gotos, I mean. err: return ret; And what I mean by "one err" is this: err: free(a); free(b) free(c); return ret; There is only one error label even though we are freeing three things. The problem with that is that you might be freeing something this hasn't been allocated like "rd_info->skb_dma" but "rd_info" wasn't allocated. It's a very normally problem to have with this style of error handling. Most kernel error handling is very simple. err_free_c: free(c); err_free_b: free(b); err_free_a: free(a); return ret; Side note: Part of the problem here is that device_alloc_rx_buf() does not have a corresponding free function. Every alloc should have a matching free function so that if we ever change the alloc function, we just have to update one free function. And it's just cleaner. static void device_free_rx_buf(struct vnt_private *priv, struct vnt_rx_desc *rd) { struct vnt_rd_info *rd_info = rd->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); } Maybe send a patch that adds that and changes device_free_rd0_ring() to use the new free function instead of open coding it. [PATCH 1/2]. These particular functions are slighttly complicated because they have loops and the error handling for loops is tricky and bug prone. Here is what I would like the error handling to look like: diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 0dc902022a91..e12a959fe080 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -533,15 +533,23 @@ static void 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; /* 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 err_free_descs; + } - if (!device_alloc_rx_buf(priv, desc)) + if (!device_alloc_rx_buf(priv, desc)) { dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); + ret = -ENOMEM; + goto err_free_rd; + } desc->next = &(priv->aRD0Ring[(i + 1) % priv->opts.rx_descs0]); desc->next_desc = cpu_to_le32(curr + sizeof(struct vnt_rx_desc)); @@ -550,6 +558,20 @@ 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; + +err_free_rd: + kfree(desc->rd_info); + +err_free_descs: + while (--i) { + desc = &priv->aRD0Ring[i]; + device_free_rx_buf(priv, desc); + kfree(desc->rd_info); + } + + return ret; } static void device_init_rd1_ring(struct vnt_private *priv) It's more work to do it this way. It's also more lines of code, but it's easier to read and review because you can look at the function and see that it's correct without jumping to other functions to verify that they check if rd_info is NULL or not. regards, dan carpenter