Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2515340imm; Mon, 24 Sep 2018 05:46:27 -0700 (PDT) X-Google-Smtp-Source: ACcGV60ecTYwpbjj6l6Qr2nf/f0qO6GGlNKJaErVOHp6X/1hwZJpNks4zDHZbhwfdf2EzN3s3t// X-Received: by 2002:a63:a441:: with SMTP id c1-v6mr9478268pgp.182.1537793187254; Mon, 24 Sep 2018 05:46:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537793187; cv=none; d=google.com; s=arc-20160816; b=EJOOTdvMxbhK+ZNiVzk+IA23dgQrNYEZxCq/SrY5RbyuiTdadMy1enUe5ZwP1XV90s p+WiQdpu/uS62VHiMHDNgGpTBN9CRPwR/EcxDeA9o1FRM/AiJVjSsw5Txiwh5c5OThHI g+XK1KZWOe4htDiLtu33wwxlgZRuXvdjAPGxLYjZC6WmDnEkIEotoO84VUr+2JjKaXba SKHAFzsJN8wwOmu9b0cNygznxdeP1cvgkt3dB4Sc0ttO4TXH9f6/tDO8SyRTGgSMnjzS ovkO4qIWv75Xv+39gxJpaN6BxkoDDUX/SA3VlEgkFbgiy4I63mpi/VF7/zopxb86nhry ge2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=ysf4dpO0kotnELF1Aq7xQo/v1gYcHljNyDlyEtvb8F0=; b=iO0OXlaSf7n2rZe+KYCpFlJolD6XUJW8ZbYdLfqjM7+eZWvxLxO3I29aLi1PFqrpri aGY305cQT6jeERFnIlDe+r1nJtNjqIWqOUHScIde+2A6GfqtGuKB//xawLaJJjtZu7IB mrJp+dGmPdNM37qWWMbk4N6xvF7O7g0Odq8GxMxaaQsk9iu/YFqXwPaXNOVwtAyFBC1D qiYAHkZX1bFk3wQ9eSoj2CLrnU+NQGgPVqNKvts1DeSLRJhQqEbW23GaMYoFeSx1OpQp GmNq59zQj9JXZQXlYN5EDGfhzslcFEO6wPESiGiruZ4nSDsBy40hJiUh+KZv88ySchZG krvQ== 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 w5-v6si2406178pgi.254.2018.09.24.05.46.12; Mon, 24 Sep 2018 05:46:27 -0700 (PDT) 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 S2389295AbeIXSrI (ORCPT + 99 others); Mon, 24 Sep 2018 14:47:08 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:59722 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388526AbeIXSrH (ORCPT ); Mon, 24 Sep 2018 14:47:07 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id A5B17109E; Mon, 24 Sep 2018 12:45:07 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jann Horn , Leon Romanovsky , Jason Gunthorpe , Sasha Levin Subject: [PATCH 4.18 227/235] IB/mlx5: fix uaccess beyond "count" in debugfs read/write handlers Date: Mon, 24 Sep 2018 13:53:33 +0200 Message-Id: <20180924113125.736824923@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180924113103.999624566@linuxfoundation.org> References: <20180924113103.999624566@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jann Horn [ Upstream commit 60e6627f12a78203a093ca05b7bca15627747d81 ] In general, accessing userspace memory beyond the length of the supplied buffer in VFS read/write handlers can lead to both kernel memory corruption (via kernel_read()/kernel_write(), which can e.g. be triggered via sys_splice()) and privilege escalation inside userspace. In this case, the affected files are in debugfs (and should therefore only be accessible to root), and the read handlers check that *pos is zero (meaning that at least sys_splice() can't trigger kernel memory corruption). Because of the root requirement, this is not a security fix, but rather a cleanup. For the read handlers, fix it by using simple_read_from_buffer() instead of custom logic. Add min() calls to the write handlers. Fixes: 4a2da0b8c078 ("IB/mlx5: Add debug control parameters for congestion control") Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Signed-off-by: Jann Horn Reviewed-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx5/cong.c | 9 +-------- drivers/infiniband/hw/mlx5/mr.c | 32 ++++++++------------------------ 2 files changed, 9 insertions(+), 32 deletions(-) --- a/drivers/infiniband/hw/mlx5/cong.c +++ b/drivers/infiniband/hw/mlx5/cong.c @@ -359,9 +359,6 @@ static ssize_t get_param(struct file *fi int ret; char lbuf[11]; - if (*pos) - return 0; - ret = mlx5_ib_get_cc_params(param->dev, param->port_num, offset, &var); if (ret) return ret; @@ -370,11 +367,7 @@ static ssize_t get_param(struct file *fi if (ret < 0) return ret; - if (copy_to_user(buf, lbuf, ret)) - return -EFAULT; - - *pos += ret; - return ret; + return simple_read_from_buffer(buf, count, pos, lbuf, ret); } static const struct file_operations dbg_cc_fops = { --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -271,16 +271,16 @@ static ssize_t size_write(struct file *f { struct mlx5_cache_ent *ent = filp->private_data; struct mlx5_ib_dev *dev = ent->dev; - char lbuf[20]; + char lbuf[20] = {0}; u32 var; int err; int c; - if (copy_from_user(lbuf, buf, sizeof(lbuf))) + count = min(count, sizeof(lbuf) - 1); + if (copy_from_user(lbuf, buf, count)) return -EFAULT; c = order2idx(dev, ent->order); - lbuf[sizeof(lbuf) - 1] = 0; if (sscanf(lbuf, "%u", &var) != 1) return -EINVAL; @@ -310,19 +310,11 @@ static ssize_t size_read(struct file *fi char lbuf[20]; int err; - if (*pos) - return 0; - err = snprintf(lbuf, sizeof(lbuf), "%d\n", ent->size); if (err < 0) return err; - if (copy_to_user(buf, lbuf, err)) - return -EFAULT; - - *pos += err; - - return err; + return simple_read_from_buffer(buf, count, pos, lbuf, err); } static const struct file_operations size_fops = { @@ -337,16 +329,16 @@ static ssize_t limit_write(struct file * { struct mlx5_cache_ent *ent = filp->private_data; struct mlx5_ib_dev *dev = ent->dev; - char lbuf[20]; + char lbuf[20] = {0}; u32 var; int err; int c; - if (copy_from_user(lbuf, buf, sizeof(lbuf))) + count = min(count, sizeof(lbuf) - 1); + if (copy_from_user(lbuf, buf, count)) return -EFAULT; c = order2idx(dev, ent->order); - lbuf[sizeof(lbuf) - 1] = 0; if (sscanf(lbuf, "%u", &var) != 1) return -EINVAL; @@ -372,19 +364,11 @@ static ssize_t limit_read(struct file *f char lbuf[20]; int err; - if (*pos) - return 0; - err = snprintf(lbuf, sizeof(lbuf), "%d\n", ent->limit); if (err < 0) return err; - if (copy_to_user(buf, lbuf, err)) - return -EFAULT; - - *pos += err; - - return err; + return simple_read_from_buffer(buf, count, pos, lbuf, err); } static const struct file_operations limit_fops = {