From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D2BAC10DCE for ; Wed, 25 Mar 2020 00:29:40 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0EBC520719 for ; Wed, 25 Mar 2020 00:29:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="XFtFssHa" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0EBC520719 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=draconx.ca Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To :From:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=lkSaop4DiYzYiRQlnJXfr+zQrlTEtbeR1gRgdKsBze8=; b=XFtFssHaMwdrov HC8FqgcLTwR+g4gRAPygohKWOiVpw6zN1kaZNfBofvNXau/8bBwuQhBRpHaRg02gm+DphgGHCqNsD RM45kiHBj2DWfz1qPnwfX5j61ULUOGaftZWFj3vysBnb+gwbbtZfKSltZ6E0Tkj1Ks63OOpd3mQWR qKQnMyl704KS+0vM4m9veiXp7qdjXs6IRMRsS5vZ41aKxSyv1SQ0PeJIuIYQjsoY7zN56VTBzEP08 8yGntR4YKq57bCxeEmMehLoHlAthOk/fc06+fUK9P6fdWw2QOE2UwQgcPTsTjONdawQ+NHal14sia hlronfdt6uqfO1QFTztA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jGtvN-0002aR-TJ; Wed, 25 Mar 2020 00:29:37 +0000 Received: from mta01.start.ca ([162.250.196.97]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jGtvK-0002Zq-Nx for linux-nvme@lists.infradead.org; Wed, 25 Mar 2020 00:29:36 +0000 Received: from mta01.start.ca (localhost [127.0.0.1]) by mta01.start.ca (Postfix) with ESMTP id 7F76D4266E; Tue, 24 Mar 2020 20:29:21 -0400 (EDT) Received: from localhost (dhcp-24-53-240-163.cable.user.start.ca [24.53.240.163]) by mta01.start.ca (Postfix) with ESMTPS id 5527941F7F; Tue, 24 Mar 2020 20:29:18 -0400 (EDT) From: Nick Bowler To: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH] nvme: Fix NVME_IOCTL_ADMIN_CMD compat address handling. Date: Tue, 24 Mar 2020 20:28:48 -0400 Message-Id: <20200325002847.2140-1-nbowler@draconx.ca> X-Mailer: git-send-email 2.24.1 MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200324_172934_843740_0AD9B286 X-CRM114-Status: GOOD ( 12.38 ) X-BeenThere: linux-nvme@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-nvme" Errors-To: linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org On a real 32-bit kernel, the upper bits of userspace addresses passed to NVME_IOCTL_ADMIN_CMD via the nvme_passthru_cmd structure are silently ignored by the nvme driver. However on a 64-bit kernel running a compat task, these upper bits are not ignored and are in fact required to be zero for the ioctl to work. Unfortunately, this difference matters. 32-bit smartctl submits garbage in these upper bits because it seems the pointer value it puts into the nvme_passthru_cmd structure is sign extended. This works fine on a real 32-bit kernel but fails on a 64-bit one because (at least on my setup) the addresses smartctl uses are consistently above 2G. For example: # smartctl -x /dev/nvme0n1p1 smartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.5.11] (local build) Copyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Bad address Since changing 32-bit kernels to actually check all of the submitted address bits now would break existing userspace, this patch fixes the problem by explicitly zeroing the upper bits in the compat case. This enables 32-bit smartctl to work on a 64-bit kernel. Signed-off-by: Nick Bowler --- drivers/nvme/host/core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a4d8c90ee7cc..afb7b76d1d8a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -1412,6 +1413,16 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns, if (cmd.timeout_ms) timeout = msecs_to_jiffies(cmd.timeout_ms); + if (in_compat_syscall()) { + /* + * On real 32-bit kernels this implementation ignores the + * upper bits of address fields so we must replicate that + * behaviour in the compat case. + */ + cmd.addr = (compat_uptr_t)cmd.addr; + cmd.metadata = (compat_uptr_t)cmd.metadata; + } + effects = nvme_passthru_start(ctrl, ns, cmd.opcode); status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, (void __user *)(uintptr_t)cmd.addr, cmd.data_len, -- 2.24.1 _______________________________________________ linux-nvme mailing list linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme