From owner-svn-src-head@freebsd.org  Tue Jul 17 09:29:15 2018
Return-Path: <owner-svn-src-head@freebsd.org>
Delivered-To: svn-src-head@mailman.ysv.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1])
 by mailman.ysv.freebsd.org (Postfix) with ESMTP id 811B1103314F;
 Tue, 17 Jul 2018 09:29:15 +0000 (UTC)
 (envelope-from hselasky@FreeBSD.org)
Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org
 [IPv6:2610:1c1:1:606c::19:3])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client CN "mxrelay.nyi.freebsd.org",
 Issuer "Let's Encrypt Authority X3" (verified OK))
 by mx1.freebsd.org (Postfix) with ESMTPS id 319D87E1BE;
 Tue, 17 Jul 2018 09:29:15 +0000 (UTC)
 (envelope-from hselasky@FreeBSD.org)
Received: from repo.freebsd.org (repo.freebsd.org
 [IPv6:2610:1c1:1:6068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0F3F217D8;
 Tue, 17 Jul 2018 09:29:15 +0000 (UTC)
 (envelope-from hselasky@FreeBSD.org)
Received: from repo.freebsd.org ([127.0.1.37])
 by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6H9TEcq019185;
 Tue, 17 Jul 2018 09:29:14 GMT (envelope-from hselasky@FreeBSD.org)
Received: (from hselasky@localhost)
 by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6H9TEUa019180;
 Tue, 17 Jul 2018 09:29:14 GMT (envelope-from hselasky@FreeBSD.org)
Message-Id: <201807170929.w6H9TEUa019180@repo.freebsd.org>
X-Authentication-Warning: repo.freebsd.org: hselasky set sender to
 hselasky@FreeBSD.org using -f
From: Hans Petter Selasky <hselasky@FreeBSD.org>
Date: Tue, 17 Jul 2018 09:29:14 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
 svn-src-head@freebsd.org
Subject: svn commit: r336383 - in head/sys/ofed: drivers/infiniband/core
 include/rdma
X-SVN-Group: head
X-SVN-Commit-Author: hselasky
X-SVN-Commit-Paths: in head/sys/ofed: drivers/infiniband/core include/rdma
X-SVN-Commit-Revision: 336383
X-SVN-Commit-Repository: base
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-head@freebsd.org
X-Mailman-Version: 2.1.27
Precedence: list
List-Id: SVN commit messages for the src tree for head/-current
 <svn-src-head.freebsd.org>
List-Unsubscribe: <https://lists.freebsd.org/mailman/options/svn-src-head>,
 <mailto:svn-src-head-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-head/>
List-Post: <mailto:svn-src-head@freebsd.org>
List-Help: <mailto:svn-src-head-request@freebsd.org?subject=help>
List-Subscribe: <https://lists.freebsd.org/mailman/listinfo/svn-src-head>,
 <mailto:svn-src-head-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Tue, 17 Jul 2018 09:29:15 -0000

Author: hselasky
Date: Tue Jul 17 09:29:14 2018
New Revision: 336383
URL: https://svnweb.freebsd.org/changeset/base/336383

Log:
  Check port number supplied by user verbs cmds in ibcore.
  
  The ib_uverbs_create_ah() ind ib_uverbs_modify_qp() calls receive
  the port number from user input as part of its attributes and assumes
  it is valid. Down on the stack, that parameter is used to access kernel
  data structures.  If the value is invalid, the kernel accesses memory
  it should not.  To prevent this, verify the port number before using it.
  
  Linux commit:
  5ecce4c9b17bed4dc9cb58bfb10447307569b77b
  a62ab66b13a0f9bcb17b7b761f6670941ed5cd62
  5a7a88f1b488e4ee49eb3d5b82612d4d9ffdf2c3
  
  MFC after:		1 week
  Sponsored by:		Mellanox Technologies

Modified:
  head/sys/ofed/drivers/infiniband/core/ib_cma.c
  head/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c
  head/sys/ofed/include/rdma/ib_verbs.h

Modified: head/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_cma.c	Tue Jul 17 09:27:31 2018	(r336382)
+++ head/sys/ofed/drivers/infiniband/core/ib_cma.c	Tue Jul 17 09:29:14 2018	(r336383)
@@ -983,6 +983,8 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib
 		} else
 			ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
 						 qp_attr_mask);
+		qp_attr->port_num = id_priv->id.port_num;
+		*qp_attr_mask |= IB_QP_PORT;
 	} else
 		ret = -ENOSYS;
 

Modified: head/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c	Tue Jul 17 09:27:31 2018	(r336382)
+++ head/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c	Tue Jul 17 09:29:14 2018	(r336383)
@@ -2366,6 +2366,25 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *fil
 		goto out;
 	}
 
+	if ((cmd.attr_mask & IB_QP_PORT) &&
+	    !rdma_is_port_valid(qp->device, cmd.port_num)) {
+		ret = -EINVAL;
+		goto release_qp;
+	}
+
+	if ((cmd.attr_mask & IB_QP_AV) &&
+	    !rdma_is_port_valid(qp->device, cmd.dest.port_num)) {
+		ret = -EINVAL;
+		goto release_qp;
+	}
+
+	if ((cmd.attr_mask & IB_QP_ALT_PATH) &&
+	    (!rdma_is_port_valid(qp->device, cmd.alt_port_num) ||
+	    !rdma_is_port_valid(qp->device, cmd.alt_dest.port_num))) {
+		ret = -EINVAL;
+		goto release_qp;
+	}
+
 	attr->qp_state 		  = cmd.qp_state;
 	attr->cur_qp_state 	  = cmd.cur_qp_state;
 	attr->path_mtu 		  = cmd.path_mtu;
@@ -2895,6 +2914,9 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *fil
 
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
+
+	if (!rdma_is_port_valid(ib_dev, cmd.attr.port_num))
+		return -EINVAL;
 
 	INIT_UDATA(&udata, buf + sizeof(cmd),
 		   (unsigned long)cmd.response + sizeof(resp),

Modified: head/sys/ofed/include/rdma/ib_verbs.h
==============================================================================
--- head/sys/ofed/include/rdma/ib_verbs.h	Tue Jul 17 09:27:31 2018	(r336382)
+++ head/sys/ofed/include/rdma/ib_verbs.h	Tue Jul 17 09:29:14 2018	(r336383)
@@ -2260,6 +2260,13 @@ static inline u8 rdma_end_port(const struct ib_device 
 	return rdma_cap_ib_switch(device) ? 0 : device->phys_port_cnt;
 }
 
+static inline int rdma_is_port_valid(const struct ib_device *device,
+				     unsigned int port)
+{
+	return (port >= rdma_start_port(device) &&
+		port <= rdma_end_port(device));
+}
+
 static inline bool rdma_protocol_ib(const struct ib_device *device, u8 port_num)
 {
 	return device->port_immutable[port_num].core_cap_flags & RDMA_CORE_CAP_PROT_IB;