linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 6.6 048/139] proc: add config & param to block forcing mem writes
       [not found] <20240925121137.1307574-1-sashal@kernel.org>
@ 2024-09-25 12:07 ` Sasha Levin
  2024-09-25 15:58   ` Alexey Dobriyan
  0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2024-09-25 12:07 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Adrian Ratiu, Doug Anderson, Jeff Xu, Jann Horn, Kees Cook,
	Ard Biesheuvel, Christian Brauner, Linus Torvalds, Sasha Levin,
	corbet, paul, jmorris, serge, thuth, bp, tglx, jpoimboe, paulmck,
	tony, xiongwei.song, akpm, oleg, adobriyan, casey, viro,
	linux-doc, linux-fsdevel, linux-security-module

From: Adrian Ratiu <adrian.ratiu@collabora.com>

[ Upstream commit 41e8149c8892ed1962bd15350b3c3e6e90cba7f4 ]

This adds a Kconfig option and boot param to allow removing
the FOLL_FORCE flag from /proc/pid/mem write calls because
it can be abused.

The traditional forcing behavior is kept as default because
it can break GDB and some other use cases.

Previously we tried a more sophisticated approach allowing
distributions to fine-tune /proc/pid/mem behavior, however
that got NAK-ed by Linus [1], who prefers this simpler
approach with semantics also easier to understand for users.

Link: https://lore.kernel.org/lkml/CAHk-=wiGWLChxYmUA5HrT5aopZrB7_2VTa0NLZcxORgkUe5tEQ@mail.gmail.com/ [1]
Cc: Doug Anderson <dianders@chromium.org>
Cc: Jeff Xu <jeffxu@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Christian Brauner <brauner@kernel.org>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Link: https://lore.kernel.org/r/20240802080225.89408-1-adrian.ratiu@collabora.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../admin-guide/kernel-parameters.txt         | 10 +++
 fs/proc/base.c                                | 61 ++++++++++++++++++-
 security/Kconfig                              | 32 ++++++++++
 3 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index a7fe113897361..d83a3f47e2007 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4639,6 +4639,16 @@
 	printk.time=	Show timing data prefixed to each printk message line
 			Format: <bool>  (1/Y/y=enable, 0/N/n=disable)
 
+	proc_mem.force_override= [KNL]
+			Format: {always | ptrace | never}
+			Traditionally /proc/pid/mem allows memory permissions to be
+			overridden without restrictions. This option may be set to
+			restrict that. Can be one of:
+			- 'always': traditional behavior always allows mem overrides.
+			- 'ptrace': only allow mem overrides for active ptracers.
+			- 'never':  never allow mem overrides.
+			If not specified, default is the CONFIG_PROC_MEM_* choice.
+
 	processor.max_cstate=	[HW,ACPI]
 			Limit processor to maximum C-state
 			max_cstate=9 overrides any DMI blacklist limit.
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6e61d93ffa552..699f085d4de7d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -85,6 +85,7 @@
 #include <linux/elf.h>
 #include <linux/pid_namespace.h>
 #include <linux/user_namespace.h>
+#include <linux/fs_parser.h>
 #include <linux/fs_struct.h>
 #include <linux/slab.h>
 #include <linux/sched/autogroup.h>
@@ -116,6 +117,40 @@
 static u8 nlink_tid __ro_after_init;
 static u8 nlink_tgid __ro_after_init;
 
+enum proc_mem_force {
+	PROC_MEM_FORCE_ALWAYS,
+	PROC_MEM_FORCE_PTRACE,
+	PROC_MEM_FORCE_NEVER
+};
+
+static enum proc_mem_force proc_mem_force_override __ro_after_init =
+	IS_ENABLED(CONFIG_PROC_MEM_NO_FORCE) ? PROC_MEM_FORCE_NEVER :
+	IS_ENABLED(CONFIG_PROC_MEM_FORCE_PTRACE) ? PROC_MEM_FORCE_PTRACE :
+	PROC_MEM_FORCE_ALWAYS;
+
+static const struct constant_table proc_mem_force_table[] __initconst = {
+	{ "always", PROC_MEM_FORCE_ALWAYS },
+	{ "ptrace", PROC_MEM_FORCE_PTRACE },
+	{ "never", PROC_MEM_FORCE_NEVER },
+	{ }
+};
+
+static int __init early_proc_mem_force_override(char *buf)
+{
+	if (!buf)
+		return -EINVAL;
+
+	/*
+	 * lookup_constant() defaults to proc_mem_force_override to preseve
+	 * the initial Kconfig choice in case an invalid param gets passed.
+	 */
+	proc_mem_force_override = lookup_constant(proc_mem_force_table,
+						  buf, proc_mem_force_override);
+
+	return 0;
+}
+early_param("proc_mem.force_override", early_proc_mem_force_override);
+
 struct pid_entry {
 	const char *name;
 	unsigned int len;
@@ -834,6 +869,28 @@ static int mem_open(struct inode *inode, struct file *file)
 	return ret;
 }
 
+static bool proc_mem_foll_force(struct file *file, struct mm_struct *mm)
+{
+	struct task_struct *task;
+	bool ptrace_active = false;
+
+	switch (proc_mem_force_override) {
+	case PROC_MEM_FORCE_NEVER:
+		return false;
+	case PROC_MEM_FORCE_PTRACE:
+		task = get_proc_task(file_inode(file));
+		if (task) {
+			ptrace_active =	READ_ONCE(task->ptrace) &&
+					READ_ONCE(task->mm) == mm &&
+					READ_ONCE(task->parent) == current;
+			put_task_struct(task);
+		}
+		return ptrace_active;
+	default:
+		return true;
+	}
+}
+
 static ssize_t mem_rw(struct file *file, char __user *buf,
 			size_t count, loff_t *ppos, int write)
 {
@@ -854,7 +911,9 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
 	if (!mmget_not_zero(mm))
 		goto free;
 
-	flags = FOLL_FORCE | (write ? FOLL_WRITE : 0);
+	flags = write ? FOLL_WRITE : 0;
+	if (proc_mem_foll_force(file, mm))
+		flags |= FOLL_FORCE;
 
 	while (count > 0) {
 		size_t this_len = min_t(size_t, count, PAGE_SIZE);
diff --git a/security/Kconfig b/security/Kconfig
index 52c9af08ad35d..39af8b8696efb 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -19,6 +19,38 @@ config SECURITY_DMESG_RESTRICT
 
 	  If you are unsure how to answer this question, answer N.
 
+choice
+	prompt "Allow /proc/pid/mem access override"
+	default PROC_MEM_ALWAYS_FORCE
+	help
+	  Traditionally /proc/pid/mem allows users to override memory
+	  permissions for users like ptrace, assuming they have ptrace
+	  capability.
+
+	  This allows people to limit that - either never override, or
+	  require actual active ptrace attachment.
+
+	  Defaults to the traditional behavior (for now)
+
+config PROC_MEM_ALWAYS_FORCE
+	bool "Traditional /proc/pid/mem behavior"
+	help
+	  This allows /proc/pid/mem accesses to override memory mapping
+	  permissions if you have ptrace access rights.
+
+config PROC_MEM_FORCE_PTRACE
+	bool "Require active ptrace() use for access override"
+	help
+	  This allows /proc/pid/mem accesses to override memory mapping
+	  permissions for active ptracers like gdb.
+
+config PROC_MEM_NO_FORCE
+	bool "Never"
+	help
+	  Never override memory mapping permissions
+
+endchoice
+
 config SECURITY
 	bool "Enable different security models"
 	depends on SYSFS
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH AUTOSEL 6.6 048/139] proc: add config & param to block forcing mem writes
  2024-09-25 12:07 ` [PATCH AUTOSEL 6.6 048/139] proc: add config & param to block forcing mem writes Sasha Levin
@ 2024-09-25 15:58   ` Alexey Dobriyan
  2024-09-26 11:07     ` Adrian Ratiu
  0 siblings, 1 reply; 3+ messages in thread
From: Alexey Dobriyan @ 2024-09-25 15:58 UTC (permalink / raw)
  To: Sasha Levin
  Cc: linux-kernel, stable, Adrian Ratiu, Doug Anderson, Jeff Xu,
	Jann Horn, Kees Cook, Ard Biesheuvel, Christian Brauner,
	Linus Torvalds, corbet, paul, jmorris, serge, thuth, bp, tglx,
	jpoimboe, paulmck, tony, xiongwei.song, akpm, oleg, casey, viro,
	linux-doc, linux-fsdevel, linux-security-module

On Wed, Sep 25, 2024 at 08:07:48AM -0400, Sasha Levin wrote:
> From: Adrian Ratiu <adrian.ratiu@collabora.com>
> 
> [ Upstream commit 41e8149c8892ed1962bd15350b3c3e6e90cba7f4 ]
> 
> This adds a Kconfig option and boot param to allow removing
> the FOLL_FORCE flag from /proc/pid/mem write calls because
> it can be abused.

And this is not a mount option why?

> The traditional forcing behavior is kept as default because
> it can break GDB and some other use cases.
> 
> Previously we tried a more sophisticated approach allowing
> distributions to fine-tune /proc/pid/mem behavior, however
> that got NAK-ed by Linus [1], who prefers this simpler
> approach with semantics also easier to understand for users.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH AUTOSEL 6.6 048/139] proc: add config & param to block forcing mem writes
  2024-09-25 15:58   ` Alexey Dobriyan
@ 2024-09-26 11:07     ` Adrian Ratiu
  0 siblings, 0 replies; 3+ messages in thread
From: Adrian Ratiu @ 2024-09-26 11:07 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: linux-kernel, stable, Doug Anderson, Jeff Xu, Jann Horn,
	Kees Cook, Ard Biesheuvel, Christian Brauner, Linus Torvalds,
	corbet, paul, jmorris, serge, thuth, bp, tglx, jpoimboe, paulmck,
	tony, xiongwei.song, akpm, oleg, casey, viro, linux-doc,
	linux-fsdevel, linux-security-module, Sasha Levin

On Wed, 25 Sep 2024, Alexey Dobriyan <adobriyan@gmail.com> wrote:
> On Wed, Sep 25, 2024 at 08:07:48AM -0400, Sasha Levin wrote: 
>> From: Adrian Ratiu <adrian.ratiu@collabora.com>  [ Upstream 
>> commit 41e8149c8892ed1962bd15350b3c3e6e90cba7f4 ]  This adds a 
>> Kconfig option and boot param to allow removing the FOLL_FORCE 
>> flag from /proc/pid/mem write calls because it can be abused. 
> 
> And this is not a mount option why? 

Hello and thanks for asking!

The only reason is nobody asked for it yet. :)

We need to be careful how we do this, so the restriction is still 
enabled when remounting, otherwise I don't see any impediment, 
provided we can find a way to make it clean and safe.
 
I am travelling these weeks (All Systems GO conf) and have a lot 
going on, so please feel free to send a patch and I'll review it 
ASAP, otherwise I'll try to come up with something by end of 
October.

Adrian

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-09-26 11:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20240925121137.1307574-1-sashal@kernel.org>
2024-09-25 12:07 ` [PATCH AUTOSEL 6.6 048/139] proc: add config & param to block forcing mem writes Sasha Levin
2024-09-25 15:58   ` Alexey Dobriyan
2024-09-26 11:07     ` Adrian Ratiu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).