From patchwork Tue Aug 7 02:47:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Devin Heitmueller X-Patchwork-Id: 1282681 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 0219A3FC8A for ; Tue, 7 Aug 2012 02:48:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932579Ab2HGCs0 (ORCPT ); Mon, 6 Aug 2012 22:48:26 -0400 Received: from mail-vc0-f174.google.com ([209.85.220.174]:52727 "EHLO mail-vc0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932570Ab2HGCsE (ORCPT ); Mon, 6 Aug 2012 22:48:04 -0400 Received: by mail-vc0-f174.google.com with SMTP id fk26so3432709vcb.19 for ; Mon, 06 Aug 2012 19:48:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=RT5Qj79BaUv0zTHDL7EnnIwkcZeoYaNoXg4TujIt/rU=; b=LJD4Sstz24/Ikyq9016ukcXWIzA958/uE32N39OXWHGdkfjMWVrTvDYxDb6rjO7rWA CnlqqV9EJqPoooWfOwOSrXIXVi2tbBfPKlm1nCKZcVlVYZdBAGOYyTALgRS64OHlMf5P vX4zRXh8OFnyMJO2zn/z1qlvOId2ZDJxXDXS7TSc12fj7mnicW6fvemCq2XWgSGLFixY JRwHZhDtt9m9NlcyIiON7A1zDyGhEiWqSIRbdIiD5U5uWr2EDoIq7j5vPUww7hduWVGF aCFQdcZ5rNIDWV6qjUyZ5eR6vV/wEi5TPl/kd2trjXRWdB2Kt9a/Gqraq3YRccv2Pcmq ziJQ== Received: by 10.58.151.197 with SMTP id us5mr11145979veb.14.1344307683908; Mon, 06 Aug 2012 19:48:03 -0700 (PDT) Received: from localhost.localdomain (pool-108-54-72-165.nycmny.fios.verizon.net. [108.54.72.165]) by mx.google.com with ESMTPS id e9sm17555638vdf.21.2012.08.06.19.48.02 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 06 Aug 2012 19:48:03 -0700 (PDT) From: Devin Heitmueller To: linux-media@vger.kernel.org Cc: Devin Heitmueller Subject: [PATCH 17/24] au0828: fix possible race condition in usage of dev->ctrlmsg Date: Mon, 6 Aug 2012 22:47:07 -0400 Message-Id: <1344307634-11673-18-git-send-email-dheitmueller@kernellabs.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1344307634-11673-1-git-send-email-dheitmueller@kernellabs.com> References: <1344307634-11673-1-git-send-email-dheitmueller@kernellabs.com> X-Gm-Message-State: ALoCoQka5da4iudwKpyUu8hNEq2iH9Kgko5LLxQU64k8dgCRwCXeodx5z2L0VwoLSaxPPkVEWPil Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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. 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 --- 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); + 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;