All of lore.kernel.org
 help / color / mirror / Atom feed
From: Devin Heitmueller <dheitmueller@kernellabs.com>
To: Mauro Carvalho Chehab <mchehab@redhat.com>
Cc: linux-media@vger.kernel.org
Subject: Re: [PATCH 17/24] au0828: fix possible race condition in usage of dev->ctrlmsg
Date: Thu, 9 Aug 2012 20:57:42 -0400	[thread overview]
Message-ID: <CAGoCfixzAbLDr3CA_UgvdS8t9ZzcODZTHu7J-FRm0BBQqzPP_Q@mail.gmail.com> (raw)
In-Reply-To: <50244C42.8070303@redhat.com>

On Thu, Aug 9, 2012 at 7:48 PM, Mauro Carvalho Chehab
<mchehab@redhat.com> wrote:
> Em 06-08-2012 23:47, Devin Heitmueller escreveu:
>> The register read function is referencing the dev->ctrlmsg structure outside
>> of the dev->mutex lock, which can cause corruption of the value if multiple
>> callers are invoking au0828_readreg() simultaneously.
>>
>> Use a stack variable to hold the result, and copy the buffer returned by
>> usb_control_msg() to that variable.
>
> It is NOT OK to use stack to send and/or receive control messages. The USB core
> uses DMA transfers for sending/receiving data via USB; the memory used by stack
> is not warranted to be at the DMA-able area. This problem is more frequent on
> ARM-based machines, but even on Intel, the urb_control_msg() may fail.
>
>>
>> In reality, the whole recv_control_msg() function can probably be collapsed
>> into au0288_readreg() since it is the only caller.
>>
>> Also get rid of cmd_msg_dump() since the only case in which the function is
>> ever called only is ever passed a single byte for the response (and it is
>> already logged).
>>
>> Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
>> ---
>>   drivers/media/video/au0828/au0828-core.c |   40 +++++++++---------------------
>>   1 files changed, 12 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
>> index 65914bc..745a80a 100644
>> --- a/drivers/media/video/au0828/au0828-core.c
>> +++ b/drivers/media/video/au0828/au0828-core.c
>> @@ -56,9 +56,12 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
>>
>>   u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
>>   {
>> -     recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1);
>> -     dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]);
>> -     return dev->ctrlmsg[0];
>> +     u8 result = 0;
>> +
>> +     recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, &result, 1);
>
> As explained above, this won't work, as result is at stack, not warranted to be at the
> DMA-able area. So, either you could lock this function, or you'll need to allocate
> it with kmalloc() and free it after using the data.
>
>> +     dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, result);
>> +
>> +     return result;
>>   }
>>
>>   u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
>> @@ -67,24 +70,6 @@ u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
>>       return send_control_msg(dev, CMD_REQUEST_OUT, val, reg);
>>   }
>>
>> -static void cmd_msg_dump(struct au0828_dev *dev)
>> -{
>> -     int i;
>> -
>> -     for (i = 0; i < sizeof(dev->ctrlmsg); i += 16)
>> -             dprintk(2, "%s() %02x %02x %02x %02x %02x %02x %02x %02x "
>> -                             "%02x %02x %02x %02x %02x %02x %02x %02x\n",
>> -                     __func__,
>> -                     dev->ctrlmsg[i+0], dev->ctrlmsg[i+1],
>> -                     dev->ctrlmsg[i+2], dev->ctrlmsg[i+3],
>> -                     dev->ctrlmsg[i+4], dev->ctrlmsg[i+5],
>> -                     dev->ctrlmsg[i+6], dev->ctrlmsg[i+7],
>> -                     dev->ctrlmsg[i+8], dev->ctrlmsg[i+9],
>> -                     dev->ctrlmsg[i+10], dev->ctrlmsg[i+11],
>> -                     dev->ctrlmsg[i+12], dev->ctrlmsg[i+13],
>> -                     dev->ctrlmsg[i+14], dev->ctrlmsg[i+15]);
>> -}
>> -
>>   static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
>>       u16 index)
>>   {
>> @@ -118,24 +103,23 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
>>       int status = -ENODEV;
>>       mutex_lock(&dev->mutex);
>>       if (dev->usbdev) {
>> -
>> -             memset(dev->ctrlmsg, 0, sizeof(dev->ctrlmsg));
>> -
>> -             /* cp must be memory that has been allocated by kmalloc */
>>               status = usb_control_msg(dev->usbdev,
>>                               usb_rcvctrlpipe(dev->usbdev, 0),
>>                               request,
>>                               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
>>                               value, index,
>> -                             cp, size, 1000);
>> +                             dev->ctrlmsg, size, 1000);
>>
>>               status = min(status, 0);
>>
>>               if (status < 0) {
>>                       printk(KERN_ERR "%s() Failed receiving control message, error %d.\n",
>>                               __func__, status);
>> -             } else
>> -                     cmd_msg_dump(dev);
>> +             }
>> +
>> +             /* the host controller requires heap allocated memory, which
>> +                is why we didn't just pass "cp" into usb_control_msg */
>> +             memcpy(cp, dev->ctrlmsg, size);
>>       }
>>       mutex_unlock(&dev->mutex);
>>       return status;
>>
>
> Regards,
> Mauro

Hi Mauro,

You seem to have misinterpreted the patch description.  The actual
call to usb_control_msg() does use a heap allocated memory region.
However we copy the result to a stack variable after the call to
usb_control_msg.  This is done so that dev->ctrlmsg[] is used
exclusively inside of the mutex (and not accessed after the mutex is
unlocked).

The change basically goes from:

au0828_readreg() -> recv_control_msg(heap) -> usb_control_msg(heap)

to:

au0828_readreg() -> recv_control_msg(stack) -> usb_control_msg(heap)

In both cases the call into the USB stack provides heap allocated memory.

Please review the implementation of the static recv_control_msg()
function, and if you have any further questions let me know.

Thanks,

Devin

-- 
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com

  reply	other threads:[~2012-08-10  0:57 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-07  2:46 [PATCH 00/24] Various HVR-950q and xc5000 fixes Devin Heitmueller
2012-08-07  2:46 ` [PATCH 01/24] au8522: fix intermittent lockup of analog video decoder Devin Heitmueller
2012-08-07  2:46 ` [PATCH 02/24] au8522: Fix off-by-one in SNR table for QAM256 Devin Heitmueller
2012-08-07  2:46 ` [PATCH 03/24] au8522: properly recover from the au8522 delivering misaligned TS streams Devin Heitmueller
2012-08-07  2:46 ` [PATCH 04/24] au0828: Make the s_reg and g_reg advanced debug calls work against the bridge Devin Heitmueller
2012-08-07  2:46 ` [PATCH 05/24] xc5000: properly show quality register values Devin Heitmueller
2012-08-07  2:46 ` [PATCH 06/24] xc5000: add support for showing the SNR and gain in the debug output Devin Heitmueller
2012-08-07  2:46 ` [PATCH 07/24] xc5000: properly report i2c write failures Devin Heitmueller
     [not found]   ` <CAPLVkLv6JNvSdSFCY7YNRkmfzHv5+JD7Y5hxvjxdFtRT2JgE2A@mail.gmail.com>
2014-02-07 13:46     ` Devin Heitmueller
2014-02-10  8:25       ` Joonyoung Shim
2014-02-10 13:29         ` Devin Heitmueller
2012-08-07  2:46 ` [PATCH 08/24] au0828: fix race condition that causes xc5000 to not bind for digital Devin Heitmueller
2012-08-07  2:46 ` [PATCH 09/24] au0828: make sure video standard is setup in tuner-core Devin Heitmueller
2012-08-07  2:47 ` [PATCH 10/24] au8522: fix regression in logging introduced by separation of modules Devin Heitmueller
2012-08-07  2:47 ` [PATCH 11/24] xc5000: don't invoke auto calibration unless we really did reset tuner Devin Heitmueller
2012-08-07  2:47 ` [PATCH 12/24] au0828: prevent i2c gate from being kept open while in analog mode Devin Heitmueller
2012-08-07  2:47 ` [PATCH 13/24] au0828: fix case where STREAMOFF being called on stopped stream causes BUG() Devin Heitmueller
2012-08-07  2:47 ` [PATCH 14/24] au0828: speed up i2c clock when doing xc5000 firmware load Devin Heitmueller
2012-08-07  2:47 ` [PATCH 15/24] au0828: remove control buffer from send_control_msg Devin Heitmueller
2012-08-07  2:47 ` [PATCH 16/24] au0828: tune retry interval for i2c interaction Devin Heitmueller
2012-08-07  2:47 ` [PATCH 17/24] au0828: fix possible race condition in usage of dev->ctrlmsg Devin Heitmueller
2012-08-09 23:48   ` Mauro Carvalho Chehab
2012-08-10  0:57     ` Devin Heitmueller [this message]
2012-08-07  2:47 ` [PATCH 18/24] xc5000: reset device if encountering PLL lock failure Devin Heitmueller
2012-08-07  2:47 ` [PATCH 19/24] xc5000: add support for firmware load check and init status Devin Heitmueller
2012-08-07  2:47 ` [PATCH 20/24] au0828: tweak workaround for i2c clock stretching bug Devin Heitmueller
2012-08-07  2:47 ` [PATCH 21/24] xc5000: show debug version fields in decimal instead of hex Devin Heitmueller
2012-08-07  2:47 ` [PATCH 22/24] au0828: fix a couple of missed edge cases for i2c gate with analog Devin Heitmueller
2012-08-07  2:47 ` [PATCH 23/24] au0828: make xc5000 firmware speedup apply to the xc5000c as well Devin Heitmueller
2012-08-07  2:47 ` [PATCH 24/24] xc5000: change filename to production/redistributable xc5000c firmware Devin Heitmueller
2012-08-07  6:26 ` [PATCH 00/24] Various HVR-950q and xc5000 fixes Hans Verkuil
2012-08-07 12:48   ` Devin Heitmueller
2012-08-07 12:59     ` Hans Verkuil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAGoCfixzAbLDr3CA_UgvdS8t9ZzcODZTHu7J-FRm0BBQqzPP_Q@mail.gmail.com \
    --to=dheitmueller@kernellabs.com \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.