Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp3862167rdh; Tue, 28 Nov 2023 06:01:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IG0o16WUWIcIbVXCCkNJdU/YdrRKKzouqayRB8GlAXhXQG+Gk9FFKWO/uoZeRH2bEz3IbeK X-Received: by 2002:a92:d78c:0:b0:35a:fad3:2b2a with SMTP id d12-20020a92d78c000000b0035afad32b2amr17700893iln.12.1701180095460; Tue, 28 Nov 2023 06:01:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701180095; cv=none; d=google.com; s=arc-20160816; b=xY2NeCFJmRa8U+H724Zy/4LaHbQiwtpk1qRbh8ki3uHA7rE/jLlkcZ5YjhcP/QENf+ FFDzrqE9l6ACKcV/wHBPkFiPp3/XpjSvFeKTGn+cXeJ+uLqyCfsY1VfO15GEIRVCZMWr w2kAb2MGOVkgCASEOIbstKgJzcYUw/wTdNVBUidj0boqz2xNq9K6xkZma8UN0hDTvFdP R8WyHNXh5V/ZOsZ9ldshuMkre2G3+1LxZmHVLGVTNcqOKnFD6S49dtkVu8yxP1bKSp49 DhalRi3wP5uwXeIUOG0Jj6eT3wOnQHjQgSXfN68RkL24zce1nAht99rRjwj+J4cdkNDR P3pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gDeyDevgPSVHyhItuIxiJ5f232ZPZJroRvVWCk5dyvo=; fh=3F54v6jmjA4Ey2JVCnJkeTLJJd6nUM30m8dRjeh6Z1M=; b=WsM8MwD0hSL8MhHyxXom24373MuCJcgcLM+JTb9E67Bmlg7ez29Nk3bFz6SfKFPc19 edeZIqZr5cH+jdpDRnrtXjACekMQEy0uX3v1LKgou1b35ryhqk8prJzaEgsd9XntNVwN 9T9R+bSgbQwl9NfpRS8lHLc9cE/Y3u2mcyYp56TNsc8GQ3W/lHaAgKzA69cDbz6C5C13 GPDni2aivM60yRKCCEaqPwV5/AmPuH8YwJK6S8CwnrmC8hbPzVRcG3M7I5rgCXflVzhH 0THCtwzOPMa+Lh8dUgf5C2zaaLKD169Sw3qqjcviljm2zsFQKSldNulkoTjFWUxLKg/6 KBKQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=akNl+mrk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id y19-20020a6bc813000000b00792458056d0si550279iof.79.2023.11.28.06.01.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Nov 2023 06:01:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=akNl+mrk; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id 9EA3F80AC8EF; Tue, 28 Nov 2023 06:01:24 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345314AbjK1OAy (ORCPT + 99 others); Tue, 28 Nov 2023 09:00:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344807AbjK1OAu (ORCPT ); Tue, 28 Nov 2023 09:00:50 -0500 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 759E1CC; Tue, 28 Nov 2023 06:00:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701180056; x=1732716056; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bzQwSFKdK4wUAzVYUBTKHo5DJAY0+XMLzAA1r8JOvRk=; b=akNl+mrkzVGbOgi9G6bPuuFqoZ9AUadOhOuOJLZMYF7U0foCLZiosDqQ 5bhxNEMnmLNc+tNVYwvJjgY7lr+sxMnLHIi789goO5PKjGklWAvNsNywk kZAqmA0Tujj31A1N0EObTCbi9M0sHDpvFjczteuZQpjiq9jVUAgGldO+7 EnQg9aHfKFc/gEeRtkBWs1NWIDooM1Uzi+vPLgNz3BoGqt/kWv7X0ua3U zNi9hHDr0iCs+vkRjOGAWNrISTvqnTDQO0cgAb1h6w7riG011ZhBODHE/ PHAHlzBPHjA9fLC0Cy26vpYSsoRNjmFFBP7txQHSCJGZvNWd06AsdP1h9 A==; X-IronPort-AV: E=McAfee;i="6600,9927,10907"; a="383312979" X-IronPort-AV: E=Sophos;i="6.04,234,1695711600"; d="scan'208";a="383312979" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Nov 2023 06:00:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10907"; a="892080417" X-IronPort-AV: E=Sophos;i="6.04,234,1695711600"; d="scan'208";a="892080417" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by orsmga004.jf.intel.com with ESMTP; 28 Nov 2023 06:00:31 -0800 From: Mathias Nyman To: khtsai@google.com Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, stern@rowland.harvard.edu, Mathias Nyman Subject: [RFT PATCH 2/2] xhci: fix possible null pointer deref during xhci urb enqueue Date: Tue, 28 Nov 2023 16:01:41 +0200 Message-Id: <20231128140141.1161490-2-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231128140141.1161490-1-mathias.nyman@linux.intel.com> References: <51b8fc3d-25ef-1ab3-d744-8d851a133828@linux.intel.com> <20231128140141.1161490-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Tue, 28 Nov 2023 06:01:24 -0800 (PST) There is a short gap between urb being submitted and actually added to the endpoint queue (linked). If the device is disconnected during this time then usb core is not yet aware of the pending urb, and device may be freed just before xhci_urq_enqueue() continues, dereferening the freed device. Freeing the device is protected by the xhci spinlock, so make sure we take and keep the lock while checking that device exists, dereference it, and add the urb to the queue. Remove the unnecessary URB check, usb core checks it before calling xhci_urb_enqueue() Suggested-by: Kuen-Han Tsai Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index df31d44498d6..4929c4396e9e 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1521,24 +1521,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag struct urb_priv *urb_priv; int num_tds; - if (!urb) - return -EINVAL; - ret = xhci_check_args(hcd, urb->dev, urb->ep, - true, true, __func__); - if (ret <= 0) - return ret ? ret : -EINVAL; - - slot_id = urb->dev->slot_id; ep_index = xhci_get_endpoint_index(&urb->ep->desc); - ep_state = &xhci->devs[slot_id]->eps[ep_index].ep_state; - - if (!HCD_HW_ACCESSIBLE(hcd)) - return -ESHUTDOWN; - - if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) { - xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n"); - return -ENODEV; - } if (usb_endpoint_xfer_isoc(&urb->ep->desc)) num_tds = urb->number_of_packets; @@ -1562,12 +1545,35 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_check_args(hcd, urb->dev, urb->ep, + true, true, __func__); + if (ret <= 0) { + ret = ret ? ret : -EINVAL; + goto free_priv; + } + + slot_id = urb->dev->slot_id; + + if (!HCD_HW_ACCESSIBLE(hcd)) { + ret = -ESHUTDOWN; + goto free_priv; + } + + if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) { + xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n"); + ret = -ENODEV; + goto free_priv; + } + if (xhci->xhc_state & XHCI_STATE_DYING) { xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); ret = -ESHUTDOWN; goto free_priv; } + + ep_state = &xhci->devs[slot_id]->eps[ep_index].ep_state; + if (*ep_state & (EP_GETTING_STREAMS | EP_GETTING_NO_STREAMS)) { xhci_warn(xhci, "WARN: Can't enqueue URB, ep in streams transition state %x\n", *ep_state); -- 2.25.1