sysctl: control functionality of /proc/pid/mem
Subsystems (3)
PATCH v3 1/1 sysctl: control functionality of /proc/pid/mem
Add the "proc_pid_mem" sysctl to control whether or not /proc/pid/mem is allowed to work: 0: disabled, 1: read only, 2: read/write (default).
---
v3:
- document the default, thanks to Randy Dunlap.
- remove needless CONFIG_PROC_FS checks, thanks to Eric W. Biederman.
v2:
- fix memory leak in error path, thanks to Ingo Molnar.
--- Documentation/sysctl/kernel.txt | 15 +++++++++++++++ fs/proc/base.c | 14 +++++++++++++- kernel/sysctl.c | 10 ++++++++++ 3 files changed, 38 insertions(+), 1 deletions(-)
Documentation/sysctl/kernel.txt +15 -0
@@ -56,6 +56,7 @@ show up in /proc/sys/kernel: - printk_delay - printk_ratelimit - printk_ratelimit_burst +- proc_pid_mem - randomize_va_space - real-root-dev ==> Documentation/initrd.txt - reboot-cmd [ SPARC only ]
@@ -477,6 +478,20 @@ send before ratelimiting kicks in. ============================================================== +proc_pid_mem: + +This option can be used to select the level of access given to potential +ptracers when using the per-process "mem" file in /proc/pid/mem. + +0 - Disable entirely. + +1 - Allow potential ptracers read access to process memory, but not writes. + +2 - Allow potential ptracers read and write access to process memory. This + is the default. + +============================================================== + randomize_va_space: This option can be used to select the type of process address
fs/proc/base.c +13 -1
@@ -109,6 +109,8 @@ struct pid_entry {union proc_op op; }; +int sysctl_proc_pid_mem =2 ; +#define NOD (NAME ,MODE ,IOP ,FOP ,OP ) { \ .name = (NAME), \ .len = sizeof(NAME) - 1, \
@@ -699,9 +701,13 @@ static const struct file_operations proc_single_file_operations = {static int mem_open (struct inode * inode,struct file * file) { -struct task_struct *task =get_proc_task (file->f_path.dentry->d_inode); +struct task_struct *task;struct mm_struct *mm; +if (sysctl_proc_pid_mem <1 ) +return -EACCES ; + + task =get_proc_task (file->f_path.dentry->d_inode);if (!task)return -ESRCH ;
@@ -726,6 +732,9 @@ static ssize_t mem_read(struct file * file, char __user * buf,unsigned long src = *ppos;struct mm_struct *mm = file->private_data; +if (sysctl_proc_pid_mem <1 ) +return -EACCES ; +if (!mm)return 0 ;
@@ -770,6 +779,9 @@ static ssize_t mem_write(struct file * file, const char __user *buf,unsigned long dst = *ppos;struct mm_struct *mm = file->private_data; +if (sysctl_proc_pid_mem <2 ) +return -EACCES ; +if (!mm)return 0 ;
kernel/sysctl.c +10 -0
@@ -103,6 +103,7 @@ extern int percpu_pagelist_fraction;extern int compat_log;extern int latencytop_enabled;extern int sysctl_nr_open_min, sysctl_nr_open_max; +extern int sysctl_proc_pid_mem;#ifndef CONFIG_MMU extern int sysctl_nr_trim_pages;#endif
@@ -1004,6 +1005,15 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, },#endif + { + .procname = "proc_pid_mem", + .data = &sysctl_proc_pid_mem, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &two, + }, { } };
Signature · 1 line
1.7.0.4
(cc'ed kernel-hardening)
Quoted 4 lines · Kees Cook
Add the "
proc_pid_mem" sysctl to control whether or not/proc/pid/memis allowed to work: 0: disabled, 1: read only, 2: read/write (default).kernel/sysctl.c +0
-0
...
Quoted 14 lines
index f487f25..6fd4bc0 100644
kernel/sysctl.c +1
-0@@ -103,6 +103,7 @@ extern int percpu_pagelist_fraction;extern int compat_log;extern int latencytop_enabled;extern int sysctl_nr_open_min, sysctl_nr_open_max; +extern int sysctl_proc_pid_mem;#ifndef CONFIG_MMU extern int sysctl_nr_trim_pages;#endif @@ -1004,6 +1005,15 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, },
kernel/sysctl.c static struct ctl_table kern_table[] = { · line 1016
Quoted 10 lines
kernel/sysctl.c +9
-0#endif + { + .procname = "proc_pid_mem", + .data = &sysctl_proc_pid_mem, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &two, + },
While I fully agree that we should step by step opt out all deprecated and legacy features, which are not widely used nowadays and are probably dangerous from the security POV, but we should define a standart way of doing it. E.g. moving all such stuff to some sysctl group, not bloating kernel.*. Probably sysctl dir kernel.legacy.*? Then this sysctl would be kernel.legacy.proc_pid_mem.
Thanks,
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
Quoted 11 lines · Vasiliy Kulikov
kernel/sysctl.c static struct ctl_table kern_table[] = { · line 1016
Quoted 8 lines
kernel/sysctl.c +8
-0+ .procname = "proc_pid_mem", + .data = &sysctl_proc_pid_mem, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &two, + },E.g. moving all such stuff to some sysctl group, not bloating kernel.*.
Ehh.
How bloat is measured in this case?
Quoted 13 lines · Alexey Dobriyan
Quoted 11 lines · Vasiliy Kulikov
kernel/sysctl.c static struct ctl_table kern_table[] = { · line 1016
Quoted 8 lines
kernel/sysctl.c +8
-0+ .procname = "proc_pid_mem", + .data = &sysctl_proc_pid_mem, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &two, + },E.g. moving all such stuff to some sysctl group, not bloating kernel.*.
Quoted 2 lines
Ehh.
How bloat is measured in this case?
Do we want to add such sort of sysctls "from time to time" when we consider one or another feature as deprecated? If yes, I'd group them somehow, e.g. by introducing subdirectory inside of kernel.
Btw, kernel sysctl dir contains all sort of stuff which goes to "kernel" as if it is "etc". It already contains ftrace, perf, printk, scheduler, ipc. IMHO plain kernel hierarchy is not profitable in the long term.
Thanks,
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
Quoted 17 lines · Vasiliy Kulikov
Quoted 10 lines · Alexey Dobriyan
Quoted 8 lines · Vasiliy Kulikov
Quoted 8 lines
+ .procname = "
proc_pid_mem",
+ .data =&sysctl_proc_pid_mem,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler =proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &two,
+ },Quoted 5 lines
Quoted 2 lines
E.g. moving all such stuff to some sysctl group, not bloating kernel.*.
Ehh.
How bloat is measured in this case?
Quoted 7 lines
Do we want to add such sort of sysctls "from time to time" when we consider one or another feature as deprecated? If yes, I'd group them somehow, e.g. by introducing subdirectory inside of kernel.
Btw, kernel sysctl dir contains all sort of stuff which goes to "kernel" as if it is "etc". It already contains ftrace, perf, printk, scheduler, ipc. IMHO plain kernel hierarchy is not profitable in the long term.
Yeah, after reconsidering this, this sysctl is not the right approach.
-Kees
Signature · 2 lines
Kees Cook ChromeOS Security
Quoted 2 lines · Kees Cook
Add the "
proc_pid_mem" sysctl to control whether or not/proc/pid/memis allowed to work: 0: disabled, 1: read only, 2: read/write (default).
Both your git commit and the Documentation/ entry are totally missing a rationale for this. Why would an admin want to set this on or off? What replaces it, if anything? What are the tradeoffs with its replacement? What userspace programs might break when this is toggled?
Quoted 9 lines · On Mon, 23 Jan 2012 13:21:15 -0800 Kees Cook <[email protected]> wrote:
Add the "
proc_pid_mem" sysctl to control whether or not/proc/pid/memis allowed to work: 0: disabled, 1: read only, 2: read/write (default).Signed-off-by Kees Cook <[email protected]>---
v3:
- document the default, thanks to Randy Dunlap.
- remove needlessCONFIG_PROC_FSchecks, thanks to Eric W. Biederman.
I was wondering about that. Is CONFIG_PROC_FS=n, CONFIG_SYSCTL=y an impossible combination? If so, why?
Quoted 17 lines
Documentation/sysctl/kernel.txt +4
-0@@ -56,6 +56,7 @@ show up in /proc/sys/kernel: - printk_delay - printk_ratelimit - printk_ratelimit_burst +- proc_pid_mem - randomize_va_space - real-root-dev ==> Documentation/initrd.txt - reboot-cmd [ SPARC only ]@@ -477,6 +478,20 @@ send before ratelimiting kicks in. ============================================================== +proc_pid_mem: + +This option can be used to select the level of access given to potential
Documentation/sysctl/kernel.txt send before ratelimiting kicks in. · line 493
Quoted 10 lines
Documentation/sysctl/kernel.txt +10
-0+ptracers when using the per-process "mem" file in /proc/pid/mem. + +0 - Disable entirely. + +1 - Allow potential ptracers read access to process memory, but not writes. + +2 - Allow potential ptracers read and write access to process memory. This + is the default. + +==============================================================
I agree with Colin on this (he stole my line!).
Overall, the patch looks really hacky and random. I felt the same way as Vasily: it's easy to see how a significant number of similar (and hacky and random) patches could be added, resulting in a regrettable mess.
Is there some better designed, more organized way of approaching all of this? Random ideas:
- A parallel /procfs-perms filesystem. You write a number into /procfs-perms/stat to affect access to /proc/stat (although why the heck not just run `chmod /proc/stat'?) It's unclear how to handle /proc/pid/. Perhaps literally have a /procfs-perms/pid/ directory.
- Make tasks inherit their /proc/pid/* permissions across fork, do a chmod /proc/1/whatever in initscripts.
- Other and better things ;) This particular approach makes my toes
curl.
Quoted 7 lines · Andrew Morton
Quoted 4 lines · On Mon, 23 Jan 2012 13:21:15 -0800 Kees Cook <[email protected]> wrote:
Add the "
proc_pid_mem" sysctl to control whether or not/proc/pid/memis allowed to work: 0: disabled, 1: read only, 2: read/write (default).
Quoted 8 lines
Quoted 5 lines
Signed-off-by Kees Cook <[email protected]>---
v3:
- document the default, thanks to Randy Dunlap.
- remove needlessCONFIG_PROC_FSchecks, thanks to Eric W. Biederman.I was wondering about that. Is
CONFIG_PROC_FS=n,CONFIG_SYSCTL=yan impossible combination? If so, why?
Fundamentally because the only way sysctls get to usespace is threw /proc/sys/. The binary sysctl emulation layer reads /proc/sys through the internal kernel mount.
As I recall the symbol define tree:CONFIG_PROC_SYSCTL select CONFIG_SYSCTL CONFIG_PROC_SYSCTL depends on CONFIG_PROC_FS.
And the only way CONFIG_SYSCTL gets set is if it is select.
If anyone cares enough we can probably cleanup the Kconfig bits to have fewer symbols.
At a practical level I think the real reason I objected is that it is ugly to just dump things into kernel/sysctl.c with #defines everywhere.
Eric
Quoted 50 lines
Quoted 17 lines
Documentation/sysctl/kernel.txt +4
-0@@ -56,6 +56,7 @@ show up in /proc/sys/kernel: - printk_delay - printk_ratelimit - printk_ratelimit_burst +- proc_pid_mem - randomize_va_space - real-root-dev ==> Documentation/initrd.txt - reboot-cmd [ SPARC only ]@@ -477,6 +478,20 @@ send before ratelimiting kicks in. ============================================================== +proc_pid_mem: + +This option can be used to select the level of access given to potentialDocumentation/sysctl/kernel.txt send before ratelimiting kicks in. · line 493
Quoted 10 lines
Documentation/sysctl/kernel.txt +10
-0+ptracers when using the per-process "mem" file in /proc/pid/mem. + +0 - Disable entirely. + +1 - Allow potential ptracers read access to process memory, but not writes. + +2 - Allow potential ptracers read and write access to process memory. This + is the default. + +==============================================================I agree with Colin on this (he stole my line!).
Overall, the patch looks really hacky and random. I felt the same way as Vasily: it's easy to see how a significant number of similar (and hacky and random) patches could be added, resulting in a regrettable mess.
Is there some better designed, more organized way of approaching all of this? Random ideas:
- A parallel /procfs-perms filesystem. You write a number into /procfs-perms/stat to affect access to
/proc/stat(although why the heck not just run `chmod/proc/stat'?) It's unclear how to handle/proc/pid/. Perhaps literally have a /procfs-perms/pid/ directory.- Make tasks inherit their
/proc/pid/*permissions across fork, do a chmod/proc/1/whateverin initscripts.- Other and better things ;) This particular approach makes my toes
curl.
Quoted 12 lines · Andrew Morton
Quoted 2 lines · On Mon, 23 Jan 2012 13:21:15 -0800 Kees Cook <[email protected]> wrote:
Add the "
proc_pid_mem" sysctl to control whether or not/proc/pid/memis allowed to work: 0: disabled, 1: read only, 2: read/write (default).I agree with Colin on this (he stole my line!).
Overall, the patch looks really hacky and random. I felt the same way as Vasily: it's easy to see how a significant number of similar (and hacky and random) patches could be added, resulting in a regrettable mess.
Quoted 7 lines
Is there some better designed, more organized way of approaching all of this? Random ideas:
- A parallel /procfs-perms filesystem. You write a number into /procfs-perms/stat to affect access to
/proc/stat(although why the heck not just run `chmod/proc/stat'?) It's unclear how to handle/proc/pid/. Perhaps literally have a /procfs-perms/pid/ directory.
This seems like too much overhead to me.
Quoted 2 lines
- Make tasks inherit their
/proc/pid/*permissions across fork, do a chmod/proc/1/whateverin initscripts.
This is actually pretty interesting. I think as long as it only allowed the _reduction_ of access. I don't want a process to open up access, just restrict it further. It does make me wonder what the side-effects would be, though. Dropping user r/w perms to things for non-DAC_OVERRIDE processes would be ... weird.
-Kees
Signature · 2 lines
Kees Cook ChromeOS Security