Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp543240ybj; Thu, 7 May 2020 01:45:21 -0700 (PDT) X-Google-Smtp-Source: APiQypLjQAXA1+sN1HmIpHFjzCQZUq8GQF3Ky6xKy0djjs7/qIRr3paF8qFaaUGgVfmtzLtmm07U X-Received: by 2002:a05:6402:b03:: with SMTP id bm3mr10439229edb.299.1588841121547; Thu, 07 May 2020 01:45:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588841121; cv=none; d=google.com; s=arc-20160816; b=jn2+riLJg57Y6ulWaDqTVSvN5GJws6NuPTT4URCk9jz8jFom6Mpj5+ZvLqjoKm2qDE 2xiVDHFZh1ylkOlmGmXzB7iVjsVhS8dgwxzX+GYENGR8eqwVRisl/hsrjbcPes+2tw+W xczKYj+lKBsPBSPkozd27NShNe1eM2hExdoGQ3ivLaO/TR4vjX41EopBxTgx2qmce0ld IJPyeScrZVqc+psCX5JsbOTiVn1uqkBZhsruHXWwdEA9Gi9KPXEaBKx4NLmapynmA6eF C1c7m7VJJebqUrmJlGpDVlIXcAhxUra7H+PwWEoVdD9K5lN22wRjMgVoFzmiOh0RSc8q t5lQ== 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; bh=wMd8Q9XKI7lRtlOD7EajA7fE02NgjWrCQjxnCSdGeB0=; b=C39zYcca5Ikk98kdMHdbylmeJfMCkHcpQdijIIDwqw6+1uWIYTQEJEC3kxRjbMMbU2 zP6vAdawi/0vi3mBYCLSh3fdukHqKTBaHSK9DsS9zII+ZloBXERQmGCMLZFWxwz5nmBa wE3CcUHMGci4JAxBvO2zhM47CV6fvKGlo/WnN0mhV8YWMt86px0OEnTSRyHeV6MEPRvj Eg7VC3x4zXsrCI/T5wcI016m6pIJ79Dt7Z+Tm+iCKBMzakdAlQ+kkxG1kiM8TnZmnleM ttGqAtH8N22kIt+YscLqothzPf4FGTmmPiQogxPYv5reDzXp6+/y0725PTsIL1YuPlwr LdaA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dn6si2708144edb.514.2020.05.07.01.44.58; Thu, 07 May 2020 01:45:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726069AbgEGInf (ORCPT + 99 others); Thu, 7 May 2020 04:43:35 -0400 Received: from gofer.mess.org ([88.97.38.141]:36089 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725802AbgEGInf (ORCPT ); Thu, 7 May 2020 04:43:35 -0400 Received: by gofer.mess.org (Postfix, from userid 1000) id 247D9C63EB; Thu, 7 May 2020 09:43:33 +0100 (BST) Date: Thu, 7 May 2020 09:43:33 +0100 From: Sean Young To: Jia-Ju Bai Cc: mchehab@kernel.org, kstewart@linuxfoundation.org, tomasbortoli@gmail.com, gregkh@linuxfoundation.org, allison@lohutok.net, tglx@linutronix.de, linux-media@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] media: usb: ttusb-dec: avoid buffer overflow in ttusb_dec_handle_irq() when DMA failures/attacks occur Message-ID: <20200507084332.GA14459@gofer.mess.org> References: <20200505142110.7620-1-baijiaju1990@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200505142110.7620-1-baijiaju1990@gmail.com> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, May 05, 2020 at 10:21:10PM +0800, Jia-Ju Bai wrote: > In ttusb_dec_init_usb(): > dec->irq_buffer = usb_alloc_coherent(...) > > Thus, "dec->irq_buffer" is a DMA value, and it is assigned to "buffer" > in ttusb_dec_handle_irq(): > char *buffer = dec->irq_buffer; > > When DMA failures or attacks occur, the value of buffer[4] can be > changed at any time. In this case, "buffer[4] - 1 < ARRAY_SIZE(rc_keys)" > can be first satisfied, and then the value of buffer[4] can be changed > to a large number, causing a buffer-overflow vulnerability. > > To avoid the risk of this vulnerability, buffer[4] is assigned to a > non-DMA local variable "index" at the beginning of > ttusb_dec_handle_irq(), and then this variable replaces each use of > buffer[4] in the function. This change is the urb completion handler. As I understand it, dma is done by the usb host controller, in this case in response to an interrupt request urb from the usb device side. In the completion handler, once we are done reading the data in the buffer, the urb is submitted again. Only then can the interrupt request urb be resent by the device, so there is no possibility of the dma buffer being overwritten. Now I might be mistaken of course. I can see that firewire and pci devices do suffer from the problems describe in the paper, but not usb. > Signed-off-by: Jia-Ju Bai > --- > drivers/media/usb/ttusb-dec/ttusb_dec.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c > index 3198f9624b7c..8543c552515b 100644 > --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c > +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c > @@ -250,6 +250,7 @@ static void ttusb_dec_handle_irq( struct urb *urb) > struct ttusb_dec *dec = urb->context; > char *buffer = dec->irq_buffer; > int retval; > + u8 index = buffer[4]; > > switch(urb->status) { > case 0: /*success*/ > @@ -281,11 +282,11 @@ static void ttusb_dec_handle_irq( struct urb *urb) > * this should/could be added later ... > * for now lets report each signal as a key down and up > */ > - if (buffer[4] - 1 < ARRAY_SIZE(rc_keys)) { Here buffer[4] is signed char, so if buffer[4] == 0 then (buffer[4] - 1) = -1, this becomes "if (-1 < ARRAY_SIZE(rc_keys))", which evaluates to false, due to it becoming an unsigned compare. _I think_. Not the most readable code at all. > - dprintk("%s:rc signal:%d\n", __func__, buffer[4]); > - input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); > + if (index - 1 < ARRAY_SIZE(rc_keys)) { > + dprintk("%s:rc signal:%d\n", __func__, index); > + input_report_key(dec->rc_input_dev, rc_keys[index - 1], 1); > input_sync(dec->rc_input_dev); > - input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); > + input_report_key(dec->rc_input_dev, rc_keys[index - 1], 0); Like Greg said, this patch reduces the number of dereferences and makes the code much cleaner, but the commit message is misleading. > input_sync(dec->rc_input_dev); > } > } > -- > 2.17.1 Thanks, Sean