Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2970678imu; Sun, 9 Dec 2018 13:58:53 -0800 (PST) X-Google-Smtp-Source: AFSGD/WzJsAxJeBYjMBXnfO9BqCxzCEN1VEqfBW0kmSoaBNHpjnPS5ZZlWP0Ga+IHRFFYtod0xyZ X-Received: by 2002:a17:902:e085:: with SMTP id cb5mr9730281plb.24.1544392732958; Sun, 09 Dec 2018 13:58:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544392732; cv=none; d=google.com; s=arc-20160816; b=CpZdFP96GqTUNbcrHQffvHiPH8L3BGnwK9lqdFJ4oBAZeWwXkNPv5s16cBwyMaC2yu mXkRAkGCVanX8lfnyRfNwLCvxgJBSobOVMdN7m2dWhVmnFLzpph1GWFTWo8Pm9Pz4tmE XmcjP7jLLsg95LRdH3ElsPt9Qdwdkldt242f/7g7j7qhYJPs/7EKUJuVrAzdxgoLgIff tWE5wsc3Ecd1ZRmlZj/cLMqjLqrd9hvFpbCB9P5G+7tyQpiDRs5vjEfGMhm0auc77230 qum6LKMLTijnBbo4nZPbfidOjFMtfNiFHJ0/MZd8IvhopRXZkoK5leesnIoTDOa1okLm Ct2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=9pdyyVwo8p6BFoeBeoKr4w6pv+0HOr+PJemAY4YLNUo=; b=osxrEYRJ87YgLy22Uy8ttL/T9xefOT3BcH9/gtgfbc0v2ukK1Ul6oXx8C6yhxm0ght XuJsRGUlOaYz8wPj7gG987Q0iHL7cb5b9WghEnZmil70OnjtZef7kirCfZUhm9hKnfx7 tcrayZHoEG5I9feWW0CTJTiFk0cKSZ9uinb6KqOiTxNJOEHIk/iQkA9hPTSC4CzjaDVv WwdM3YrJnKskyYobJ8JVoLvAy6Pe807eqiHSD1KUbfWWq2RyCNxuh3BWsVqdZ/wcMRs1 OQ8SU7jNnWbKE7hz0EP7pqc88aSzRhtyRhQgtjdYdl+Bt7R3ztTCtrT97DYCtmceID+M hu5A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 69si8235127pgc.164.2018.12.09.13.58.37; Sun, 09 Dec 2018 13:58:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726804AbeLIVzl (ORCPT + 99 others); Sun, 9 Dec 2018 16:55:41 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:35394 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726545AbeLIVzY (ORCPT ); Sun, 9 Dec 2018 16:55:24 -0500 Received: from pub.yeoldevic.com ([81.174.156.145] helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1gW72n-0002pp-K7; Sun, 09 Dec 2018 21:55:21 +0000 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1gW72l-0003g3-0x; Sun, 09 Dec 2018 21:55:19 +0000 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Shuah Khan (Samsung OSG)" , syzbot+bccc1fe10b70fadc78d0@syzkaller.appspotmail.com, "Greg Kroah-Hartman" Date: Sun, 09 Dec 2018 21:50:33 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) X-Patchwork-Hint: ignore Subject: [PATCH 3.16 305/328] usb: usbip: Fix BUG: KASAN: slab-out-of-bounds in vhci_hub_control() In-Reply-To: X-SA-Exim-Connect-IP: 81.174.156.145 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.62-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: "Shuah Khan (Samsung OSG)" commit 81f7567c51ad97668d1c3a48e8ecc482e64d4161 upstream. vhci_hub_control() accesses port_status array with out of bounds port value. Fix it to reference port_status[] only with a valid rhport value when invalid_rhport flag is true. The invalid_rhport flag is set early on after detecting in port value is within the bounds or not. The following is used reproduce the problem and verify the fix: C reproducer: https://syzkaller.appspot.com/x/repro.c?x=14ed8ab6400000 Reported-by: syzbot+bccc1fe10b70fadc78d0@syzkaller.appspotmail.com Signed-off-by: Shuah Khan (Samsung OSG) Signed-off-by: Greg Kroah-Hartman [bwh: Backported to 3.16: - s/VHCI_HC_PORTS/VHCI_NPORTS/ - Mask wIndex before using it, as done upstream in commit 1c9de5bf4286 "usbip: vhci-hcd: Add USB3 SuperSpeed support" - Drop inapplicable changes - Adjust filename] Signed-off-by: Ben Hutchings --- --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -234,7 +234,8 @@ static int vhci_hub_control(struct usb_h { struct vhci_hcd *dum; int retval = 0; - int rhport; + int rhport = -1; + bool invalid_rhport = false; u32 prev_port_status[VHCI_NPORTS]; @@ -245,11 +246,23 @@ static int vhci_hub_control(struct usb_h * NOTE: * wIndex shows the port number and begins from 1. */ + wIndex = ((__u8)(wIndex & 0x00ff)); usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, wIndex); - if (wIndex > VHCI_NPORTS) - pr_err("invalid port number %d\n", wIndex); - rhport = ((__u8)(wIndex & 0x00ff)) - 1; + + /* + * wIndex can be 0 for some request types (typeReq). rhport is + * in valid range when wIndex >= 1 and < VHCI_HC_PORTS. + * + * Reference port_status[] only with valid rhport when + * invalid_rhport is false. + */ + if (wIndex < 1 || wIndex > VHCI_NPORTS) { + invalid_rhport = true; + if (wIndex > VHCI_NPORTS) + pr_err("invalid port number %d\n", wIndex); + } else + rhport = wIndex - 1; dum = hcd_to_vhci(hcd); @@ -257,8 +270,9 @@ static int vhci_hub_control(struct usb_h /* store old status and compare now and old later */ if (usbip_dbg_flag_vhci_rh) { - memcpy(prev_port_status, dum->port_status, - sizeof(prev_port_status)); + if (!invalid_rhport) + memcpy(prev_port_status, dum->port_status, + sizeof(prev_port_status)); } switch (typeReq) { @@ -266,8 +280,10 @@ static int vhci_hub_control(struct usb_h usbip_dbg_vhci_rh(" ClearHubFeature\n"); break; case ClearPortFeature: - if (rhport < 0) + if (invalid_rhport) { + pr_err("invalid port number %d\n", wIndex); goto error; + } switch (wValue) { case USB_PORT_FEAT_SUSPEND: if (dum->port_status[rhport] & USB_PORT_STAT_SUSPEND) { @@ -315,9 +331,10 @@ static int vhci_hub_control(struct usb_h break; case GetPortStatus: usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex); - if (wIndex > VHCI_NPORTS || wIndex < 1) { + if (invalid_rhport) { pr_err("invalid port number %d\n", wIndex); retval = -EPIPE; + goto error; } /* we do not care about resume. */ @@ -372,8 +389,10 @@ static int vhci_hub_control(struct usb_h case USB_PORT_FEAT_RESET: usbip_dbg_vhci_rh( " SetPortFeature: USB_PORT_FEAT_RESET\n"); - if (rhport < 0) + if (invalid_rhport) { + pr_err("invalid port number %d\n", wIndex); goto error; + } /* if it's already running, disconnect first */ if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) { dum->port_status[rhport] &= @@ -389,8 +408,10 @@ static int vhci_hub_control(struct usb_h default: usbip_dbg_vhci_rh(" SetPortFeature: default %d\n", wValue); - if (rhport < 0) + if (invalid_rhport) { + pr_err("invalid port number %d\n", wIndex); goto error; + } dum->port_status[rhport] |= (1 << wValue); break; } @@ -406,7 +427,7 @@ error: if (usbip_dbg_flag_vhci_rh) { pr_debug("port %d\n", rhport); /* Only dump valid port status */ - if (rhport >= 0) { + if (!invalid_rhport) { dump_port_status_diff(prev_port_status[rhport], dum->port_status[rhport]); }