From patchwork Thu Feb 22 00:17:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Edgecombe, Rick P" X-Patchwork-Id: 204502 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp1375618dyc; Wed, 21 Feb 2024 16:17:57 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCV+zoREsMXEuOdOhvh3o9Vqzmycouym4EXWMRk1ahi3g3ZNpwCO33VZg+qPivsTWOrC2mRqdl0UyvYHO1hsIxfIgXDk1g== X-Google-Smtp-Source: AGHT+IFME6Q20DDGeqz07jXqnZd4BLk+oFDJcVZWSWE+k7sB4DXxHqo328llb4f5G71cO3SS59pL X-Received: by 2002:a17:906:1c0c:b0:a3e:d847:5243 with SMTP id k12-20020a1709061c0c00b00a3ed8475243mr5367333ejg.57.1708561076921; Wed, 21 Feb 2024 16:17:56 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708561076; cv=pass; d=google.com; s=arc-20160816; b=M6mXyZB8QCV92H9REahK2S812XEDmQJ96jIqK14Y9mYH129axve37dxUnqmR/IEa9t 8AYd/e2cRXjt1RvTPVAzWub+IrLAp6TadGpWb9Z5hVHnYKN0jQH9dn4YLTBlM4bmQ7nc QU65A5AREDo8TSDYz2WSkm+RIVtCPPIT07V3w6j1KF0P3xc8YjeGbwfL4DGq3zvYCGly JFj5IPNfypl62Ci5pChW1dlF+ZPN2KRbqhITJy1SEcIdLAT8ynZP2bzrrPhS8N7QPIoq xdgTgsFtBWeGRgMFtjzmZz+pthjjWxsg6SxlEoJ6+TZCxw0PHu6Qxst/lBYV6EpkZ1ro MZeA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=nID4oGRBNh0r9jhIOa54v4IrqFBDJK/eAtIbgmd0jHQ=; fh=bwbIDGspIUfdoJpgB/v63QDuVyy3r7k89AyZdyo5JOI=; b=YH8RBLRY7SpYLItsC/1zL4iE2znSmmQ9bN7I6v3jIOntqniH7/vwHiYRePvq4J0AIi zO5YrrrJWafVb5q827Zg32NZ0T9uqnKxPSJxJL23zNcEvC3csQMEYfmDEhgPnlCooU8X AQxnoLO065gcQSEmwFAPDmbiQm4Th+OFPyamTZ8etx0cLZkFbmCKgiRi+7eJjFMxilH8 7e2/1wRsg6mtZviYgEp1yQs0DzpXyBEhe4pCQacpqF7l/Sfcc50IIRFmq0/CTYt/+kN/ MHdxD+SOVllq/CCVoZ3I+jQdga4Wa+IRDTivLu8uaa3Gg0ZJLRlyKnWUV4nFfu9fBUc5 tJww==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=J1q+ZAP2; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-75709-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-75709-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id qk34-20020a1709077fa200b00a3ecd47f937si2576352ejc.667.2024.02.21.16.17.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Feb 2024 16:17:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-75709-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=J1q+ZAP2; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-75709-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-75709-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 895121F22D74 for ; Thu, 22 Feb 2024 00:17:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CA625A95E; Thu, 22 Feb 2024 00:17:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="J1q+ZAP2" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) (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 A5E6C1FB2 for ; Thu, 22 Feb 2024 00:17:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708561062; cv=none; b=BNFX9fIIkhgCShn8LOuxElMvI5zOe3tYMYjHyqPknyuPx6o3D5jpMjV2BJpb1neOTmDlaORqzOligCd+C/XmOb65ySVtreB3I4iDmfjbkCwE7JOfv3GGakCT1L90zH6AHCQPTnW9qwsauISne6+x/SQKNZ/OUDTmn1UU0SDPyv0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708561062; c=relaxed/simple; bh=a09YNCy07mYtJGRS2Rh/roKV8v3u3IkAZ8WtyECXgcM=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type; b=nWEZ9OO0POd0gqWvCr90B9p0wdYWWxJyPd54r3vmCY4/kUAXz3SDr3PyAepAHDTLLjOWKazr7PNUUvF3RG28SsKcffHTKURIotiM14Dh80us9e3hYZq2aENJwLphIbudcp5inl7EGwp4OQgxiIOAz/XNonDMG3JxRzLe/nNBwiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=J1q+ZAP2; arc=none smtp.client-ip=192.198.163.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1708561060; x=1740097060; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=a09YNCy07mYtJGRS2Rh/roKV8v3u3IkAZ8WtyECXgcM=; b=J1q+ZAP2MSghm+32yeYgz7NR+0v/E7sAb+gEVdHPtib8VXHmtANZWd/B YqtMEVSYi6wDiY8f1VhSGAfFfgLVp+HBgLgb7gmqkdMKqC0KPckh0xFXv ttZv4APnUJEhh6x89L1smkr2auaAd1rxG5fo40ykEi7SSh4GolnRYnL0A zKq/vZoxqT+ZtIE1z+YB0qTr+VGNHj/+p8o14+97KOPO5VPumXuSCPXDL IzTPrbmpXmtznw2VLuTqomowXE3Pr2AkFBJAWyKH28nyERbwxNdFUsjca AkTYdVQta6DSmlHNLRRe0aVoypNrU97TqgcZr09eo7F68UL64YXMIkpSa A==; X-IronPort-AV: E=McAfee;i="6600,9927,10991"; a="6532588" X-IronPort-AV: E=Sophos;i="6.06,176,1705392000"; d="scan'208";a="6532588" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Feb 2024 16:17:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10991"; a="936729215" X-IronPort-AV: E=Sophos;i="6.06,176,1705392000"; d="scan'208";a="936729215" Received: from nlokaya-mobl1.amr.corp.intel.com (HELO rpedgeco-desk4.intel.com) ([10.209.62.65]) by fmsmga001-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Feb 2024 16:17:35 -0800 From: Rick Edgecombe To: hch@lst.de, m.szyprowski@samsung.com, robin.murphy@arm.com, linux-kernel@vger.kernel.org Cc: kirill.shutemov@linux.intel.com, elena.reshetova@intel.com, Rick Edgecombe , iommu@lists.linux.dev Subject: [PATCH] dma: Leak pages on dma_set_decrypted() failure Date: Wed, 21 Feb 2024 16:17:21 -0800 Message-Id: <20240222001721.2269203-1-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791556140053171779 X-GMAIL-MSGID: 1791556140053171779 On TDX it is possible for the untrusted host to cause set_memory_encrypted() or set_memory_decrypted() to fail such that an error is returned and the resulting memory is shared. Callers need to take care to handle these errors to avoid returning decrypted (shared) memory to the page allocator, which could lead to functional or security issues. DMA could free decrypted/shared pages if dma_set_decrypted() fails. This should be a rare case. Just leak the pages in this case instead of freeing them. Cc: Christoph Hellwig Cc: Marek Szyprowski Cc: Robin Murphy Cc: iommu@lists.linux.dev Signed-off-by: Rick Edgecombe --- Shared (decrypted) pages should never return to the page allocator, or future usage of the pages may allow for the contents to be exposed to the host. They may also cause the guest to crash if the page is used in way disallowed by HW (i.e. for executable code or as a page table). Normally set_memory() call failures are rare. But on TDX set_memory_XXcrypted() involves calls to the untrusted VMM, and an attacker could fail these calls such that: 1. set_memory_encrypted() returns an error and leaves the pages fully shared. 2. set_memory_decrypted() returns an error, but the pages are actually full converted to shared. This means that patterns like the below can cause problems: void *addr = alloc(); int fail = set_memory_decrypted(addr, 1); if (fail) free_pages(addr, 0); And: void *addr = alloc(); int fail = set_memory_decrypted(addr, 1); if (fail) { set_memory_encrypted(addr, 1); free_pages(addr, 0); } Unfortunately these patterns are all over the place. And what the set_memory() callers should do in this situation is not clear either. They shouldn’t use them as shared because something clearly went wrong, but they also need to fully reset the pages to private to free them. But, the kernel needs the VMMs help to do this and the VMM is already being uncooperative around the needed operations. So this isn't guaranteed to succeed and the caller is kind of stuck with unusable pages. The only choice is to panic or leak the pages. The kernel tries not to panic if at all possible, so just leak the pages at the call sites. Separately there is a patch[0] to warn if the guest detects strange VMM behavior around this. It is stalled, so in the mean time I’m proceeding with fixing the callers to leak the pages. No additional warnings are added, because the plan is to warn in a single place in x86 set_memory() code. [0] https://lore.kernel.org/lkml/20240122184003.129104-1-rick.p.edgecombe@intel.com/ --- --- kernel/dma/direct.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 98b2e192fd69..4d543b1e9d57 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -286,7 +286,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, } else { ret = page_address(page); if (dma_set_decrypted(dev, ret, size)) - goto out_free_pages; + goto out_leak_pages; } memset(ret, 0, size); @@ -307,6 +307,8 @@ void *dma_direct_alloc(struct device *dev, size_t size, out_free_pages: __dma_direct_free_pages(dev, page, size); return NULL; +out_leak_pages: + return NULL; } void dma_direct_free(struct device *dev, size_t size, @@ -367,12 +369,11 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, ret = page_address(page); if (dma_set_decrypted(dev, ret, size)) - goto out_free_pages; + goto out_leak_pages; memset(ret, 0, size); *dma_handle = phys_to_dma_direct(dev, page_to_phys(page)); return page; -out_free_pages: - __dma_direct_free_pages(dev, page, size); +out_leak_pages: return NULL; }