From patchwork Wed Jan 20 10:20:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 12031901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8C0CC10DCE for ; Wed, 20 Jan 2021 10:45:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DDA52333C for ; Wed, 20 Jan 2021 10:45:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387730AbhATKmj (ORCPT ); Wed, 20 Jan 2021 05:42:39 -0500 Received: from mx2.suse.de ([195.135.220.15]:56362 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732961AbhATKVn (ORCPT ); Wed, 20 Jan 2021 05:21:43 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 9B356AF90; Wed, 20 Jan 2021 10:21:00 +0000 (UTC) From: Takashi Iwai To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Seyfried Subject: [PATCH 1/2] media: dvb-usb: Fix memory leak at error in dvb_usb_device_init() Date: Wed, 20 Jan 2021 11:20:56 +0100 Message-Id: <20210120102057.21143-2-tiwai@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210120102057.21143-1-tiwai@suse.de> References: <20210120102057.21143-1-tiwai@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org dvb_usb_device_init() allocates a dvb_usb_device object, but it doesn't release it even when returning an error. The callers don't seem caring it as well, hence those memories are leaked. This patch assures releasing the memory at the error path in dvb_usb_device_init(). Also it makes sure that USB intfdata is reset and don't return the bogus pointer to the caller at the error path, too. Cc: Signed-off-by: Takashi Iwai Reviewed-by: Robert Foss --- drivers/media/usb/dvb-usb/dvb-usb-init.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c index c1a7634e27b4..5befec87f26a 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -281,15 +281,21 @@ int dvb_usb_device_init(struct usb_interface *intf, usb_set_intfdata(intf, d); - if (du != NULL) + ret = dvb_usb_init(d, adapter_nums); + if (ret) { + info("%s error while loading driver (%d)", desc->name, ret); + goto error; + } + + if (du) *du = d; - ret = dvb_usb_init(d, adapter_nums); + info("%s successfully initialized and connected.", desc->name); + return 0; - if (ret == 0) - info("%s successfully initialized and connected.", desc->name); - else - info("%s error while loading driver (%d)", desc->name, ret); + error: + usb_set_intfdata(intf, NULL); + kfree(d); return ret; } EXPORT_SYMBOL(dvb_usb_device_init); From patchwork Wed Jan 20 10:20:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 12031925 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A886C433DB for ; Wed, 20 Jan 2021 10:45:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7451D23339 for ; Wed, 20 Jan 2021 10:45:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387717AbhATKmg (ORCPT ); Wed, 20 Jan 2021 05:42:36 -0500 Received: from mx2.suse.de ([195.135.220.15]:56376 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732967AbhATKVn (ORCPT ); Wed, 20 Jan 2021 05:21:43 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id AE908AFB4; Wed, 20 Jan 2021 10:21:00 +0000 (UTC) From: Takashi Iwai To: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Stefan Seyfried Subject: [PATCH 2/2] media: dvb-usb: Fix use-after-free access Date: Wed, 20 Jan 2021 11:20:57 +0100 Message-Id: <20210120102057.21143-3-tiwai@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210120102057.21143-1-tiwai@suse.de> References: <20210120102057.21143-1-tiwai@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org dvb_usb_device_init() copies the properties to the own data, so that the callers can release the original properties later (as done in the commit 299c7007e936 "media: dw2102: Fix memleak on sequence of probes"). However, it also stores dev->desc pointer that is a reference to the original properties data. Since dev->desc is referred later, it may result in use-after-free, in the worst case, leading to a kernel Oops as reported. This patch addresses the problem by allocating and copying the properties at first, then get the desc from the copied properties. Reported-and-tested-by: Stefan Seyfried BugLink: http://bugzilla.opensuse.org/show_bug.cgi?id=1181104 Cc: Signed-off-by: Takashi Iwai Reviewed-by: Robert Foss --- drivers/media/usb/dvb-usb/dvb-usb-init.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c index 5befec87f26a..07ff9b4d2f34 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -255,27 +255,30 @@ int dvb_usb_device_init(struct usb_interface *intf, if (du != NULL) *du = NULL; - if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) { + d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); + if (!d) { + err("no memory for 'struct dvb_usb_device'"); + return -ENOMEM; + } + + memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); + + desc = dvb_usb_find_device(udev, &d->props, &cold); + if (!desc) { deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); - return -ENODEV; + ret = -ENODEV; + goto error; } if (cold) { info("found a '%s' in cold state, will try to load a firmware", desc->name); ret = dvb_usb_download_firmware(udev, props); if (!props->no_reconnect || ret != 0) - return ret; + goto error; } info("found a '%s' in warm state.", desc->name); - d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); - if (d == NULL) { - err("no memory for 'struct dvb_usb_device'"); - return -ENOMEM; - } - d->udev = udev; - memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); d->desc = desc; d->owner = owner;