From patchwork Fri Dec 27 01:51:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Isaac J. Manjarres" X-Patchwork-Id: 13921504 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53FC3E7718E for ; Fri, 27 Dec 2024 01:52:20 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id D8D476B0088; Thu, 26 Dec 2024 20:52:19 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id D3C766B0089; Thu, 26 Dec 2024 20:52:19 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BDD4C6B008C; Thu, 26 Dec 2024 20:52:19 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 9F1A36B0088 for ; Thu, 26 Dec 2024 20:52:19 -0500 (EST) Received: from smtpin06.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 21AA11A022D for ; Fri, 27 Dec 2024 01:52:19 +0000 (UTC) X-FDA: 82939062318.06.FDCF551 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) by imf15.hostedemail.com (Postfix) with ESMTP id C69C4A0006 for ; Fri, 27 Dec 2024 01:51:04 +0000 (UTC) Authentication-Results: imf15.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=MiSTIfyl; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf15.hostedemail.com: domain of 3TwhuZw4KCFoAK224E2FB2JJ6K8GG8D6.4GEDAFMP-EECN24C.GJ8@flex--isaacmanjarres.bounces.google.com designates 209.85.214.202 as permitted sender) smtp.mailfrom=3TwhuZw4KCFoAK224E2FB2JJ6K8GG8D6.4GEDAFMP-EECN24C.GJ8@flex--isaacmanjarres.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1735264297; a=rsa-sha256; cv=none; b=gfDOzyhK/zWvNeV0OaKH+aUAKw89JQ32DjDv7XwVF9zFK5ZtJZzgqBAIr9F2K+nx4OIgDa fSECzLYxKjFuNXdYRXJthajUg+uV1pvWB3bxtSrD9o//UMiymDGX5sCzBe7K7z+M4eames CXXtcZoSMLIMR8WkN5h7w6upavhBWsI= ARC-Authentication-Results: i=1; imf15.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=MiSTIfyl; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf15.hostedemail.com: domain of 3TwhuZw4KCFoAK224E2FB2JJ6K8GG8D6.4GEDAFMP-EECN24C.GJ8@flex--isaacmanjarres.bounces.google.com designates 209.85.214.202 as permitted sender) smtp.mailfrom=3TwhuZw4KCFoAK224E2FB2JJ6K8GG8D6.4GEDAFMP-EECN24C.GJ8@flex--isaacmanjarres.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1735264297; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=v6yaTDfkaNJVYvN9IEtl+N1Z6cSe/++H2abnIIHWux0=; b=3VT0jYbTgsn0GBew5HPcJXhTfOFL+502ASgm261+dOBcx6VmYD3kYapUYJ/O3ppLVUc0g5 AHXBOigCMr2nlJLtzKSTYB/bI2JdF99UGW91Q6ouP62tRKASFDDQMSG7ULO3+3jEOako2H MlOgDeeZvwAsYbLSD16GGCaAa3eEZjc= Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2166f9f52fbso138998325ad.2 for ; Thu, 26 Dec 2024 17:52:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1735264336; x=1735869136; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=v6yaTDfkaNJVYvN9IEtl+N1Z6cSe/++H2abnIIHWux0=; b=MiSTIfyl6IgttReasNLCM3yOpPeIlu4jQeGo/1bbeyRDw/4gIYLF6JJ/LNA/mUwxeC VMLNFTW5iTmMEHh8I+gZQndK48WmezQ5krYtwerG04PYNc6xk86JGBKSpahziCMWjVGc SUDEyVomCUEEI8VKdUpYgce0aduKzBIkgNgSHcbgxy+EZ4oMA9I+zU32gD302WIO7jtN a+iyy/rQAyIIbjQfv4johjom7yw0Aaj6/1dMq8yWqkYg3nlGRSQvE3PIJAIqktjg/RwQ XzGW6JyCg3fHJEi/L5/u5Crvkg8y17Mc7aWtrG5r8redrrRl/D+BJ/koJX85JFQj0dAY FHeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735264336; x=1735869136; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=v6yaTDfkaNJVYvN9IEtl+N1Z6cSe/++H2abnIIHWux0=; b=Cib9nEY/1c6X7gDw9cTmmgveC47JSlI50ks8StmHATVpJIbkKX5HRIzwnjl8iaxuiP qfqAdzoK/h6LGF/5ZavrPSXDAudFJ03PZDirhE0jBxEkkLkaLnWmN++JjNJJE0QzLRZ2 8/hiOiJ668QUbtArtY6N/h49cANTHIyX94n4K3yjX5vMAsLLhuAmBaP4v1PeaUm004U2 E2oMrhKVu3ZSQqJ4XUOg218kD6Y9vtwC3J8bhVKRSpABTiTz3YiECGJ5NzFDNgatbZ94 izLtjBj/KWMEg5Vpd1SdKnb8Jolef8VZ2L1cThMky5ehGzjNAwb9hl129+je0UztOg+A a27Q== X-Forwarded-Encrypted: i=1; AJvYcCVqRfJqXWCtVPWasqv5EyEvxvRaYMVVPm2AH45MOD9ZJOO6xgTFglTUh6cRL8AMfWbd+sc8GydupQ==@kvack.org X-Gm-Message-State: AOJu0Yx5pb06UYOxZgbf9VclTFl/IMO42bnoOOG5JBbZEJK+g4tc6AJs zbGRA5xjY/FihKXW7d19n8PrnlWy+aXbg58z8heNGrXmVv+dPUAT5kPoeR6eVn1fZGmWwc+mjuz zZrmRhQlzKmNp+PG81Nn4Kqa5f7E6TqteQQ== X-Google-Smtp-Source: AGHT+IHse4XovH7OCFMIjVWOPD1SQgxTAQ/h5NRfnQWPd1gX69b7atGrDkgoCdZnGb8GfH754+jN0PTv1D/JC0qrH+J2xw== X-Received: from pgjg7.prod.google.com ([2002:a63:dd47:0:b0:801:9858:ef95]) (user=isaacmanjarres job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:f68f:b0:215:63a0:b58c with SMTP id d9443c01a7336-219e6f25f6bmr358562925ad.46.1735264335985; Thu, 26 Dec 2024 17:52:15 -0800 (PST) Date: Thu, 26 Dec 2024 17:51:59 -0800 In-Reply-To: <20241227015205.1375680-1-isaacmanjarres@google.com> Mime-Version: 1.0 References: <20241227015205.1375680-1-isaacmanjarres@google.com> X-Mailer: git-send-email 2.47.1.613.gc27f4b7a9f-goog Message-ID: <20241227015205.1375680-2-isaacmanjarres@google.com> Subject: [RFC PATCH v2 1/2] mm/memfd: Add support for F_SEAL_FUTURE_EXEC to memfd From: "Isaac J. Manjarres" To: Jeff Layton , Chuck Lever , Alexander Aring , Andrew Morton , Shuah Khan Cc: surenb@google.com, kaleshsingh@google.com, jstultz@google.com, aliceryhl@google.com, jeffxu@google.com, kees@kernel.org, "Isaac J. Manjarres" , kernel-team@android.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: C69C4A0006 X-Stat-Signature: h6y1s3qx485yh5b41sd5e41atk7debra X-Rspam-User: X-HE-Tag: 1735264264-673769 X-HE-Meta: U2FsdGVkX1+kluLASvYk9AtAd8GtsAzyJaRndFJPX4ObfmUnA9fJO+zSd5lGOffJJB52k8Sm8Cg4A/lygxXPVSD6nij6xx87G9jBRj0ypkSBnpbtmdPVFj9Xk8iGRuvvCl1OLpjmQwEn0tKConUA5H2ylkARYPOIhKwZExPlsFUFzYUCZjdhhymOMNTErNZuVB9pg0AruqW4IMWafSe8LMsSdiRtzBpeaHKrs63RTHTouPEb/uRnKnh6qA6mkn5wDpCfmRymPw5LmkbCH4zifFCTzteEtEId7y2uVMasnqtPcJdRbS7YFf936GAv8x5XUzAmnjrBRr8YY9Aq1OHQAd+Sn7UbO6560mHs71h8ZkCRDyiDf1RxR3KFq1qOsddJJKFxvW8FXBRWVZk0sOt7nh+T9WxNWEUFq2eecQF1GtmTuoFRfeN0DKbYMZ6OE4zBEtL5Y9WWg+Rd6iQKBtUUHXnHBexQYfkNbpfj6D5WbEs+j7em5A+TE9fjh3hw8KKoUwUPr4Yn+uPj0SGlIrfnKsruQcYyVWzpwHEabRJwvT/a/YGKvrN/J0ojgm1B3lvrd8llp1PiQtmtTExXtIDTSCTe9imt7GCCZS7htyF10rp+3z0nGeHwGEAMJQoiMqd4+FgumjLJkx+GbsVVBBacytmMtnU9J2nwvMGxuXuGduwq5GEvnOhmtatan1Q59IPCA57afQ/Yl15OAszgwP6XCsWdHJ7taTfY/3YPGTpLWV+LEybJ5fA7voQZ7P9d5wtbNo6ZWDPLTMv72P7KZ4Kxla1JO1lGn2pccMZ1MkKQXAb2WHgfpSCnuapexUCB8VPRx9NEuHUvyVoMPbkt2JgeNpzAqkmc0auVzX0qv1BMvjBRpiD6vax0rd88n/TeOCL+WPA/VICKw1gaYsAguCXfpBEtVi+bAt5pGSDSpMaGi5hI3ic2YWKVKBAJ5JLPvwN5HkNiKCp9cEAz0LOymx2 TJhBVkoW fT7iotBGLpFb59wZUL0GxANO/4foqRBaWLIHDRVd+QiXmPltNTsrj7AQ3SjohvVnj490JT/RXTa2sW1fQ7YiKHPV/UQRO95oZ2XL+4UTh6FBz5e3bzlxLqbXDtUCI+kbM2P1CD6fZ6ADq6X7qYatOQOKwjDni97F9PDTzQ96AogmOUZ+B9kRTZNjLBtsKSJh9x4PDDB/+m5p4MO9LN+n4kkNzkzvSo20OzzrYIb74VRIVdXBG8slGZL5m5MJ9tQ+vXj0qv4P8s3x838ul2jgRAvjHmb4QPF/nz7oN0vdCWR4bq8jbUgWFZfPNSTubXumNu7L/qVtvtxOPu0N6vothO4fPcbB0Zrykf4LNM+Eeq7KpBf3vMSbE5/EUFSwKS7JzdlfcMRuenYBlh4p9E/L8wp2ZvRJUydwLkBakni8A2Zto9pyZWhUAD2v4rgAyI9JrI53BIKNb6vaR+4xS+nZoGwImRvCv36dgNQ8L17W8hatCK0FGNeC8MK2Uc4uCfKTh7rtl1qXO12+54TXrQf0OIA5rbvN4+b4fToQdRlJHyOnffvwkwBRljSaMeXkk3IfE5xOkch6XMEDubOvUP9zTgkMzfTtPn4IA/TRGNybNsatq2WaQMRjcIl87Za7207maqm922hJqpjvwUPX2hFMDSBIZBanNG6VyPmwyoXq2OmFYDSPnNK7VHeQoSYdAYI/X74XFHDoHSOA7WliRdAL38+NnulcTNtkytwGF6iDH01zQFaDbK/5yPLAy8g== X-Bogosity: Ham, tests=bogofilter, spamicity=0.012420, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Android currently uses the ashmem driver [1] for creating shared memory regions between processes. Ashmem buffers can initially be mapped with PROT_READ, PROT_WRITE, and PROT_EXEC. Processes can then use the ASHMEM_SET_PROT_MASK ioctl command to restrict--never add--the permissions that the buffer can be mapped with. Processes can remove the ability to map ashmem buffers as executable to ensure that those buffers cannot be exploited to run unintended code. For instance, suppose process A allocates a memfd that is meant to be read and written by itself and another process, call it B. Process A shares the buffer with process B, but process B injects code into the buffer, and compromises process A, such that it makes A map the buffer with PROT_EXEC. This provides an opportunity for process A to run the code that process B injected into the buffer. If process A had the ability to seal the buffer against future executable mappings before sharing the buffer with process B, this attack would not be possible. Android is currently trying to replace ashmem with memfd. However, memfd does not have a provision to permanently remove the ability to map a buffer as executable, and leaves itself open to the type of attack described earlier. However, this should be something that can be achieved via a new file seal. There are known usecases (e.g. CursorWindow [2]) where a process maps a buffer with read/write permissions before restricting the buffer to being mapped as read-only for future mappings. The resulting VMA from the writable mapping has VM_MAYEXEC set, meaning that mprotect() can change the mapping to be executable. Therefore, implementing the seal similar to F_SEAL_WRITE would not be appropriate, since it would not work with the CursorWindow usecase. This is because the CursorWindow process restricts the mapping permissions to read-only after the writable mapping is created. So, adding a file seal for executable mappings that operates like F_SEAL_WRITE would fail. Therefore, add support for F_SEAL_FUTURE_EXEC, which is handled similarly to F_SEAL_FUTURE_WRITE. This ensures that CursorWindow can continue to create a writable mapping initially, and then restrict the permissions on the buffer to be mappable as read-only by using both F_SEAL_FUTURE_WRITE and F_SEAL_FUTURE_EXEC. After the seal is applied, any calls to mmap() with PROT_EXEC will fail. [1] https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/drivers/staging/android/ashmem.c [2] https://developer.android.com/reference/android/database/CursorWindow Signed-off-by: Isaac J. Manjarres --- include/uapi/linux/fcntl.h | 1 + mm/memfd.c | 39 +++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 6e6907e63bfc..ef066e524777 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -49,6 +49,7 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ #define F_SEAL_FUTURE_WRITE 0x0010 /* prevent future writes while mapped */ #define F_SEAL_EXEC 0x0020 /* prevent chmod modifying exec bits */ +#define F_SEAL_FUTURE_EXEC 0x0040 /* prevent future executable mappings */ /* (1U << 31) is reserved for signed error codes */ /* diff --git a/mm/memfd.c b/mm/memfd.c index 5f5a23c9051d..cfd62454df5e 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -184,6 +184,7 @@ static unsigned int *memfd_file_seals_ptr(struct file *file) } #define F_ALL_SEALS (F_SEAL_SEAL | \ + F_SEAL_FUTURE_EXEC |\ F_SEAL_EXEC | \ F_SEAL_SHRINK | \ F_SEAL_GROW | \ @@ -357,14 +358,50 @@ static int check_write_seal(unsigned long *vm_flags_ptr) return 0; } +static inline bool is_exec_sealed(unsigned int seals) +{ + return seals & F_SEAL_FUTURE_EXEC; +} + +static int check_exec_seal(unsigned long *vm_flags_ptr) +{ + unsigned long vm_flags = *vm_flags_ptr; + unsigned long mask = vm_flags & (VM_SHARED | VM_EXEC); + + /* Executability is not a concern for private mappings. */ + if (!(mask & VM_SHARED)) + return 0; + + /* + * New PROT_EXEC and MAP_SHARED mmaps are not allowed when exec seal + * is active. + */ + if (mask & VM_EXEC) + return -EPERM; + + /* + * Prevent mprotect() from making an exec-sealed mapping executable in + * the future. + */ + *vm_flags_ptr &= ~VM_MAYEXEC; + + return 0; +} + int memfd_check_seals_mmap(struct file *file, unsigned long *vm_flags_ptr) { int err = 0; unsigned int *seals_ptr = memfd_file_seals_ptr(file); unsigned int seals = seals_ptr ? *seals_ptr : 0; - if (is_write_sealed(seals)) + if (is_write_sealed(seals)) { err = check_write_seal(vm_flags_ptr); + if (err) + return err; + } + + if (is_exec_sealed(seals)) + err = check_exec_seal(vm_flags_ptr); return err; }