From patchwork Wed Sep 25 14:52:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shu Han X-Patchwork-Id: 13812073 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 6B084CF9C7A for ; Wed, 25 Sep 2024 14:53:05 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 011056B00B1; Wed, 25 Sep 2024 10:53:05 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id F01816B00B2; Wed, 25 Sep 2024 10:53:04 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DC9286B00B3; Wed, 25 Sep 2024 10:53:04 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id B601C6B00B1 for ; Wed, 25 Sep 2024 10:53:04 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 52262AAE49 for ; Wed, 25 Sep 2024 14:53:04 +0000 (UTC) X-FDA: 82603553088.05.5CA1260 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by imf11.hostedemail.com (Postfix) with ESMTP id 9738040010 for ; Wed, 25 Sep 2024 14:53:02 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=ZPnlwpvr; spf=pass (imf11.hostedemail.com: domain of ebpqwerty472123@gmail.com designates 209.85.216.47 as permitted sender) smtp.mailfrom=ebpqwerty472123@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1727275862; 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-transfer-encoding:content-transfer-encoding: in-reply-to:references:dkim-signature; bh=URux+BlQKOTmnPYbOPO7cMHEzkvt3JkZ4l1c9KS0fJs=; b=nVe4IzlniCr6fxvOZZcg7Ggg7dBBCsQzTwVYkWT9wycyJweK2bh9pZ3s7oY+gIC7wxz7zi 27vyJ0oUSGl1xmic6dPGXpr4ZaHHF0IAZGb3jTSi1AdKqNh+CzfUh+Pj1oiKclMh2NElbQ HRHH1rZyFFVLTOd0cCNcvH3Cprwu0SQ= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1727275862; a=rsa-sha256; cv=none; b=BioEhsSsxxxYF33yOryGw6T0XimjbWvGgBvOX+Y/E62Fj0eqgAN9M05WTL7AmmL2NRRTrI HTTEhvPZ04AJuMXnTszDcqB6SxQdc3D6wld+3PINE0pZWYSN3MtQ6oV2rDcpOrOG7+BMzS LVb1pNLS+/LkZBmJ4I3aN3H9y8q2z+U= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=ZPnlwpvr; spf=pass (imf11.hostedemail.com: domain of ebpqwerty472123@gmail.com designates 209.85.216.47 as permitted sender) smtp.mailfrom=ebpqwerty472123@gmail.com; dmarc=pass (policy=none) header.from=gmail.com Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-2e08085596eso453896a91.3 for ; Wed, 25 Sep 2024 07:53:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727275981; x=1727880781; darn=kvack.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=URux+BlQKOTmnPYbOPO7cMHEzkvt3JkZ4l1c9KS0fJs=; b=ZPnlwpvrAuKogdGMyUPy/lIAjSXIGxNMEbd+Cz2xAiMe6GMkt6v/3aCtrASxmvAr4Z /v6SaARzvyXcP6I2CAT1crMLWeFR/W2n2AwLzCY6U1qg4Q3D9nFagGEo2bO7OupN2SAv KzKM2OQFhFTmKiaIVRgM2HBuaWCLE44VPhPnzbdhn1DuL2srs3NLkgkwGId1/0ykF3go E6xmIZG78i7ToNvRoiIYmRQKwb2eDHY3DO7xlwWAWszumOU17FnR5UWJb5HaRTXSwaM6 vFU+mSQ0+nXvhFVROzrRIQlk7FTG4o4Klu0andKz5X5IG84JwjQ+1GhYjtgtjzX8XHAn tBxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727275981; x=1727880781; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=URux+BlQKOTmnPYbOPO7cMHEzkvt3JkZ4l1c9KS0fJs=; b=pQcy5pRp3OTFIQE3ZB6mk5hM7Hq4sQ5u0fDVRvbsCoyML8JK88Ac/sAEIGABRFWUgU UrFEtBzaP1JnQg+QyG3G9kbOqCfJuafaUXv1hX2PdwXwhp9UESpxY+wtHLnEiBlUPsui UGFZ/e0czou3hXcjRe02/Jp41fuG2uyWQuoHqum9kkpQ67B2cDR0A9sNfYWRbpjKDho5 GD2h6DfPfymHSHbb0V9EpyLv2LUObsEhHCuJYN92zHCgAc6OFiqfzm73OCy5mf/p8gER +VOU4aONLxffeY2AvnPzqlB0U1E9rTpCLTNoZKxGhsrvuZKLqgiuj+GyAskMFKv1x2KW VnNg== X-Gm-Message-State: AOJu0YyiRISe8em5YBRwHyFsgtL7gEivDZwAE8Tu8CEdi/WIRCgLw3/q yWOp8BESLuoJPoAVqucNv28ic7BbgRndcWznwfRAAdMz5CSZWd7f X-Google-Smtp-Source: AGHT+IGhPUQZ+n7yszk/KE8RG3Zymew7SBluMpTMIvTEWbClRv5v274GFfjA4XG98dYXWJBNZDsnmg== X-Received: by 2002:a17:90b:4a4f:b0:2d8:aa9c:e386 with SMTP id 98e67ed59e1d1-2e06ae5e76dmr3991797a91.14.1727275981094; Wed, 25 Sep 2024 07:53:01 -0700 (PDT) Received: from localhost.localdomain ([20.37.103.148]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e06e1fedadsm1622558a91.28.2024.09.25.07.52.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Sep 2024 07:53:00 -0700 (PDT) From: Shu Han To: akpm@linux-foundation.org, paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com, Liam.Howlett@oracle.com, vbabka@suse.cz, lorenzo.stoakes@oracle.com Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org Subject: [PATCH RFC v3] mm: move the check of READ_IMPLIES_EXEC out of do_mmap() Date: Wed, 25 Sep 2024 22:52:49 +0800 Message-Id: <20240925145249.50-1-ebpqwerty472123@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 9738040010 X-Stat-Signature: sptimays9jrdd7kbw64d6a7cxj7jxtk9 X-HE-Tag: 1727275982-636600 X-HE-Meta: U2FsdGVkX18fr3+sj7i6SY9e+2C1vYEs3kjg+lZjrNyOXurlkVkZ6uNGu7/OPP4LPB1iN2W4ORgklFqXfUpzrgaGGoyNtOTuv9DjvZMANM98hkncUEBUovA2Vgka9gQuyQgJvRA6aeZGTso5Sv4lym+GvIOfMyNWdkgZ4TXnHpF5PiuwojIU0ZY/Bk7iF+FohigVX8p7ST9fpTXmm43f5w/1eT+MhoaqvxEVjpuUdcCy0irLyHsKVJZwc1gA9JcQOqouurLl1QRy8/9J4vblbAL/qZrBlT0pDNlnLvR9Lyl5xd3wQsSjfgqfuiS2HPa0AqXPKLcRz0Lbz7MzTRLAz9wBrfnL6Ymf64zQTgr3q1GGhHtbX0/0QKiOZa8SluaAPANhrZJyLtn6v4hZ2zJ9GF0W1VTu6Fh0vgwmodl8OzM1cEyej4Ze4tmsB7JUeCrKr8mWEuSKzTKBpowxG+hPqDOf+oZrDq9F2YKNsYFf3grDUXMfLQ/SVBkFo0yr4H6xdSWYoCFmV03HDMZUXIUl/j8gjAEs8yeENs3Aql2+/Q0HIm8MJFLrlBUMPqM0e8jexNB0EWxyCEn7LdE2IVP9tWTn+cKei8Lqmf3ZtVzVDdIf52gqlaLTDvFacIqstHnxOVm2/cEjaoviQSz9FrgXOs+IDreDKn6xmirzBQaEu43Q8c4ha9bGJ6bGsi7GNTq5K+IkMRP/2cWmyquxZH1fdY3IwUXG7eFTXpU39BOpzg8pNMhNLQvyHlYB7nCkrlZwOaovmcZ/MfR+cGS6zkvZrhAtxHEKJ7RF05WhmFY3QRliE1pbwP1QnfiDrqN2RkJZlf0OZwGe/im+qXbAby8HzeBaD1wpf/je8ocfWwj/Gpt2p2eACZ9E7W0og/IcNKU9rdFGyeTkoeTd7HuVcm4f3BKVIW18juDL6W9dmotFZlSvQvDSV751HrLVfltgasP03RLqg2NbFmQKNhDON68 KM3OEpP2 I8JQ3w22TrFJTONuHLLLXGHYBLa0xPFJWbDRVvXpGa82ADDvNWbLZFuTpzGB5RsDzbzNSSkmCLD5y8zGQjy/IlCBMax37USWlrDe/Y2zADmTvpGEs3wG40KYl4qW7tUjVwLwCTaVnNgVcrhJdhLR6wql1MfU6agWTaadsTXQGWezlxBY8Ql0umxs4fgPpvqYd6Vcc544VdlfHEACf5PKk0+dQYkSt2+ELkDqynSb5zve/583e6gDbvnriDdvJNsQDHW1WwFgB8+v8n2FedsdFMQnU3yxhhef82VqPM3WNF8+QeLGtbcUHjuvlqivEa+eG1xiidy/4Fcv/u3RAdEOUogBGnZKd7EHrDH3WCw/KrT5JKY4JAvhgglfmbDdPaRzM96GD/ZXa88hCeRGmRnO0eeK6UXTt5bgIEeTkJ5C4wRDFRn9twBrVac3lVUBv5mpGBcfyW7fdOQtyukhfqt117f5532yQp9kRQh7YP4VeFec3WLGpijbZtD+BUyFgtWCofqLJ0zsqkH8O6UOZeOuPuZ/VaHo2dUerENQW+lR63BFxC1Y= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: This patch moves the check of READ_IMPLIES_EXEC out of do_mmap(), and calls the LSM hooks at the same time. Below is the reason. This patch is related to: 1. the personality flag READ_IMPLIES_EXEC, which can be changed in userspace and will add PROT_EXEC to prot in do_mmap() when it is set and some other conditions are met. 2. the LSM hook security_mmap_file, which requires the prot before and after 1. For now, this is the mmap() logic that actually executes (only the part we care): 1. call security_mmap_file() 1.1. calculate the final prot in mmap_prot() 1.2. call hooks by the original prot and the final prot 2. lock mmap_write_lock 3. call do_mmap() 3.1. calculate the final prot again according to the personality flag READ_IMPLIES_EXEC and other conditions 3.2. do the actual memory map with the final prot 4. unlock mmap_write_lock There are 2 problems with them: 1. The final prot is calculated twice, which is redundant. And currently, the !MMU case won't imply exec if the file's mmap_capabilities do not exist in step 3.1, but step 1.1 is different. 2. Some other call sites call do_mmap() without step 1, which is still secure if there is no step 3.1 since they map an anonymous page or a private file without PROT_EXEC, which is not cared for by LSM. So, it is implied that it is call sites' duty to do step 1.1 or let step 3.1 never take effect(let other conditions not be met, such as marking the mapped file as NO_EXEC). Especially the implicit duty in problem 2 is rarely noticed by the caller, which leads to some security issues(in aio[1] and remap_file_pages[2]). It is believed that the future call sites to do_mmap() is easily to harm the security if we don't take measures. The measures in this patch are moving step 3.1 out of do_mmap(), into the new function mmap_check_prot(), and calling the LSM hooks in the same function. The function is out of the mmap_write_lock. The measures remove the repeated logic in step 1.1 and let further call sites have 2 choices: 1. call mmap_check_prot() before calling do_mmap(), which is equal to the current steps 1-4. 2. call do_mmap() directly, which is still secure since there is no step 3.1 in do_mmap() anymore. The potential harm that remains without precedent is a new caller calls do_mmap() with a non-private file and the PROT_EXEC flag, which is mentioned in the comment of do_mmap(). The measures have a minor behavior change, which is: If the call site selects choice 2 and the conditions for READ_IMPLIES_EXEC are met, there will be no PROT_EXEC automatically added anymore. This is all call sites currently and why they should clearly be fine: 1. mm/util.c: choice 1. 2. ipc/shm.c: choice 1. 3. fs/aio.c: the conditions for READ_IMPLIES_EXEC will never be met since the patch for [1] adds the noexec flag. 4. arch/x86/kernel/shstk.c: must not be intended to have PROT_EXEC, since shadow stack is a stack that only store return addresses, executing it is never required. 5. mm/mmap.c: in the history, remap_file_pages won't change prot, which is changed in the emulation version after the deprecated mark exists. the patch only revert the side effect introduced in the emulation version. Link: https://project-zero.issues.chromium.org/issues/42452389 [1] Link: https://lore.kernel.org/all/20240919080905.4506-2-paul@paul-moore.com/ [2] Signed-off-by: Shu Han --- May require a better name for mmap_check_prot(). v3: Send only one version as lorenzo.stoakes@oracle.com suggested and rewrite the description more clearly. Sorry for the inconvenience caused by v1 and v2. v2: Add RFC tag as lorenzo.stoakes@oracle.com suggested, and refine the comment in the patch. https://lore.kernel.org/all/20240925120940.309-1-ebpqwerty472123@gmail.com/ v1: The original. https://lore.kernel.org/all/20240925063034.169-1-ebpqwerty472123@gmail.com/ Alternatives: 1. Add sufficient comments for do_mmap() without code changes. This method remains problem 1 unsolved. 2. Move security_mmap_file() back into do_mmap(). No cases should caller to be taken care anymore, but LSM modules should check their hook for mmap_file works fine in the mmap_write_lock. The detail is in(separating it should be a mistake) https://lore.kernel.org/all/20240925115701.73-1-ebpqwerty472123@gmail.com/ --- include/linux/mm.h | 2 ++ include/linux/security.h | 8 +++---- ipc/shm.c | 2 +- mm/mmap.c | 42 ++++++++++++++++++++++------------ mm/nommu.c | 49 +++++++++++++++++++++++++++++++--------- mm/util.c | 2 +- security/security.c | 41 ++++----------------------------- 7 files changed, 78 insertions(+), 68 deletions(-) base-commit: f89722faa31466ff41aed21bdeb9cf34c2312858 diff --git a/include/linux/mm.h b/include/linux/mm.h index c4b238a20b76..83f334590b06 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3392,6 +3392,8 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, vm_flags_t vm_flags, unsigned long pgoff, struct list_head *uf); +extern int mmap_check_prot(struct file *file, unsigned long *prot, + unsigned long flags); extern unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, vm_flags_t vm_flags, unsigned long pgoff, unsigned long *populate, diff --git a/include/linux/security.h b/include/linux/security.h index c37c32ebbdcd..e061bc9a0331 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -423,8 +423,8 @@ void security_file_free(struct file *file); int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int security_file_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg); -int security_mmap_file(struct file *file, unsigned long prot, - unsigned long flags); +int security_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags); int security_mmap_addr(unsigned long addr); int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot); @@ -1077,8 +1077,8 @@ static inline int security_file_ioctl_compat(struct file *file, return 0; } -static inline int security_mmap_file(struct file *file, unsigned long prot, - unsigned long flags) +static inline int security_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) { return 0; } diff --git a/ipc/shm.c b/ipc/shm.c index 3e3071252dac..f1095ee3796d 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1636,7 +1636,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, sfd->vm_ops = NULL; file->private_data = sfd; - err = security_mmap_file(file, prot, flags); + err = mmap_check_prot(file, &prot, flags); if (err) goto out_fput; diff --git a/mm/mmap.c b/mm/mmap.c index 18fddcce03b8..b979a6055f8e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1249,8 +1249,36 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode, return true; } +int mmap_check_prot(struct file *file, unsigned long *prot, + unsigned long flags) +{ + unsigned long req_prot = *prot; + unsigned long new_prot = req_prot; + int err; + + /* + * Does the application expect PROT_READ to imply PROT_EXEC? + * + * (the exception is when the underlying filesystem is noexec + * mounted, in which case we don't add PROT_EXEC.) + */ + if (((req_prot & (PROT_READ | PROT_EXEC)) == PROT_READ) && + (current->personality & READ_IMPLIES_EXEC) && + !(file && path_noexec(&file->f_path))) + new_prot |= PROT_EXEC; + + err = security_mmap_file(file, req_prot, new_prot, flags); + if (err) + return err; + + *prot = new_prot; + return 0; +} + /* * The caller must write-lock current->mm->mmap_lock. + * The caller must call mmap_check_prot before if + * (file && !IS_PRIVATE(file_inode(file)) && (prot & PROT_EXEC)). */ unsigned long do_mmap(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -1266,16 +1294,6 @@ unsigned long do_mmap(struct file *file, unsigned long addr, if (!len) return -EINVAL; - /* - * Does the application expect PROT_READ to imply PROT_EXEC? - * - * (the exception is when the underlying filesystem is noexec - * mounted, in which case we don't add PROT_EXEC.) - */ - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) - if (!(file && path_noexec(&file->f_path))) - prot |= PROT_EXEC; - /* force arch specific MAP_FIXED handling in get_unmapped_area */ if (flags & MAP_FIXED_NOREPLACE) flags |= MAP_FIXED; @@ -3198,12 +3216,8 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, flags |= MAP_LOCKED; file = get_file(vma->vm_file); - ret = security_mmap_file(vma->vm_file, prot, flags); - if (ret) - goto out_fput; ret = do_mmap(vma->vm_file, start, size, prot, flags, 0, pgoff, &populate, NULL); -out_fput: fput(file); out: mmap_write_unlock(mm); diff --git a/mm/nommu.c b/mm/nommu.c index 7296e775e04e..96761add1295 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -792,12 +792,6 @@ static int validate_mmap_request(struct file *file, if (path_noexec(&file->f_path)) { if (prot & PROT_EXEC) return -EPERM; - } else if ((prot & PROT_READ) && !(prot & PROT_EXEC)) { - /* handle implication of PROT_EXEC by PROT_READ */ - if (current->personality & READ_IMPLIES_EXEC) { - if (capabilities & NOMMU_MAP_EXEC) - prot |= PROT_EXEC; - } } else if ((prot & PROT_READ) && (prot & PROT_EXEC) && !(capabilities & NOMMU_MAP_EXEC) @@ -810,11 +804,6 @@ static int validate_mmap_request(struct file *file, * privately mapped */ capabilities = NOMMU_MAP_COPY; - - /* handle PROT_EXEC implication by PROT_READ */ - if ((prot & PROT_READ) && - (current->personality & READ_IMPLIES_EXEC)) - prot |= PROT_EXEC; } /* allow the security API to have its say */ @@ -992,6 +981,44 @@ static int do_mmap_private(struct vm_area_struct *vma, return -ENOMEM; } +int mmap_check_prot(struct file *file, unsigned long *prot, + unsigned long flags) +{ + unsigned long req_prot = *prot; + unsigned long new_prot = req_prot; + int err; + + /* + * Does the application expect PROT_READ to imply PROT_EXEC? + * + * (the exception is when the underlying filesystem is noexec + * mounted or the file does not have NOMMU_MAP_EXEC + * (== VM_MAYEXEC), in which case we don't add PROT_EXEC.) + */ + if ((req_prot & (PROT_READ | PROT_EXEC)) != PROT_READ) + goto check; + if (!(current->personality & READ_IMPLIES_EXEC)) + goto check; + if (!file) { + new_prot |= PROT_EXEC; + goto check; + } + if (file->f_op->mmap_capabilities) { + unsigned int caps = file->f_op->mmap_capabilities(file); + + if (!(caps & NOMMU_MAP_EXEC)) + goto check; + new_prot |= PROT_EXEC; + } +check: + err = security_mmap_file(file, req_prot, new_prot, flags); + if (err) + return err; + + *prot = new_prot; + return 0; +} + /* * handle mapping creation for uClinux */ diff --git a/mm/util.c b/mm/util.c index bd283e2132e0..2eb4d6037610 100644 --- a/mm/util.c +++ b/mm/util.c @@ -581,7 +581,7 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr, unsigned long populate; LIST_HEAD(uf); - ret = security_mmap_file(file, prot, flag); + ret = mmap_check_prot(file, &prot, flag); if (!ret) { if (mmap_write_lock_killable(mm)) return -EINTR; diff --git a/security/security.c b/security/security.c index 4564a0a1e4ef..25556629f588 100644 --- a/security/security.c +++ b/security/security.c @@ -2927,42 +2927,10 @@ int security_file_ioctl_compat(struct file *file, unsigned int cmd, } EXPORT_SYMBOL_GPL(security_file_ioctl_compat); -static inline unsigned long mmap_prot(struct file *file, unsigned long prot) -{ - /* - * Does we have PROT_READ and does the application expect - * it to imply PROT_EXEC? If not, nothing to talk about... - */ - if ((prot & (PROT_READ | PROT_EXEC)) != PROT_READ) - return prot; - if (!(current->personality & READ_IMPLIES_EXEC)) - return prot; - /* - * if that's an anonymous mapping, let it. - */ - if (!file) - return prot | PROT_EXEC; - /* - * ditto if it's not on noexec mount, except that on !MMU we need - * NOMMU_MAP_EXEC (== VM_MAYEXEC) in this case - */ - if (!path_noexec(&file->f_path)) { -#ifndef CONFIG_MMU - if (file->f_op->mmap_capabilities) { - unsigned caps = file->f_op->mmap_capabilities(file); - if (!(caps & NOMMU_MAP_EXEC)) - return prot; - } -#endif - return prot | PROT_EXEC; - } - /* anything on noexec mount won't get PROT_EXEC */ - return prot; -} - /** * security_mmap_file() - Check if mmap'ing a file is allowed * @file: file + * @reqprot: protection requested by user * @prot: protection applied by the kernel * @flags: flags * @@ -2971,11 +2939,10 @@ static inline unsigned long mmap_prot(struct file *file, unsigned long prot) * * Return: Returns 0 if permission is granted. */ -int security_mmap_file(struct file *file, unsigned long prot, - unsigned long flags) +int security_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) { - return call_int_hook(mmap_file, file, prot, mmap_prot(file, prot), - flags); + return call_int_hook(mmap_file, file, reqprot, prot, flags); } /**