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 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 795B4E77188 for ; Fri, 3 Jan 2025 15:04:26 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0AAA16B007B; Fri, 3 Jan 2025 10:04:26 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 031CD6B0082; Fri, 3 Jan 2025 10:04:25 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DEDE46B0083; Fri, 3 Jan 2025 10:04:25 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id C05E76B007B for ; Fri, 3 Jan 2025 10:04:25 -0500 (EST) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 75D4EC08C7 for ; Fri, 3 Jan 2025 15:04:25 +0000 (UTC) X-FDA: 82966459968.21.3AB0289 Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) by imf25.hostedemail.com (Postfix) with ESMTP id 582B8A001A for ; Fri, 3 Jan 2025 15:03:46 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=rIko8wIO; spf=pass (imf25.hostedemail.com: domain of jannh@google.com designates 209.85.208.53 as permitted sender) smtp.mailfrom=jannh@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1735916624; 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:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Id4oxg5aLGXSceJ4jMag81lcUDVzfnKFnYjbXZWeSzw=; b=VFkXBVr3FXPz19+cl/z+TY5cKy27hdTURLnTBf7/Fec5RfTQI4Cg1sNw4GYNRymkm2/beE IvhdpRTKrRa1/w0N2S3HlhDY8PEtjGvxLJnUEEOc++ZUXfocbkYNniBjPPbAAcfFL3c1yX oSgZLPNQST4NrOcSCuzP50DJJPIptkQ= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=rIko8wIO; spf=pass (imf25.hostedemail.com: domain of jannh@google.com designates 209.85.208.53 as permitted sender) smtp.mailfrom=jannh@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1735916624; a=rsa-sha256; cv=none; b=aLDoz6mfgBijvXY8ObbLvMbd7zxcHlZY1ceC162kA+hKs8asMqpv8SP2qGParRtsb3TDZb LeDv5wISiO8h9w0TuiuXySYLSWUZVbhhn85wwyd+nDJ/amN4ZF7lW3EkRPnSGOCLbFWZRi RncFtyvD2eZl49n7Z0Zt775GiHJqGzo= Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-5d442f9d285so6521a12.1 for ; Fri, 03 Jan 2025 07:04:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1735916662; x=1736521462; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=Id4oxg5aLGXSceJ4jMag81lcUDVzfnKFnYjbXZWeSzw=; b=rIko8wIOVnHNLCScnZVwewU9UMHM+/xmrxsKDO3xcLTYg/RxMRpQRKi33frvKvG4RA KI5TAFkRr84KNCOr7pK8DjHWyz9IrHGoG2MwUHK8S/aeyEq+FDQ1s81N9vqI5bxCWbM6 A8ZEDscxpa8yQx7RzZt3MSkpyZsDBO9NU+0qdUqUZ7aEbqvS2Exgy5KXAF0Z/Evi+ncy wr3N81Ux19EahmW36nlgwR5smzuwoGy4MzSzX3Zw0GcUDydarZtAhH3X/Qk48xTlWppp 6uW44icFAN4Mri9mhzrYtUrt0jsCCpcUS/MEJwIhP3DGAJ6zKNV7c2PLeL7suWKQkrIH W7BA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735916662; x=1736521462; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Id4oxg5aLGXSceJ4jMag81lcUDVzfnKFnYjbXZWeSzw=; b=O0SwxrTaYwNgsUN4bJsOxfq/ofc7FUvrpKHktOASl9jiAyXkqLwzswC7MHlZQ97aII jWNWrt1SzTQmPnNreskLwgKilsIC6FRR6WC8jU1g0i3DmPuq2cQdxp090xOQfkwU07by pG66m9AcGtRTZcZYdAFXRgWOtsfuH8LOWhXXa1ElifxChvWlouDOKK8kW7Puhti2CKTB X8jp6RlNMD2Hisc3oNn7gjwyFzkBa5xb2PjmyH14KSc2d+mrocw1Y9jlmPxL5YcFt/Tk cGcRdX6y5W7BEi4OwwQf1wo8y1ouVBTHh9NzIgl/6NgpiSgRiWLRpAFUoHeO0ShI7RbJ 4sZg== X-Forwarded-Encrypted: i=1; AJvYcCXZEzxA+/ARTDcDKB/rPg0YLj0Nckcp/YeK1bRdZLgc8p6YLWKbQsm8A4GtLpSAeapHPeWgzC65QQ==@kvack.org X-Gm-Message-State: AOJu0YzXaIRUy0UnsrBwAaUlNbROEtKk+JDXuY6x85kR6tvA9gv8ZAmC pEK+O9dEOAKFoBPvFcolOgsF97uvbSHvHonzB5ONpQhsFmRVzQFzSJ6nQAocOQI5UPSjcZ5p92Y UAyoXTTd5AWOuezX0is3haIOLNdBdmvUgw+83 X-Gm-Gg: ASbGncsy69vjZr9yOIN7paXCWds0af+DhVktssQZBOTduMFZcmOEnMOulnG4q9pdaqX dE9+COxDoFNwF15aNJP6xfmAcPztgNcvw6JxLnKjmT0mWRbACpcu2kILpG/BglXwb5Q== X-Google-Smtp-Source: AGHT+IFknxnCzFbvgu8AZszEzJyOGLrYHtr2vib+erlkZBzK+H/wa1Cb/HQQn/wWnU9hYJ+F20EUNjy6Fd+wUhb0USc= X-Received: by 2002:a05:6402:390a:b0:5d0:84a6:f1a1 with SMTP id 4fb4d7f45d1cf-5d915fd5b89mr67905a12.6.1735916661051; Fri, 03 Jan 2025 07:04:21 -0800 (PST) MIME-Version: 1.0 References: <20250102233255.1180524-1-isaacmanjarres@google.com> <20250102233255.1180524-2-isaacmanjarres@google.com> In-Reply-To: <20250102233255.1180524-2-isaacmanjarres@google.com> From: Jann Horn Date: Fri, 3 Jan 2025 16:03:44 +0100 X-Gm-Features: AbW1kvZEznasGOClsf9wt8kiTBehvJ5adu0RJBrEPt4Ec9xeLPfDzlDTrZ0G_4Y Message-ID: Subject: Re: [RFC PATCH RESEND v2 1/2] mm/memfd: Add support for F_SEAL_FUTURE_EXEC to memfd To: "Isaac J. Manjarres" Cc: lorenzo.stoakes@oracle.com, Jeff Layton , Chuck Lever , Alexander Aring , Andrew Morton , Shuah Khan , surenb@google.com, kaleshsingh@google.com, jstultz@google.com, aliceryhl@google.com, jeffxu@google.com, kees@kernel.org, kernel-team@android.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 582B8A001A X-Rspamd-Server: rspam12 X-Stat-Signature: ns7mtt86ifsckzq6q8c4gyym19rag4k1 X-Rspam-User: X-HE-Tag: 1735916626-807995 X-HE-Meta: U2FsdGVkX1+LGSQCxFdseF2AXj+pPjVMywQCXccqaBNqrVGHdtN/tSsme1wp9uOUIW9UMibvHB+y5vOCBqICxvuznYxyIvMqz85Bih+khbD0PixSK2umqUaOITMn0CfI5ZR5hkLGOz4rbBeDW548alzbckMEqGrDZqaJDNLuzB6Xj9KEBmj0FO+goFm2YNOoMF73DMJPrSPBn/z/qYt6u81vUa1KwI7pRR6tnR15oBjj5D+s5rHFUecVmxk/hBC+Q/lvd9Ksv8D0nxZcsYSRSdSj6dmb1FWER8m6Ooxq9gCbfiLAj90jqEA9uwAmDxPy+MXfzeGqaRoNx8u06LllQF2XYDiMiNjn+XeH5ct1f6wwUz/N7LdebaDv4WiDkss5RMejS6tOBNeJWrXWm6fps/jvMsy0xmhXnBwlipwKlZttPTEqKDQcCmJC/lqpoe20oTB+9RfwjpVUNaQ6K4AKE4ielorADxt516x4/swVCDRs07E7MrbLzMjObJllQfSNiKII0WklrP5M2SFDdSF7c1QPTBZHyIZ2Bgl8FX3waMbwRLGTgWYBPXEfZVchqfLKvsAthB21j2fPB05elC6gV6P5awoPPGlcKfkJUkzS8kNO0LeHTV+dr3Xw7ItRMTs0AiatqcSaJWfOmZEvBXOnYq8zafXcUAYnLMzyNXp5QLpDVJ1tXVzk5mQ4VY2SdniiSY6hDqc7nz6RXRHFTLMFqj2xTGTGzk7EVvNdYCY8zXneFsEV5JY0RtX29vnw1tNDNiu6kA4mOhV8A4itMvUtTyG0u+RPcxkHkRdqVRqTu+3pGaOCaYEHNmauCcVgK4c5Fq7OAuaA4ewKxwTAeXtatFGBPtq8WkJmjPrAtVa0riQPf0shP0W2RTnE5QR13D0VtppUfqLo5QIk6xGewT1svMIWO5+A/y8ZSIdtc5Rq3ak71kFstR27d3jLN358n0HTbGHgVcJYIMkrsIOqnkl P49rom2L YBJdWPUWwXyPl/Vk/qGdUKAOAWNVoDzTrctKouQlVJ7cpxZS+ikvWNhcMR1x1VzZK57okNlmjetUuFyEezoDFxSdr1iMPmAWaOD3ZZu1VwZbQeAfAF/DnHywMiw3z9XZ6mQ7QAaWJKRR93GpOF++7/sb9+oKpT1hHlIP5wqLTiISIrLCi33io2wt8d9wZDtMhRBIyKz37YAG6p2HraJWlUr1lKi5U2qvFxhKImxj/eWtUM2vwYTOsyCaycCkIC/RF15tKZVIE6CnZQD86u1zhzOh6UARhWBy16h42g08CSo9PGPwy8rjZkVQOWvdZW01NYtGaMCP3KoIKM0ZhZR468KsMNF2typqPdpRYcAjDoNk2rRU= X-Bogosity: Ham, tests=bogofilter, spamicity=0.045878, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: On Fri, Jan 3, 2025 at 12:32=E2=80=AFAM Isaac J. Manjarres wrote: > 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. Is there really code out there that first maps an ashmem buffer with PROT_EXEC, then uses the ioctl to remove execute permission for future mappings? I don't see why anyone would do that. > 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. I think if you want to enforce such restrictions in a scenario where the attacker can already make the target process perform semi-arbitrary syscalls, it would probably be more reliable to enforce rules on executable mappings with something like SELinux policy and/or F_SEAL_EXEC. > 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. Here you're talking about write permission, but the patch is about execute permission? > 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-m= ainline: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 ma= pped */ > #define F_SEAL_EXEC 0x0020 /* prevent chmod modifying exec bits */ > +#define F_SEAL_FUTURE_EXEC 0x0040 /* prevent future executable mappi= ngs */ > /* (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 =3D *vm_flags_ptr; > + unsigned long mask =3D vm_flags & (VM_SHARED | VM_EXEC); > + > + /* Executability is not a concern for private mappings. */ > + if (!(mask & VM_SHARED)) > + return 0; Why is it not a concern for private mappings? > + /* > + * New PROT_EXEC and MAP_SHARED mmaps are not allowed when exec s= eal > + * is active. > + */ > + if (mask & VM_EXEC) > + return -EPERM; > + > + /* > + * Prevent mprotect() from making an exec-sealed mapping executab= le in > + * the future. > + */ > + *vm_flags_ptr &=3D ~VM_MAYEXEC; > + > + return 0; > +} > + > int memfd_check_seals_mmap(struct file *file, unsigned long *vm_flags_pt= r) > { > int err =3D 0; > unsigned int *seals_ptr =3D memfd_file_seals_ptr(file); > unsigned int seals =3D seals_ptr ? *seals_ptr : 0; > > - if (is_write_sealed(seals)) > + if (is_write_sealed(seals)) { > err =3D check_write_seal(vm_flags_ptr); > + if (err) > + return err; > + } > + > + if (is_exec_sealed(seals)) > + err =3D check_exec_seal(vm_flags_ptr); > > return err; > } > -- > 2.47.1.613.gc27f4b7a9f-goog > > >