From nobody Wed Apr 1 14:14:56 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C591B28002B; Tue, 31 Mar 2026 05:57:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774936621; cv=none; b=MBcdqDyJXbdbfZgWTy2c+FbBSSCBBMkphi9hFKooGpkMCM1dqRq+85QBc4uAqFZAlq167joTr6UT0oY4xzGVjl1UlYDLYdDNgPKJKmNyxVGq9NsMKegGka4rVXilXvZJ/05NR09YwjjTrohEvlsGdjWk2eQd7jlwBljBIGgjHLw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774936621; c=relaxed/simple; bh=2sUVXWm6gNzbVe8kaPMIgxN7RRU36ux1iye5UqtO5zY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iCeiQ23xA60bBzs7eblNRcSjI7ZhTakfXCBOHhIk2wJZUn6KFaW7Hynlk6m4fEOVHDMIxwUOhxKIt5T5gIj4u5gnyoJpxU0n8FyQHGpJbROAjAqSLSVVS6kxQNCmPlYQT0zBXXx9tBtWQAfK+3TnTDyUWYHwm5UfHZ7X0yW4Bf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=b8H84but; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="b8H84but" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D21EFC2BCB2; Tue, 31 Mar 2026 05:57:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774936621; bh=2sUVXWm6gNzbVe8kaPMIgxN7RRU36ux1iye5UqtO5zY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b8H84butCoPCRLEFvp8G0bCPS9e/YZqXvfcgpLlYxU8v0Q2hb9g2cQrGUEBxjOoQK v6kqvevV2I22huT1MSDikjrDpi5lN2aUjU6u8nXblALEoExcZ6ZHZQzm/hhkJP0v8a SHIncaR3H+a0IZAhk5WMueCzUUAbmG7xxZWDhoUQM0tUMF1/O6B1voDl5ozOnX0yJW xWj4mIK/thjVdMF2aOVCQBZ2DrXI+hDa/CKniLrY9v6PDuasX8RlU6vwC1XjOiCSc/ /YkcC7XHb+oMDBNtxMkpyh6MuutaDDJn7rcsh2BKn8cX6N5A1pWheExXoiLMujfqBX Y27YV0xzQmHWg== From: Leon Romanovsky To: KP Singh , Matt Bobrowski , Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Leon Romanovsky , Jason Gunthorpe , Saeed Mahameed , Itay Avraham , Dave Jiang , Jonathan Cameron Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-rdma@vger.kernel.org, Chiara Meiohas , Maher Sanalla , Jonathan Cameron Subject: [PATCH v2 3/4] RDMA/mlx5: Externally validate FW commands supplied in DEVX interface Date: Tue, 31 Mar 2026 08:56:35 +0300 Message-ID: <20260331-fw-lsm-hook-v2-3-78504703df1f@nvidia.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260331-fw-lsm-hook-v2-0-78504703df1f@nvidia.com> References: <20260331-fw-lsm-hook-v2-0-78504703df1f@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.15-dev-18f8f Content-Transfer-Encoding: quoted-printable From: Chiara Meiohas DEVX is an RDMA uverbs extension that allows userspace to submit firmware command buffers. The driver inspects the command and then passes the buffer through for firmware execution. Call bpf_lsm_fw_validate_cmd() before dispatching firmware commands through DEVX. This allows BPF programs to implement custom policies and enforce per-command security policy on user-triggered firmware commands. For example, a BPF program could restrict specific firmware operations to privileged users. Signed-off-by: Chiara Meiohas Reviewed-by: Maher Sanalla Reviewed-by: Jonathan Cameron Reviewed-by: Dave Jiang Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mlx5/devx.c | 49 +++++++++++++++++++++++++++++------= ---- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5= /devx.c index 0066b2738ac89..b7a2e19987018 100644 --- a/drivers/infiniband/hw/mlx5/devx.c +++ b/drivers/infiniband/hw/mlx5/devx.c @@ -18,6 +18,7 @@ #include "devx.h" #include "qp.h" #include +#include =20 #define UVERBS_MODULE_NAME mlx5_ib #include @@ -1111,6 +1112,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)( struct mlx5_ib_dev *dev; void *cmd_in =3D uverbs_attr_get_alloced_ptr( attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN); + int cmd_in_len =3D uverbs_attr_get_len(attrs, + MLX5_IB_ATTR_DEVX_OTHER_CMD_IN); int cmd_out_len =3D uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT); void *cmd_out; @@ -1135,9 +1138,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OTHER)( return PTR_ERR(cmd_out); =20 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); - err =3D mlx5_cmd_do(dev->mdev, cmd_in, - uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OTHER_CMD_IN), - cmd_out, cmd_out_len); + err =3D bpf_lsm_fw_validate_cmd(cmd_in, cmd_in_len, &dev->ib_dev.dev, + FW_CMD_CLASS_UVERBS, RDMA_DRIVER_MLX5); + if (err) + return err; + + err =3D mlx5_cmd_do(dev->mdev, cmd_in, cmd_in_len, cmd_out, cmd_out_len); if (err && err !=3D -EREMOTEIO) return err; =20 @@ -1570,6 +1576,11 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CR= EATE)( devx_set_umem_valid(cmd_in); } =20 + err =3D bpf_lsm_fw_validate_cmd(cmd_in, cmd_in_len, &dev->ib_dev.dev, + FW_CMD_CLASS_UVERBS, RDMA_DRIVER_MLX5); + if (err) + goto obj_free; + if (opcode =3D=3D MLX5_CMD_OP_CREATE_DCT) { obj->flags |=3D DEVX_OBJ_FLAGS_DCT; err =3D mlx5_core_create_dct(dev, &obj->core_dct, cmd_in, @@ -1646,6 +1657,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_MOD= IFY)( struct uverbs_attr_bundle *attrs) { void *cmd_in =3D uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ= _MODIFY_CMD_IN); + int cmd_in_len =3D uverbs_attr_get_len(attrs, + MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN); int cmd_out_len =3D uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT); struct ib_uobject *uobj =3D uverbs_attr_get_uobject(attrs, @@ -1676,10 +1689,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_M= ODIFY)( =20 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); devx_set_umem_valid(cmd_in); + err =3D bpf_lsm_fw_validate_cmd(cmd_in, cmd_in_len, &mdev->ib_dev.dev, + FW_CMD_CLASS_UVERBS, RDMA_DRIVER_MLX5); + if (err) + return err; =20 - err =3D mlx5_cmd_do(mdev->mdev, cmd_in, - uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN), - cmd_out, cmd_out_len); + err =3D mlx5_cmd_do(mdev->mdev, cmd_in, cmd_in_len, cmd_out, cmd_out_len); if (err && err !=3D -EREMOTEIO) return err; =20 @@ -1693,6 +1708,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QUE= RY)( struct uverbs_attr_bundle *attrs) { void *cmd_in =3D uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ= _QUERY_CMD_IN); + int cmd_in_len =3D uverbs_attr_get_len(attrs, + MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN); int cmd_out_len =3D uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT); struct ib_uobject *uobj =3D uverbs_attr_get_uobject(attrs, @@ -1722,9 +1739,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_QU= ERY)( return PTR_ERR(cmd_out); =20 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); - err =3D mlx5_cmd_do(mdev->mdev, cmd_in, - uverbs_attr_get_len(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN), - cmd_out, cmd_out_len); + err =3D bpf_lsm_fw_validate_cmd(cmd_in, cmd_in_len, &mdev->ib_dev.dev, + FW_CMD_CLASS_UVERBS, RDMA_DRIVER_MLX5); + if (err) + return err; + + err =3D mlx5_cmd_do(mdev->mdev, cmd_in, cmd_in_len, cmd_out, cmd_out_len); if (err && err !=3D -EREMOTEIO) return err; =20 @@ -1832,6 +1852,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_ASY= NC_QUERY)( { void *cmd_in =3D uverbs_attr_get_alloced_ptr(attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN); + int cmd_in_len =3D uverbs_attr_get_len(attrs, + MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN); struct ib_uobject *uobj =3D uverbs_attr_get_uobject( attrs, MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_HANDLE); @@ -1894,9 +1916,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_AS= YNC_QUERY)( async_data->ev_file =3D ev_file; =20 MLX5_SET(general_obj_in_cmd_hdr, cmd_in, uid, uid); - err =3D mlx5_cmd_exec_cb(&ev_file->async_ctx, cmd_in, - uverbs_attr_get_len(attrs, - MLX5_IB_ATTR_DEVX_OBJ_QUERY_ASYNC_CMD_IN), + err =3D bpf_lsm_fw_validate_cmd(cmd_in, cmd_in_len, &mdev->ib_dev.dev, + FW_CMD_CLASS_UVERBS, RDMA_DRIVER_MLX5); + if (err) + goto free_async; + + err =3D mlx5_cmd_exec_cb(&ev_file->async_ctx, cmd_in, cmd_in_len, async_data->hdr.out_data, async_data->cmd_out_len, devx_query_callback, &async_data->cb_work); --=20 2.53.0