Realtime LSM
Subsystems (3)
PATCH 1/1 Realtime LSM
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications. The typical use for this is low latency audio, and the patch has been extensively field tested by Linux audio users. The realtime LSM is a major improvement in security over the 2.4 capablities patch and other workarounds like jackstart, which rely on CAP_SETPCAP.
Lee
Documentation/realtime-lsm.txt +47 -0
@@ -0,0 +1,47 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + + # modprobe realtime allcaps=1 + + Enables all capabilities, including CAP_SETPCAP. This is equivalent + to the 2.4 kernel capabilities patch. It is needed for root + programs to assign realtime capabilities to other processes. This + option can be used in conjunction with any of the other options. + + The JACK Audio Connection Kit (jackit.sourceforge.net) includes a + `jackstart' program which uses CAP_SETPCAP to run the JACK daemon + and its clients with realtime capabilities. + + There are serious security exposures with CAP_SETPCAP. If an + attacker manages to subvert some system daemon running with root + privileges, it can use this capability to deny needed privileges to + other root processes. + +Jack O'Quin, [email protected]
security/Kconfig +14 -0
@@ -44,6 +44,20 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense. + + This module selectively grants realtime privileges + controlled by load-time parameters. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu
security/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c +226 -0
226 lines not on this page · raw message
security/Kconfig line 54
Quoted 8 lines · Lee Revell
security/Kconfig +8
-0+config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense.
Why not just make it a bool then?
I wonder if it might be better to specify configuration via /proc/<pid>/attr rather than module parameters.
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 1 line · James Morris
Why not just make it a bool then?
Ignore that, I read the comment incorrectly.
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 13 lines · James Morris
security/Kconfig line 54
Quoted 8 lines · Lee Revell
security/Kconfig +8
-0+config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense.Why not just make it a bool then?
Good idea.
Quoted 3 lines
I wonder if it might be better to specify configuration via /proc/<pid>/attr rather than module parameters.
This would not work for several reasons. How would you decide who is allowed to run RT processes? Root would have to set the above value, which defeats the purpose of the realtime-lsm module which is to selectively allow non-root users to run RT tasks.
Here is a good summary of the security issues that have been raised:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=269661
Realtime-lsm solves all of these problems.
Lee
Quoted 2 lines · James Morris
I wonder if it might be better to specify configuration via /proc/<pid>/attr rather than module parameters.
We discussed configuration via /proc, and it seems worthwhile.
Maybe I don't understand the details of what you propose. I don't find the /proc/<pid> approach attractive because it seems difficult to administer. But, setting something global like /proc/realtime/group or /proc/realtime/any would make a good enhancement to the current interface.
I have not implemented that yet because (1) the current approach has proven adequate for the Linux audio user community, and (2) I haven't wanted to spend time mastering the internal kernel interfaces for accessing /proc from an LSM. I know it's not difficult, but I had other things I'd rather do. :-)
Thanks for the suggestion,
Signature · 1 line
joq
Quoted 5 lines · Jack O'Quin
I have not implemented that yet because (1) the current approach has proven adequate for the Linux audio user community, and (2) I haven't wanted to spend time mastering the internal kernel interfaces for accessing /proc from an LSM. I know it's not difficult, but I had other things I'd rather do. :-)
Here's a patch based on the one posted in <[email protected]> that adds a sysctl (/proc/sys) interface. These sysctls don't seem to fit into any of the existing groups, so I added CTL_SECURITY (/proc/sys/security).
Example:
# modprobe realtime # echo 29 > /proc/sys/security/realtime/gid
Documentation/realtime-lsm.txt new file +47 -0
@@ -0,0 +1,47 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + + # modprobe realtime allcaps=1 + + Enables all capabilities, including CAP_SETPCAP. This is equivalent + to the 2.4 kernel capabilities patch. It is needed for root + programs to assign realtime capabilities to other processes. This + option can be used in conjunction with any of the other options. + + The JACK Audio Connection Kit (jackit.sourceforge.net) includes a + `jackstart' program which uses CAP_SETPCAP to run the JACK daemon + and its clients with realtime capabilities. + + There are serious security exposures with CAP_SETPCAP. If an + attacker manages to subvert some system daemon running with root + privileges, it can use this capability to deny needed privileges to + other root processes. + +Jack O'Quin, [email protected]
security/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_SECURITY) += security.o d obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c new file +283 -0
283 lines not on this page · raw message
include/linux/sysctl.h +8 -1
@@ -61,7 +61,14 @@ enumCTL_DEV =7 ,/* Devices */ CTL_BUS =8 ,/* Busses */ CTL_ABI =9 ,/* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ +SECURITY_REALTIME =1 /* Realtime LSM */ };/* CTL_BUS names: */
security/Kconfig +14 -0
@@ -44,6 +44,20 @@ config SECURITY_ROOTPLUG If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense. + + This module selectively grants realtime privileges + controlled by load-time parameters. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu
Quoted 13 lines · Jody McIntyre
Quoted 5 lines · Jack O'Quin
I have not implemented that yet because (1) the current approach has proven adequate for the Linux audio user community, and (2) I haven't wanted to spend time mastering the internal kernel interfaces for accessing /proc from an LSM. I know it's not difficult, but I had other things I'd rather do. :-)
Here's a patch based on the one posted in <[email protected]> that adds a sysctl (
/proc/sys) interface. These sysctls don't seem to fit into any of the existing groups, so I addedCTL_SECURITY(/proc/sys/security).
Quoted 4 lines
Example:
# modprobe realtime # echo 29 > /proc/sys/security/realtime/gid
Thanks! That's even cleaner than I had realized. I like it.
What are the serialization issues with variable updates via /proc? I presume they can change at any time, even while the LSM is running on some other processor. If so, I'll need to be careful to fetch each variable only once and use that value for the entire capability computation, right? That should be straightforward.
The only LSM option that doesn't fit this model is `allcaps', which only functions at initialization time (by adding CAP_SETPCAP to the capability bounds). My initial thought is that we probably don't want that to change via /proc, so just leave it out of the sysctl list.
But, perhaps we should consider removing this option entirely. It is the only one with a potentially serious security exposure. The others at worst allow Denial of Service attacks.
`Allcaps' is there for compatibility with 2.4 kernels with the so- called "capabilities patch". Many Linux audio users run that way so they can use the JACK Audio Connection Kit without being root. With allcaps' the same methods work with either kernel. This is not strictly necessary, because the Realtime LSM provides the required capabilities without allcaps'. But, it is convenient for people like me who maintain programs on both kernel versions and frequently switch back and forth for testing purposes.
Because 2.4 with the low-latency patches provides outstanding realtime performance, many serious audio users have not yet moved to 2.6. With the excellent results recently reported with 2.6 patched for low latency, that may soon change (especially when some of these patches have been integrated into the mainline kernel).
Since the long-term need for allcaps' is unclear, maybe it should be enabled by a separate experimental' Kconfig option accompanied with appropriate security warnings. Eventually, we might want to phase it out entirely.
Signature · 1 line
joq
Quoted 5 lines · Jack O'Quin
What are the serialization issues with variable updates via /proc? I presume they can change at any time, even while the LSM is running on some other processor. If so, I'll need to be careful to fetch each variable only once and use that value for the entire capability computation, right? That should be straightforward.
It doesn't matter. There's no added security risk if gid changes halfway through the permission check, and the other variables are used only once. It's probably cleaner to check the gid in a separate function though.
However, I just noticed something interesting:
If "any" and "gid" is set, any is ignored and only the gid check is effective. This is counter to the documentation, so I assume it is a bug.
So I made gid checking a separate function and fixed the any+gid bug. See patch.
Quoted 4 lines
The only LSM option that doesn't fit this model is `allcaps', which only functions at initialization time (by adding
CAP_SETPCAPto the capability bounds). My initial thought is that we probably don't want that to change via /proc, so just leave it out of the sysctl list.
You're right. Sorry I missed that. The patch below removes the (useless) sysctl for allcaps.
I also added the sysctl interface to the documentation.
Quoted 5 lines
But, perhaps we should consider removing this option entirely. It is the only one with a potentially serious security exposure. The others at worst allow Denial of Service attacks.
[...]
I hate allcaps too. Maybe you should just use a shell script wrapper like (untested):
----
if echo uname -r |grep '^2\.4\.' ; then
jackstart $@
else
jackd $@
fi
----
Anyway, here's the patch:
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications. The typical use for this is low latency audio, and the patch has been extensively field tested by Linux audio users. The realtime LSM is a major improvement in security over the 2.4 capablities patch and other workarounds like jackstart, which rely on CAP_SETPCAP.
Documentation/realtime-lsm.txt new file +50 -0
@@ -0,0 +1,50 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + + # modprobe realtime allcaps=1 + + Enables all capabilities, including CAP_SETPCAP. This is equivalent + to the 2.4 kernel capabilities patch. It is needed for root + programs to assign realtime capabilities to other processes. This + option can be used in conjunction with any of the other options. + + The JACK Audio Connection Kit (jackit.sourceforge.net) includes a + `jackstart' program which uses CAP_SETPCAP to run the JACK daemon + and its clients with realtime capabilities. + + There are serious security exposures with CAP_SETPCAP. If an + attacker manages to subvert some system daemon running with root + privileges, it can use this capability to deny needed privileges to + other root processes. + +All parameters apart from allcaps can also be changed dynamically via +the entries in /proc/sys/security/realtime. + +Jack O'Quin, [email protected]
security/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_SECURITY) += security.o d obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c new file +274 -0
274 lines not on this page · raw message
include/linux/sysctl.h +8 -1
@@ -61,7 +61,14 @@ enumCTL_DEV =7 ,/* Devices */ CTL_BUS =8 ,/* Busses */ CTL_ABI =9 ,/* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ +SECURITY_REALTIME =1 /* Realtime LSM */ };/* CTL_BUS names: */
security/Kconfig +15 -0
@@ -44,6 +44,21 @@ config SECURITY_ROOTPLUG If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense. + + This module selectively grants realtime privileges + controlled by load-time parameters and + /proc/sys/security/realtime. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu
Quoted 8 lines · Jody McIntyre
Quoted 5 lines · Jack O'Quin
What are the serialization issues with variable updates via /proc? I presume they can change at any time, even while the LSM is running on some other processor. If so, I'll need to be careful to fetch each variable only once and use that value for the entire capability computation, right? That should be straightforward.
Quoted 4 lines
It doesn't matter. There's no added security risk if gid changes halfway through the permission check, and the other variables are used only once. It's probably cleaner to check the gid in a separate function though.
Agreed.
One could probably get a false negative, but it's hard to imagine a sensible usage example. I just like to be tidy any time concurrency issues arise.
Quoted 5 lines
However, I just noticed something interesting:
If "any" and "gid" is set, any is ignored and only the gid check is effective. This is counter to the documentation, so I assume it is a bug.
Quite right, good eye. :-)
I must not have tested that combination. :-(
Quoted 1 line
I also added the sysctl interface to the documentation.
Good. I thought about that, too.
Quoted 7 lines
Quoted 3 lines
But, perhaps we should consider removing this option entirely. It is the only one with a potentially serious security exposure. The others at worst allow Denial of Service attacks.
I hate allcaps too. Maybe you should just use a shell script wrapper like (untested):
Quoted 7 lines
----
if echo uname -r |grep '^2\.4\.' ; then
jackstart $@
else
jackd $@
fi
----
I am willing to do that if the kernel developers think it better.
It recently occurred to me that jackstart might be able to detect this situation and exec jackd, anyway. (AFAICT, the only reasonably POSIX-compliant method for detecting that a process has the "appropriate permission" to do something is trying it to see whether it returns EPERM.)
Thanks for helping...
Signature · 1 line
joq
Quoted 8 lines · Jack O'Quin
I am willing to do that if the kernel developers think it better.
It recently occurred to me that jackstart might be able to detect this situation and exec jackd, anyway. (AFAICT, the only reasonably POSIX-compliant method for detecting that a process has the "appropriate permission" to do something is trying it to see whether it returns EPERM.)
how should jackstart detect the situation ? its running SUID root and is allowed to do everything.
Quoted 5 lines
Thanks for helping...
Signature · 1 line
joq
Signature · 2 lines
torben Hohn http://galan.sourceforge.net -- The graphical Audio language
Quoted 9 lines · [email protected] writes:
Quoted 5 lines · Jack O'Quin
It recently occurred to me that jackstart might be able to detect this situation and exec jackd, anyway. (AFAICT, the only reasonably POSIX-compliant method for detecting that a process has the "appropriate permission" to do something is trying it to see whether it returns EPERM.)
how should jackstart detect the situation ? its running SUID root and is allowed to do everything.
I was thinking that it could drop root privileges and try creating a realtime thread. But, then I realied it would be better (and simpler) for jackstart' to exec jackd' unconditionally, even when the required capabilities are not available. Let `jackd' figure out for itself what it can actually do.
That is what I meant about trying the operation being the only reliable test. Jackstart should not give up just because one privilege mechanism is unavailable. It cannot know all the possible reasons why jackd might or might not have access to realtime resources. Its job is simply to pass the capabilities if they are available.
Signature · 1 line
joq
Quoted 5 lines · Jack O'Quin
I was thinking that it could drop root privileges and try creating a realtime thread. But, then I realied it would be better (and simpler) for
jackstart' to execjackd' unconditionally, even when the required capabilities are not available. Let `jackd' figure out for itself what it can actually do.
I agree. jackstart should always call jackd. I ran into a similar problem a few weeks ago when I gave a demo on my laptop and didn't have time to patch my kernel. I wasn't doing any serious recording so I thought I'd run without -R. Of course, that didn't work until I changed qjackctl to use 'jackd' as a command rather than 'jackstart'. This could be a serious problem for a less experienced user.
Jody
Quoted 8 lines
That is what I meant about trying the operation being the only reliable test. Jackstart should not give up just because one privilege mechanism is unavailable. It cannot know all the possible reasons why jackd might or might not have access to realtime resources. Its job is simply to pass the capabilities if they are available.
Signature · 1 line
joq
Lee Revell <[email protected]> ha scritto:
Quoted 3 lines
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications.
Hi,
just a couple of comments:
Quoted 3 lines
diff -ruN -X
/home/joq/bin/kdiff.excludelinux-2.6.8.1/security/realtime.clinux-2.6.8.1-rt/security/realtime.csecurity/realtime.c Fri Sep 10 11:09:09 2004 renamed from security/realtime.c Wed Dec 31 18:00:00 1969 +0
-0
[...]
Quoted 7 lines
security/realtime.c Fri Sep 10 11:09:09 2004 renamed from security/realtime.c Wed Dec 31 18:00:00 1969 +7
-0+#ifdef NGROUPS_SMALL /* using new groups struct? */ + get_group_info(current->group_info); + for (i = 0; i < current->group_info->ngroups; ++i) { + if (gid == GROUP_AT(current->group_info, i)) { + rt_ok = 1; + break; + }
security/realtime.c Fri Sep 10 11:09:09 2004
Quoted 10 lines
security/realtime.c Fri Sep 10 11:09:09 2004 renamed from security/realtime.c Wed Dec 31 18:00:00 1969 +10
-0+ } + put_group_info(current->group_info); +#else /* old task struct */ + for (i = 0; i < NGROUPS; ++i) { + if (gid == current->groups[i]) { + rt_ok = 1; + break; + } + } +#endif /* NGROUPS_SMALL */
Since you are targeting linux 2.6.9 this ifdef can go away.
security/realtime.c Fri Sep 10 11:09:09 2004
Quoted 5 lines
security/realtime.c Fri Sep 10 11:09:09 2004 renamed from security/realtime.c Wed Dec 31 18:00:00 1969 +5
-0+#ifdef LSM_UNSAFE_SHARE /* version >= 2.6.6 */ + .bprm_apply_creds = cap_bprm_apply_creds, +#else + .bprm_compute_creds = cap_bprm_compute_creds, +#endif
Same here.
Quoted 1 line
+#define
MY_NAMETHIS_MODULE->name
This is ugly :P
Luca
Signature · 5 lines
Home: http://kronoz.cjb.net Se alla sera, dopo una strepitosa vittoria, guardandoti allo specchio dovessi notare un secondo paio di palle, che il tuo cuore non si riempia d'orgoglio, perche` vuol dire che ti stanno inculando -- Saggio Cinese
Quoted 8 lines · Kronos
Lee Revell <[email protected]> ha scritto:
Quoted 3 lines
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications.
Hi,
just a couple of comments:
OK, here's a cleaned up patch with the ifdefs removed and MY_NAME define'd as __stringify(KBUILD_MODNAME).
Lee
---
Documentation/realtime-lsm.txt +47 -0
@@ -0,0 +1,47 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + + # modprobe realtime allcaps=1 + + Enables all capabilities, including CAP_SETPCAP. This is equivalent + to the 2.4 kernel capabilities patch. It is needed for root + programs to assign realtime capabilities to other processes. This + option can be used in conjunction with any of the other options. + + The JACK Audio Connection Kit (jackit.sourceforge.net) includes a + `jackstart' program which uses CAP_SETPCAP to run the JACK daemon + and its clients with realtime capabilities. + + There are serious security exposures with CAP_SETPCAP. If an + attacker manages to subvert some system daemon running with root + privileges, it can use this capability to deny needed privileges to + other root processes. + +Jack O'Quin, [email protected]
security/Kconfig +14 -0
@@ -44,6 +44,20 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense. + + This module selectively grants realtime privileges + controlled by load-time parameters. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu
security/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c +206 -0
206 lines not on this page · raw message
Quoted 16 lines · * Lee Revell ([email protected]) wrote:
Documentation/realtime-lsm.txt +16
-0+Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. + + # modprobe realtime mlock=0 +
Documentation/realtime-lsm.txt line 36
Quoted 10 lines
Documentation/realtime-lsm.txt +10
-0+ Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + + # modprobe realtime allcaps=1 + + Enables all capabilities, including CAP_SETPCAP. This is equivalent + to the 2.4 kernel capabilities patch. It is needed for root + programs to assign realtime capabilities to other processes. This + option can be used in conjunction with any of the other options.
The mlock() bit is unecessary now. Use rlimits on the audio users. Which leaves realtime bits, plus others. I had a more generic module (per-capability) that would be a superset of this. Perhaps that's a better fit. I'm travelling this week, so forgive the spotty replies.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 12 lines · Chris Wright
Documentation/realtime-lsm.txt line 30
Quoted 6 lines · * Lee Revell ([email protected]) wrote:
Documentation/realtime-lsm.txt +6
-0+ # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. +The
mlock()bit is unecessary now. Use rlimits on the audio users. Which leaves realtime bits, plus others. I had a more generic module (per-capability) that would be a superset of this. Perhaps that's a better fit. I'm travelling this week, so forgive the spotty replies.
I think this would be fine. All we need is a way to allow users to run SCHED_FIFO processes and use mlockall() without being root and without having to patch the kernel. It's a pretty simple requirement.
Lee
Quoted 4 lines · Chris Wright
Quoted 4 lines
The
mlock()bit is unecessary now. Use rlimits on the audio users. Which leaves realtime bits, plus others. I had a more generic module (per-capability) that would be a superset of this. Perhaps that's a better fit. I'm travelling this week, so forgive the spotty replies.
Quoted 3 lines · Lee Revell
I think this would be fine. All we need is a way to allow users to run
SCHED_FIFOprocesses and usemlockall()without being root and without having to patch the kernel. It's a pretty simple requirement.
Please construct a entitlement/permission checking scheme for this that is not so lax as removing permissions checks altogether conditionally on some sysctl.
-- wli
Quoted 6 lines · William Lee Irwin III
Quoted 4 lines · Chris Wright
Quoted 4 lines
The
mlock()bit is unecessary now. Use rlimits on the audio users. Which leaves realtime bits, plus others. I had a more generic module (per-capability) that would be a superset of this. Perhaps that's a better fit. I'm travelling this week, so forgive the spotty replies.
Quoted 8 lines
Quoted 3 lines · Lee Revell
I think this would be fine. All we need is a way to allow users to run
SCHED_FIFOprocesses and usemlockall()without being root and without having to patch the kernel. It's a pretty simple requirement.Please construct a entitlement/permission checking scheme for this that is not so lax as removing permissions checks altogether conditionally on some sysctl.
This is how it works now. You would typically do 'modprobe realtime gid=29' and add audio users to that group. How is this any less secure than the traditional user/group/other permissions model?
Lee
Quoted 3 lines · William Lee Irwin III
Quoted 3 lines
Please construct a entitlement/permission checking scheme for this that is not so lax as removing permissions checks altogether conditionally on some sysctl.
Quoted 3 lines · Lee Revell
This is how it works now. You would typically do 'modprobe realtime gid=29' and add audio users to that group. How is this any less secure than the traditional user/group/other permissions model?
I have no issue with uid/gid checks, thanks for clarifying.
-- wli
security/Kconfig line 54
Quoted 3 lines · Lee Revell
security/Kconfig +3
-0+ Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense.
Why does this make no sense?
I tried answering Y and it oopsed on boot. I'll try and track down/fix what is happening later.
Jody
Quoted 7 lines · Jody McIntyre
security/Kconfig line 54
Quoted 3 lines · Lee Revell
security/Kconfig +3
-0+ Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense.Why does this make no sense?
Before your /proc enhancement, it made no sense because there was no way to set parameters. By default, the LSM does nothing. We should change that comment now (as soon as it's working).
Quoted 2 lines
I tried answering Y and it oopsed on boot. I'll try and track down/fix what is happening later.
Long ago, I built and ran it linked into the kernel (with different parameter defaults), which worked at the time. It may matter how some of the other security modules are configured. Perhaps some additional Kconfig dependency checking would help. I'm not an expert at that.
Signature · 1 line
joq
Quoted 10 lines · Jack O'Quin
Quoted 7 lines · Jody McIntyre
security/Kconfig line 54
Quoted 3 lines · Lee Revell
security/Kconfig +3
-0+ Answer M to build realtime support as a Linux Security + Module. Answering Y to build realtime capabilities into the + kernel makes no sense.Why does this make no sense?
Quoted 3 lines
Before your /proc enhancement, it made no sense because there was no way to set parameters. By default, the LSM does nothing. We should change that comment now (as soon as it's working).
one can pass paremeters to the kernel on boot.
i think that the parameters get to the module somehow.
(the parameter stuff is handled by magic macros, which should now what to do when not built as a module.
Quoted 8 lines
Quoted 3 lines
I tried answering Y and it oopsed on boot. I'll try and track down/fix what is happening later.
Long ago, I built and ran it linked into the kernel (with different parameter defaults), which worked at the time. It may matter how some of the other security modules are configured. Perhaps some additional
Kconfigdependency checking would help. I'm not an expert at that.
i think jody will fix it.
Quoted 3 lines
Signature · 1 line
joq
Signature · 2 lines
torben Hohn http://galan.sourceforge.net -- The graphical Audio language
I fixed the oops on boot by changing security_initcall() to late_initcall(). This moves initialization of the module to after /proc and sysctl is setup.
This patch still includes allcaps, which should be removed before it is merged.
The patch is now against 2.6.9-pre2-mm4.
Jody
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications. The typical use for this is low latency audio, and the patch has been extensively field tested by Linux audio users. The realtime LSM is a major improvement in security over the 2.4 capablities patch and other workarounds like jackstart, which rely on CAP_SETPCAP.
Documentation/realtime-lsm.txt new file +50 -0
@@ -0,0 +1,50 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + + # modprobe realtime allcaps=1 + + Enables all capabilities, including CAP_SETPCAP. This is equivalent + to the 2.4 kernel capabilities patch. It is needed for root + programs to assign realtime capabilities to other processes. This + option can be used in conjunction with any of the other options. + + The JACK Audio Connection Kit (jackit.sourceforge.net) includes a + `jackstart' program which uses CAP_SETPCAP to run the JACK daemon + and its clients with realtime capabilities. + + There are serious security exposures with CAP_SETPCAP. If an + attacker manages to subvert some system daemon running with root + privileges, it can use this capability to deny needed privileges to + other root processes. + +All parameters except allcaps can be changed dynamically via the entries in +/proc/sys/security/realtime. + +Jack O'Quin, [email protected]
security/Makefile +1 -0
@@ -16,3 +16,4 @@ obj-$(CONFIG_SECURITY) += security.o d obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c new file +274 -0
274 lines not on this page · raw message
include/linux/sysctl.h +8 -1
@@ -61,7 +61,14 @@ enumCTL_DEV =7 ,/* Devices */ CTL_BUS =8 ,/* Busses */ CTL_ABI =9 ,/* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ +SECURITY_REALTIME =1 /* Realtime LSM */ };/* CTL_BUS names: */
security/Kconfig +11 -0
@@ -73,6 +73,17 @@ config SECURITY_ROOTPLUG If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + This module selectively grants realtime privileges + controlled by load-time parameters and + /proc/sys/security/realtime. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu
Quoted 6 lines · Jody McIntyre
I fixed the oops on boot by changing
security_initcall()tolate_initcall(). This moves initialization of the module to after /proc and sysctl is setup.This patch still includes allcaps, which should be removed before it is merged.
Another issue that was raised was that the mlock stuff is also unnecessary, because rlimits can do this now. Is this the case?
Lee
Quoted 2 lines · Lee Revell
Another issue that was raised was that the mlock stuff is also unnecessary, because rlimits can do this now. Is this the case?
I don't know. The idea was not explained in enough detail for me to understand if it would be simple enough to administer. Where can I find out more?
Does this somehow explain the need for CAP_SYS_RESOURCE when calling mlockall()? Comments in capability.h seem to imply that only CAP_IPC_LOCK is required, which is not true. I never found any explicit CAP_SYS_RESOURCE test in mm/mlock.c, though it does check `rlim[RLIMIT_MEMLOCK].rlim_cur'.
Signature · 1 line
joq
Quoted 8 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 2 lines · Lee Revell
Another issue that was raised was that the mlock stuff is also unnecessary, because rlimits can do this now. Is this the case?
I don't know. The idea was not explained in enough detail for me to understand if it would be simple enough to administer. Where can I find out more?
This uses the basic rlimits infrastructure. You can manage it manually in a shell with ulimit -l, or you can use pam (pam_limits) to configure per uid limits. There's a pam doc that describes limits, and a manpage for ulimit. It's really easy to use, and should eliminate the need for the mlock part of that module.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 5 lines · Chris Wright
This uses the basic rlimits infrastructure. You can manage it manually in a shell with ulimit -l, or you can use pam (
pam_limits) to configure per uid limits. There's a pam doc that describes limits, and a manpage for ulimit. It's really easy to use, and should eliminate the need for the mlock part of that module.
Thanks for the pointer, Chris.
I'll see if I can figure out a way to make that useable for musicians.
The ulimit approach is way too cumbersome.
The pam_limits solution is not well-documented on my Debian system, which doesn't even have a man page for /etc/security/limits.conf, though the file has comments, now that I know where to look. PAM is powerful and flexible, but "easy to use" is not a phrase that comes readily to mind. :-)
The PAM approach would probably be workable for special-purpose audio distributions like Planet CCRMA or DeMuDi. That still leaves all the audio developers with a significant challenge trying to explain every configuration step to all our other users. AFAICT, PAM configuration is rather distribution-specific, so that could become a significant burden.
It appears that a limits.conf line like this might work...
@audio - memlock 10000 # is there any way to say "unlimited"?
I'll experiment tomorrow to see if I can actually make this work.
Signature · 1 line
joq
Quoted 8 lines · Jack O'Quin
Quoted 5 lines · Chris Wright
This uses the basic rlimits infrastructure. You can manage it manually in a shell with ulimit -l, or you can use pam (
pam_limits) to configure per uid limits. There's a pam doc that describes limits, and a manpage for ulimit. It's really easy to use, and should eliminate the need for the mlock part of that module.
Quoted 5 lines
Thanks for the pointer, Chris.
I'll see if I can figure out a way to make that useable for musicians.
The ulimit approach is way too cumbersome.
Agreed. The whole point of getting realtime-lsm in the kernel is to make it _easier_ to get a linux audio (or other realtime system) up and running. Would it be feasible to use rlimits to let users run SCHED_FIFO processes? The ulimit approach would probably be acceptable if it subsumed all the functionality of the realtime-lsm module.
Lee
Quoted 6 lines · * Lee Revell ([email protected]) wrote:
Quoted 1 line · Jack O'Quin
The ulimit approach is way too cumbersome.
Agreed. The whole point of getting realtime-lsm in the kernel is to make it _easier_ to get a linux audio (or other realtime system) up and running.
It's nice to have something that's easy to use, but that's not a great justification for addition to the kernel. Esp. when there's a functional userspace solution.
Quoted 2 lines
Would it be feasible to use rlimits to let users run
SCHED_FIFOprocesses?
No, it doesn't support that. I suppose it could, whether is should is another matter.
Quoted 2 lines
The ulimit approach would probably be acceptable
if it subsumed all the functionality of the realtime-lsm module.
Hrm, I guess we'll have to agree to disagree. The whole point of the mlock rlimits code is to enable this policy to be pushed to userspace. A generic method of enabling capabilities is the best way to go, long term. Any interest in pursuing that?
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 4 lines · Chris Wright
Quoted 3 lines · * Lee Revell ([email protected]) wrote:
Quoted 1 line · Jack O'Quin
The ulimit approach is way too cumbersome.
Quoted 8 lines
Quoted 3 lines
Agreed. The whole point of getting realtime-lsm in the kernel is to make it _easier_ to get a linux audio (or other realtime system) up and running.
It's nice to have something that's easy to use, but that's not a great justification for addition to the kernel. Esp. when there's a functional userspace solution.
OK, poor choice of words. Correctness of course comes before ease of use. I believe the realtime-lsm module satisfies both requirements.
Quoted 7 lines
Quoted 2 lines
The ulimit approach would probably be acceptable
if it subsumed all the functionality of the realtime-lsm module.Hrm, I guess we'll have to agree to disagree. The whole point of the mlock rlimits code is to enable this policy to be pushed to userspace. A generic method of enabling capabilities is the best way to go, long term. Any interest in pursuing that?
I did not mean to imply that I disagree with the realtime-lsm approach. Obviously some kernel support is required, and realtime-lsm seems to solve the problem with the minimum possible change to the kernel. And above all it is a proven working solution that has been field tested for months by many, many users.
Lee
Quoted 7 lines · * Lee Revell ([email protected]) wrote:
Quoted 3 lines · Chris Wright
It's nice to have something that's easy to use, but that's not a great justification for addition to the kernel. Esp. when there's a functional userspace solution.
OK, poor choice of words. Correctness of course comes before ease of use. I believe the realtime-lsm module satisfies both requirements.
I agree with that. That's not my objection. It's about pushing code (albeit it's small and non-invasive) into the kernel that can be done in userspace, that's all.
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
The ulimit approach would probably be acceptable
if it subsumed all the functionality of the realtime-lsm module.Hrm, I guess we'll have to agree to disagree. The whole point of the mlock rlimits code is to enable this policy to be pushed to userspace. A generic method of enabling capabilities is the best way to go, long term. Any interest in pursuing that?
Quoted 5 lines
I did not mean to imply that I disagree with the realtime-lsm approach. Obviously some kernel support is required, and realtime-lsm seems to solve the problem with the minimum possible change to the kernel. And above all it is a proven working solution that has been field tested for months by many, many users.
Clearly it's useful for the audio folks. Whether it's the right thing to go into the kernel is all that's in question here. Do we agree it's a stopgap measure making up for lack of a better general solution?
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 6 lines · Chris Wright
Quoted 5 lines · * Lee Revell ([email protected]) wrote:
Quoted 3 lines · Chris Wright
It's nice to have something that's easy to use, but that's not a great justification for addition to the kernel. Esp. when there's a functional userspace solution.
Quoted 7 lines
Quoted 2 lines
OK, poor choice of words. Correctness of course comes before ease of use. I believe the realtime-lsm module satisfies both requirements.
I agree with that. That's not my objection. It's about pushing code (albeit it's small and non-invasive) into the kernel that can be done in userspace, that's all.
How do you envision this working? I am sure it's possible, I think I am just not seeing how it would be different in practice.
Quoted 14 lines
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
The ulimit approach would probably be acceptable
if it subsumed all the functionality of the realtime-lsm module.Hrm, I guess we'll have to agree to disagree. The whole point of the mlock rlimits code is to enable this policy to be pushed to userspace. A generic method of enabling capabilities is the best way to go, long term. Any interest in pursuing that?
Quoted 5 lines
I did not mean to imply that I disagree with the realtime-lsm approach. Obviously some kernel support is required, and realtime-lsm seems to solve the problem with the minimum possible change to the kernel. And above all it is a proven working solution that has been field tested for months by many, many users.
Quoted 4 lines
Clearly it's useful for the audio folks. Whether it's the right thing to go into the kernel is all that's in question here. Do we agree it's a stopgap measure making up for lack of a better general solution?
See above, no argument here from me.
Lee
Quoted 7 lines · * Lee Revell ([email protected]) wrote:
Quoted 3 lines · Chris Wright
I agree with that. That's not my objection. It's about pushing code (albeit it's small and non-invasive) into the kernel that can be done in userspace, that's all.
How do you envision this working? I am sure it's possible, I think I am just not seeing how it would be different in practice.
As of now, the only practical part to move out is just that tiny mlock bit. Using pam_limits seems the best choice there. This burdens the audio folks with a documentation task (describing not only how to turn this rlimits feature on properly, although that'd be welcome since the docs in that area are lacking, but also doc for the module
re: SCHED_FIFO). A general solution is pam_cap, and making capabilities inherit in a sane way (Andy L. and I have code to move in that direction). One step shy of that, is extend what you've done across the capability set, so that it could solve problems similar to yours but with different cap requirements. Pushing more bits into rlimits is possible as well, but could get unruly.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 12 lines · Chris Wright
Quoted 2 lines · * Lee Revell ([email protected]) wrote:
OK, poor choice of words. Correctness of course comes before ease of use. I believe the realtime-lsm module satisfies both requirements.
I agree with that. That's not my objection. It's about pushing code (albeit it's small and non-invasive) into the kernel that can be done in userspace, that's all.
Quoted 4 lines
Quoted 4 lines
Hrm, I guess we'll have to agree to disagree. The whole point of the mlock rlimits code is to enable this policy to be pushed to userspace. A generic method of enabling capabilities is the best way to go, long term. Any interest in pursuing that?
None here. I prefer to spend my time on audio development than kernel code. There are plenty of good kernel developers already.
I agree that a generic capabilities module would be nice to have, mainly because of current difficulties with stacking multiple LSM's. However, if there were a good stacking facility, then multiple, simple, application-oriented modules like the realtime-lsm might be even better in some respects.
Quoted 9 lines
Quoted 5 lines
I did not mean to imply that I disagree with the realtime-lsm approach. Obviously some kernel support is required, and realtime-lsm seems to solve the problem with the minimum possible change to the kernel. And above all it is a proven working solution that has been field tested for months by many, many users.
Clearly it's useful for the audio folks. Whether it's the right thing to go into the kernel is all that's in question here. Do we agree it's a stopgap measure making up for lack of a better general solution?
Sure, I agree. But, I suspect that gap looks much larger from my perspective than yours. :-)
We would never have developed this LSM had there not been a serious need. Audio developers have been struggling for years with the need to apply specialized kernel patches to get acceptable realtime operation. Audio is very intolerant of realtime glitches. They cause nasty pops in the output. And, large audio applications should not run as `root'. The 2.4 "capabilities patch" was never a satisfactory solution.
Thanks to the good work being done on 2.6, we are now close to being able to do serious realtime work with standard kernels available everwhere. The LSM framework is an important element of that solution, with the realtime LSM a small but essential component, because it makes these features available without excessive administrative burden. Many musicians have a Mac or Windows background. They are not willing to perform complex system administration tasks to get good audio performance. PAM is great for sophisticated sysadmins on shared systems. But, I seriously doubt many musicians will be able to configure it correctly. For a single-user Digital Audio Workstation it is overkill.
So, even if you do provide a more general solution, I will probably have to continue supporting the realtime-lsm interface throughout the 2.6 kernel life-cycle, as there will be enough users for it to be a defacto standard. If it is no longer needed in the 2.8 timeframe, I can drop support then.
It's hard to say how many people use realtime-lsm right now. SourceForge lists about 1500 source downloads over the last six months. Binary copies are included in the most popular audio-oriented distributions, including Planet CCRMA and DeMuDi. I guess there are probably no more than a few thousand active users.
These are already enough that I feel committed to providing whatever module updates are required for all official 2.6 kernel versions. Including the LSM in the kernel would distribute it to more users. It would also simplify maintenance slightly. I currently maintain a single source that works for all 2.6 versions. As a practical matter, I may ignore some of the pre-2.6.6 issues in the next release.
Is that what you meant by stop-gap? :-)
Signature · 1 line
joq
Quoted 6 lines · Jack O'Quin
Thanks to the good work being done on 2.6, we are now close to being able to do serious realtime work with standard kernels available everwhere. The LSM framework is an important element of that solution, with the realtime LSM a small but essential component, because it makes these features available without excessive administrative burden.
Since no one has objected to any of Jack's points, and now that the setpcap is gone, and with more audio users moving to 2.6+mm+VP every day, I would like to ask that this go into -mm. Any objections?
Lee
Quoted 8 lines · Lee Revell
Quoted 6 lines · Jack O'Quin
Thanks to the good work being done on 2.6, we are now close to being able to do serious realtime work with standard kernels available everwhere. The LSM framework is an important element of that solution, with the realtime LSM a small but essential component, because it makes these features available without excessive administrative burden.
Quoted 4 lines
Since no one has objected to any of Jack's points, and now that the setpcap is gone, and with more audio users moving to 2.6+mm+VP every day, I would like to ask that this go into -mm. Any objections?
Oops, I just realized that this has some rejects now with -mm3 due to the addition of the BSD jail LSM. Here's an updated patch, only difference is line numbers.
Lee
Documentation/realtime-lsm.txt +38 -0
@@ -0,0 +1,38 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. A + `gid' of -1 disables group access. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + +Parameters can be changed dynamically via /proc/sys/security/realtime: + + # sysctl -w security/realtime/any=0 + # sysctl -w security/realtime/gid=29 + # sysctl -w security/realtime/mlock=1 + +Jack O'Quin, [email protected]
include/linux/sysctl.h +8 -1
@@ -61,7 +61,14 @@CTL_DEV =7 ,/* Devices */ CTL_BUS =8 ,/* Busses */ CTL_ABI =9 ,/* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ +SECURITY_REALTIME =1 /* Realtime LSM */ };/* CTL_BUS names: */
security/Kconfig +11 -0
@@ -84,6 +84,17 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + This module selectively grants realtime privileges + controlled by load-time parameters and + /proc/sys/security/realtime. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig config SECURITY_BSDJAIL
security/Makefile +1 -0
@@ -18,3 +18,4 @@ obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o obj-$(CONFIG_SECURITY_SECLVL) += seclvl.o obj-$(CONFIG_SECURITY_BSDJAIL) += bsdjail.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c +267 -0
267 lines not on this page · raw message
Quoted 3 lines · Lee Revell
Here's an updated patch, only
difference is line numbers.
Nice patch. Wanna tell me something about what it's for?
I haven't been following the "Realtime LSM" thread and I'd rather not have to prepare a description of your work for you.
Quoted 10 lines · Andrew Morton
Quoted 3 lines · Lee Revell
Here's an updated patch, only
difference is line numbers.Nice patch. Wanna tell me something about what it's for?
I haven't been following the "Realtime LSM" thread and I'd rather not have to prepare a description of your work for you.
Oh, sorry. Here's the description from my original post:
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications. The typical use for this is low latency audio, and the patch has been extensively field tested by Linux audio users. The realtime LSM is a major improvement in security over the 2.4 capablities patch and other workarounds like jackstart, which rely on CAP_SETPCAP.
This has been extensively field tested, and undeniably satisfies a demand (unlike some other LSMs posted lately). Here is the the author's more detailed explanation:
"We would never have developed this LSM had there not been a serious need. Audio developers have been struggling for years with the need to apply specialized kernel patches to get acceptable realtime operation. Audio is very intolerant of realtime glitches. They cause nasty pops in the output. And, large audio applications should not run as `root'. The 2.4 "capabilities patch" was never a satisfactory solution.
Thanks to the good work being done on 2.6, we are now close to being able to do serious realtime work with standard kernels available everwhere. The LSM framework is an important element of that solution, with the realtime LSM a small but essential component, because it makes these features available without excessive administrative burden. Many musicians have a Mac or Windows background. They are not willing to perform complex system administration tasks to get good audio performance. PAM is great for sophisticated sysadmins on shared systems. But, I seriously doubt many musicians will be able to configure it correctly. For a single-user Digital Audio Workstation it is overkill.
So, even if you do provide a more general solution, I will probably have to continue supporting the realtime-lsm interface throughout the 2.6 kernel life-cycle, as there will be enough users for it to be a defacto standard. If it is no longer needed in the 2.8 timeframe, I can drop support then.
It's hard to say how many people use realtime-lsm right now. SourceForge lists about 1500 source downloads over the last six months. Binary copies are included in the most popular audio-oriented distributions, including Planet CCRMA and DeMuDi. I guess there are probably no more than a few thousand active users."
Lee
Quoted 7 lines · Andrew Morton
Quoted 3 lines · Lee Revell
Here's an updated patch, only
difference is line numbers.Nice patch. Wanna tell me something about what it's for?
Also, just to give a frame of reference, MacOS X (which is our real competition in the pro audio area) just lets any user run RT tasks. So this LSM would give us that needed functionality, but better, because it's selective.
Lee
Documentation/realtime-lsm.txt line 37
Quoted 4 lines · * Lee Revell ([email protected]) wrote:
Documentation/realtime-lsm.txt +4
-0+ # sysctl -w security/realtime/any=0 + # sysctl -w security/realtime/gid=29 + # sysctl -w security/realtime/mlock=1 +
I think these should move to sysfs.
Quoted 8 lines
+Jack O'Quin, [email protected]
diff -ruN -X/home/joq/bin/kdiff.excludelinux-2.6.8.1/include/linux/sysctl.hlinux-2.6.8.1-rt02/include/linux/sysctl.hinclude/linux/sysctl.h +0
-0@@ -61,7 +61,14 @@CTL_DEV =7 ,/* Devices */ CTL_BUS =8 ,/* Busses */ CTL_ABI=9, /* Binary emulation */
include/linux/sysctl.h line 72
Quoted 10 lines
include/linux/sysctl.h +8
-1- CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ +SECURITY_REALTIME =1 /* Realtime LSM */ };
Without adding this extra bit.
security/Kconfig line 89
Quoted 10 lines
diff -ruN -X
/home/joq/bin/kdiff.excludelinux-2.6.8.1/security/Kconfig linux-2.6.8.1-rt02/security/Kconfigsecurity/Kconfig +3
-0@@ -84,6 +84,17 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y
Capabilities can be disabled on boot command line.
security/realtime.c line 49
Quoted 3 lines
security/realtime.c +1
-0+static int any =0 ;/* if TRUE, any process is realtime */
unecessary init to 0
Quoted 1 line
+MODULE_PARM(any, "i");
please use module_param (bonus, you get free entry on command line when non-modular, and entry in /sysfs if you want).
security/realtime.c line 54
Quoted 4 lines
security/realtime.c +4
-0+MODULE_PARM_DESC (any," grant realtime privileges to any process." ); + +static int gid =-1 ;/* realtime group id, or NO_GROUP */ +MODULE_PARM (gid,"i" );
module_param.
security/realtime.c line 58
Quoted 4 lines
security/realtime.c +4
-0+MODULE_PARM_DESC (gid," the group ID with access to realtime privileges." ); + +static int mlock =1 ;/* enable mlock() privileges */ +MODULE_PARM (mlock,"i" );
module_param.
Quoted 10 lines
security/realtime.c +10
-0+MODULE_PARM_DESC (mlock," enable memory locking privileges." ); + +/* helper function for testing group membership */ +static inline int gid_ok (int gid,int e_gid) { +int i; +int rt_ok =0 ; + +if (gid ==-1 ) +return 0 ; +
security/realtime.c line 78
Quoted 10 lines
security/realtime.c +10
-0+if ((gid == e_gid) || (gid == current->gid)) +return 1 ; + +get_group_info (current->group_info); +for (i =0 ; i < current->group_info->ngroups; ++i) { +if (gid ==GROUP_AT (current->group_info, i)) { + rt_ok =1 ; +break ; + } + }
why not in_group_p?
Quoted 23 lines
security/realtime.c +23
-0+put_group_info (current->group_info); + +return rt_ok; +} + +int realtime_bprm_set_security (struct linux_binprm *bprm) +{ +/* Copied from security/commoncap.c: cap_bprm_set_security()... */ +/* Copied from fs/exec.c:prepare_binprm. */ +/* We don't have VFS support for capabilities yet */ +cap_clear (bprm->cap_inheritable); +cap_clear (bprm->cap_permitted); +cap_clear (bprm->cap_effective); + +/* If a non-zero `any' parameter was specified, we grant +* realtime privileges to every process. If the `gid' +* parameter was specified and it matches the group id of the +* executable, of the current process or any supplementary +* groups, we grant realtime capabilites. +*/ + +if (any ||gid_ok (gid, bprm->e_gid)) { +cap_raise (bprm->cap_effective,CAP_SYS_NICE );
security/realtime.c line 111
Quoted 10 lines
security/realtime.c +10
-0+cap_raise (bprm->cap_permitted,CAP_SYS_NICE ); +if (mlock) { +cap_raise (bprm->cap_effective,CAP_IPC_LOCK ); +cap_raise (bprm->cap_permitted,CAP_IPC_LOCK ); +cap_raise (bprm->cap_effective, +CAP_SYS_RESOURCE ); +cap_raise (bprm->cap_permitted, +CAP_SYS_RESOURCE ); + } + }
Maybe it would be better to call cap_bprm_set_security first, then or in the bits you care about. That way you don't have to worry about any changes over there.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 6 lines · Chris Wright
security/realtime.c line 49
Quoted 3 lines
security/realtime.c +1
-0+static int any =0 ;/* if TRUE, any process is realtime */ unecessary init to 0
I think gcc 3.4 complains otherwise.
Lee
Quoted 9 lines · * Lee Revell ([email protected]) wrote:
Quoted 6 lines · Chris Wright
security/realtime.c line 49
Quoted 3 lines
security/realtime.c +1
-0+static int any =0 ;/* if TRUE, any process is realtime */ unecessary init to 0
I think gcc 3.4 complains otherwise.
Nah, it's fine.
$ grep 'int any' security/realtime.c static int any; /* if TRUE, any process is realtime */ $ make security/realtime.o CC security/realtime.o $ gcc --version gcc (GCC) 3.4.2 20040907 (Red Hat 3.4.2-2)
thanks,
-chris
Signature · 33 lines
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net --- security/realtime.c~orig 2004-10-08 14:27:27.000000000 -0700 +++ security/realtime.c 2004-10-08 14:52:31.303484080 -0700 @@ -26,6 +26,7 @@ #include <linux/netlink.h> #include <linux/ptrace.h> #include <linux/sysctl.h> +#include <linux/moduleparam.h> #ifdef CONFIG_SECURITY @@ -46,16 +47,16 @@ * each is referenced only once in each function call. Nothing * depends on parameters having the same value every time. */ -static int any = 0; /* if TRUE, any process is realtime */ -MODULE_PARM(any, "i"); +static int any; /* if TRUE, any process is realtime */ +module_param(any, int, 0644); MODULE_PARM_DESC(any, " grant realtime privileges to any process."); static int gid = -1; /* realtime group id, or NO_GROUP */ -MODULE_PARM(gid, "i"); +module_param(gid, int, 0644); MODULE_PARM_DESC(gid, " the group ID with access to realtime privileges."); static int mlock = 1; /* enable mlock() privileges */ -MODULE_PARM(mlock, "i"); +module_param(mlock, int, 0644); MODULE_PARM_DESC(mlock, " enable memory locking privileges."); /* helper function for testing group membership */
Quoted 11 lines · Chris Wright
Quoted 9 lines · * Lee Revell ([email protected]) wrote:
Quoted 6 lines · Chris Wright
security/realtime.c line 49
Quoted 3 lines
security/realtime.c +1
-0+static int any =0 ;/* if TRUE, any process is realtime */ unecessary init to 0
I think gcc 3.4 complains otherwise.
Quoted 8 lines
Nah, it's fine.
$ grep 'int any' security/realtime.c static int any; /* if TRUE, any process is realtime */ $ make security/realtime.o CC security/realtime.o $ gcc --version gcc (GCC) 3.4.2 20040907 (Red Hat 3.4.2-2)
So MODULE_PARM_DESC is neccesary even when using module_param instear of MODULE_PARM?
Lee
Quoted 21 lines · * Lee Revell ([email protected]) wrote:
Quoted 11 lines · Chris Wright
Quoted 9 lines · * Lee Revell ([email protected]) wrote:
Quoted 6 lines · Chris Wright
security/realtime.c line 49
Quoted 3 lines
security/realtime.c +1
-0+static int any =0 ;/* if TRUE, any process is realtime */ unecessary init to 0
I think gcc 3.4 complains otherwise.
Quoted 8 lines
Nah, it's fine.
$ grep 'int any' security/realtime.c static int any; /* if TRUE, any process is realtime */ $ make security/realtime.o CC security/realtime.o $ gcc --version gcc (GCC) 3.4.2 20040907 (Red Hat 3.4.2-2)
Quoted 2 lines
So
MODULE_PARM_DESCis neccesary even when usingmodule_paraminstear ofMODULE_PARM?
YYeah, minor blemmish ;-)
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
relative to last one.
realtime.c renamed from realtime.c~module_param +4 -26
@@ -84,12 +84,8 @@int realtime_bprm_set_security (struct linux_binprm *bprm) { -/* Copied from security/commoncap.c: cap_bprm_set_security()... */ -/* Copied from fs/exec.c:prepare_binprm. */ -/* We don't have VFS support for capabilities yet */ -cap_clear (bprm->cap_inheritable); -cap_clear (bprm->cap_permitted); -cap_clear (bprm->cap_effective); + +cap_bprm_set_security (bprm);/* If a non-zero `any' parameter was specified, we grant * realtime privileges to every process. If the `gid'
@@ -104,28 +100,10 @@if (mlock) {cap_raise (bprm->cap_effective,CAP_IPC_LOCK );cap_raise (bprm->cap_permitted,CAP_IPC_LOCK ); -cap_raise (bprm->cap_effective, -CAP_SYS_RESOURCE ); -cap_raise (bprm->cap_permitted, -CAP_SYS_RESOURCE ); +cap_raise (bprm->cap_effective,CAP_SYS_RESOURCE ); +cap_raise (bprm->cap_permitted,CAP_SYS_RESOURCE ); } } - -/* To support inheritance of root-permissions and suid-root -* executables under compatibility mode, we raise all three -* capability sets for the file. -* -* If only the real uid is 0, we only raise the inheritable -* and permitted sets of the executable file. -*/ - -if (bprm->e_uid ==0 || current->uid ==0 ) { -cap_set_full (bprm->cap_inheritable); -cap_set_full (bprm->cap_permitted); - } -if (bprm->e_uid ==0 ) -cap_set_full (bprm->cap_effective); -return 0 ; }
(relative to last one)
use in_group_p
realtime.c renamed from realtime.c~cap_bprm_set +3 -14
@@ -60,26 +60,15 @@MODULE_PARM_DESC (mlock," enable memory locking privileges." );/* helper function for testing group membership */ -static inline int gid_ok (int gid,int e_gid) { -int i; -int rt_ok =0 ; - +static inline int gid_ok (int gid,int e_gid) +{if (gid ==-1 )return 0 ;if ((gid == e_gid) || (gid == current->gid))return 1 ; -get_group_info (current->group_info); -for (i =0 ; i < current->group_info->ngroups; ++i) { -if (gid ==GROUP_AT (current->group_info, i)) { - rt_ok =1 ; -break ; - } - } -put_group_info (current->group_info); - -return rt_ok; +return in_group_p (gid); }int realtime_bprm_set_security (struct linux_binprm *bprm)
Quoted 4 lines · Chris Wright
(relative to last one)
use
in_group_p
Thanks! These make the patch even smaller and more comprehensible. Does this cover all the issues with the patch as I posted it?
Lee
Quoted 8 lines · * Lee Revell ([email protected]) wrote:
Quoted 4 lines · Chris Wright
(relative to last one)
use
in_group_pThanks! These make the patch even smaller and more comprehensible. Does this cover all the issues with the patch as I posted it?
The last bit is removing sysctls. It'll take a bit more effort, as we need a touch of infrastructure for it. I'm working on that now. Here's a couple really minor ones.
- make realtime_bprm_set_security static
- don't mark exit_security __exit, it's called from an __init function
thanks,
-chris
Signature · 22 lines
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
--- security/realtime.c 2004-10-08 16:10:52.080357656 -0700
+++ security/realtime.c~in_group 2004-10-08 16:02:05.932344312 -0700
@@ -71,7 +71,7 @@
return in_group_p(gid);
}
-static int realtime_bprm_set_security(struct linux_binprm *bprm)
+int realtime_bprm_set_security(struct linux_binprm *bprm)
{
cap_bprm_set_security(bprm);
@@ -170,7 +170,7 @@
static int secondary; /* flag to keep track of how we were registered */
-static void exit_security(void)
+static void __exit exit_security(void)
{
/* remove ourselves from the security framework */
if (secondary) {Quoted 10 lines · Chris Wright
Quoted 8 lines · * Lee Revell ([email protected]) wrote:
Quoted 4 lines · Chris Wright
(relative to last one)
use
in_group_pThanks! These make the patch even smaller and more comprehensible. Does this cover all the issues with the patch as I posted it?
Quoted 6 lines
The last bit is removing sysctls. It'll take a bit more effort, as we need a touch of infrastructure for it. I'm working on that now. Here's a couple really minor ones.
- make
realtime_bprm_set_securitystatic
- don't markexit_security__exit, it's called from an__initfunction
I think the patch is reversed. It does the opposite of what you say in both cases ;-). I fixed these by hand.
Thanks again.
Lee
Quoted 2 lines · * Lee Revell ([email protected]) wrote:
I think the patch is reversed. It does the opposite of what you say in both cases ;-). I fixed these by hand.
Ooops, thanks.
- rm unecessary #ifdef CONFIG_SECURITY
thanks,
-chris
Signature · 20 lines
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
--- security/realtime.c~static_exit 2004-10-08 16:12:14.199873592 -0700
+++ security/realtime.c 2004-10-08 16:15:43.915991896 -0700
@@ -28,8 +28,6 @@
#include <linux/sysctl.h>
#include <linux/moduleparam.h>
-#ifdef CONFIG_SECURITY
-
#define RT_LSM "Realtime LSM " /* syslog module name prefix */
#define RT_ERR "Realtime: " /* syslog error message prefix */
@@ -231,5 +229,3 @@
MODULE_DESCRIPTION("Realtime Capabilities Security Module");
MODULE_LICENSE("GPL");
-
-#endif /* CONFIG_SECURITY */Quoted 1 line · Chris Wright
use
in_group_p
I looked at that, it wasn't clear to me whether to use in_group_p() or in_egroup_p(). How do you choose?
Signature · 1 line
joq
Quoted 5 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 1 line · Chris Wright
use
in_group_pI looked at that, it wasn't clear to me whether to use
in_group_p()orin_egroup_p(). How do you choose?
For most cases they'll be identical. The difference is whether you're comparing the fsgid or the egid. The former is what's used for file access, the latter might make more sense in your case. However, in 99.9% of the cases you care about fsgid == egid, so it's a wash. So, in_egroup_p matches a bit better. Relative to the other patches...
thanks,
-chris
Signature · 14 lines
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net --- security/realtime.c~rm_CONFIG_SECURITY 2004-10-08 16:16:35.000000000 -0700 +++ security/realtime.c 2004-10-08 21:06:28.020084984 -0700 @@ -66,7 +66,7 @@ if ((gid == e_gid) || (gid == current->gid)) return 1; - return in_group_p(gid); + return in_egroup_p(gid); } static int realtime_bprm_set_security(struct linux_binprm *bprm)
Quoted 4 lines · Chris Wright
Quoted 3 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 1 line · Chris Wright
use
in_group_p
Quoted 8 lines
Quoted 2 lines
I looked at that, it wasn't clear to me whether to use
in_group_p()orin_egroup_p(). How do you choose?For most cases they'll be identical. The difference is whether you're comparing the fsgid or the egid. The former is what's used for file access, the latter might make more sense in your case. However, in 99.9% of the cases you care about fsgid == egid, so it's a wash. So,
in_egroup_pmatches a bit better. Relative to the other patches...
Thanks. I was familiar with gid, and egid from other Unix kernels, but fsgid is new to me.
In what cases does it *differ* from the effective group ID?
realtime.c line 72
Quoted 11 lines
realtime.c renamed from realtime.c~rm_CONFIG_SECURITY +1
-1@@ -66,7 +66,7 @@if ((gid == e_gid) || (gid == current->gid))return 1 ; -return in_group_p (gid); +return in_egroup_p (gid); }static int realtime_bprm_set_security (struct linux_binprm *bprm)
This adds a test against current->egid in addition to the explicit check of current->gid. I don't see any problem with that. AFAICT, the current->gid check is still useful.
Signature · 1 line
joq
Quoted 4 lines · * Jack O'Quin ([email protected]) wrote:
Thanks. I was familiar with gid, and egid from other Unix kernels, but fsgid is new to me.
In what cases does it *differ* from the effective group ID?
If the program calls setfsgid. It would typically only do this if it wanted to assume a new gid for filesystem access on behalf of someone else (e.g. file server).
Quoted 10 lines
Quoted 10 lines
realtime.c renamed from realtime.c~rm_CONFIG_SECURITY +1
-1@@ -66,7 +66,7 @@if ((gid == e_gid) || (gid == current->gid))return 1 ; -return in_group_p (gid); +return in_egroup_p (gid); }
Quoted 5 lines
realtime.c line 72
Quoted 1 line
realtime.c renamed from realtime.c~rm_CONFIG_SECURITY +0
-0static int realtime_bprm_set_security (struct linux_binprm *bprm)This adds a test against
current->egidin addition to the explicit check ofcurrent->gid. I don't see any problem with that. AFAICT, thecurrent->gidcheck is still useful.
The egid makes a setgid-audio program be meaningful as well.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 4 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 3 lines
This adds a test against
current->egidin addition to the explicit check ofcurrent->gid. I don't see any problem with that. AFAICT, thecurrent->gidcheck is still useful.
Quoted 1 line · Chris Wright
The egid makes a setgid-audio program be meaningful as well.
That works already, because we test the e_gid from the bprm structure, right? Is that redundant?
Signature · 1 line
joq
Quoted 5 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 1 line · Chris Wright
The egid makes a setgid-audio program be meaningful as well.
That works already, because we test the
e_gidfrom the bprm structure, right? Is that redundant?
You're right. It's not quite redundant, because current->egid test is before current->egid would be reset on setgid (happens in apply_creds). Using apply_creds actually makes a bit more sense here, and simplifies things a touch.
- use apply_creds and update gid_ok accordingly
- only upgrade cap_effective
- less generic variable names
- s/any/rt_any/
- s/gid/rt_gid/
- s/mlock/rt_mlock/
thanks,
-chris
Signature · 134 lines
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
--- security/realtime.c~in_egroup 2004-10-08 22:17:23.499153832 -0700
+++ security/realtime.c 2004-10-09 15:49:38.048243488 -0700
@@ -45,34 +45,37 @@
* each is referenced only once in each function call. Nothing
* depends on parameters having the same value every time.
*/
-static int any; /* if TRUE, any process is realtime */
-module_param(any, int, 0644);
+
+/* if TRUE, any process is realtime */
+static int rt_any;
+module_param_named(any, rt_any, int, 0644);
MODULE_PARM_DESC(any, " grant realtime privileges to any process.");
-static int gid = -1; /* realtime group id, or NO_GROUP */
-module_param(gid, int, 0644);
+/* realtime group id, or NO_GROUP */
+static int rt_gid = -1;
+module_param_named(gid, rt_gid, int, 0644);
MODULE_PARM_DESC(gid, " the group ID with access to realtime privileges.");
-static int mlock = 1; /* enable mlock() privileges */
-module_param(mlock, int, 0644);
+/* enable mlock() privileges */
+static int rt_mlock = 1;
+module_param_named(mlock, rt_mlock, int, 0644);
MODULE_PARM_DESC(mlock, " enable memory locking privileges.");
/* helper function for testing group membership */
-static inline int gid_ok(int gid, int e_gid)
+static inline int gid_ok(int gid)
{
if (gid == -1)
return 0;
- if ((gid == e_gid) || (gid == current->gid))
+ if (gid == current->gid)
return 1;
return in_egroup_p(gid);
}
-static int realtime_bprm_set_security(struct linux_binprm *bprm)
+static void realtime_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
{
-
- cap_bprm_set_security(bprm);
+ cap_bprm_apply_creds(bprm, unsafe);
/* If a non-zero `any' parameter was specified, we grant
* realtime privileges to every process. If the `gid'
@@ -81,17 +84,13 @@
* groups, we grant realtime capabilites.
*/
- if (any || gid_ok(gid, bprm->e_gid)) {
- cap_raise(bprm->cap_effective, CAP_SYS_NICE);
- cap_raise(bprm->cap_permitted, CAP_SYS_NICE);
- if (mlock) {
- cap_raise(bprm->cap_effective, CAP_IPC_LOCK);
- cap_raise(bprm->cap_permitted, CAP_IPC_LOCK);
- cap_raise(bprm->cap_effective, CAP_SYS_RESOURCE);
- cap_raise(bprm->cap_permitted, CAP_SYS_RESOURCE);
+ if (rt_any || gid_ok(rt_gid)) {
+ cap_raise(current->cap_effective, CAP_SYS_NICE);
+ if (rt_mlock) {
+ cap_raise(current->cap_effective, CAP_IPC_LOCK);
+ cap_raise(current->cap_effective, CAP_SYS_RESOURCE);
}
}
- return 0;
}
static struct security_operations capability_ops = {
@@ -102,8 +101,8 @@
.capable = cap_capable,
.netlink_send = cap_netlink_send,
.netlink_recv = cap_netlink_recv,
- .bprm_apply_creds = cap_bprm_apply_creds,
- .bprm_set_security = realtime_bprm_set_security,
+ .bprm_apply_creds = realtime_bprm_apply_creds,
+ .bprm_set_security = cap_bprm_set_security,
.bprm_secureexec = cap_bprm_secureexec,
.task_post_setuid = cap_task_post_setuid,
.task_reparent_to_init = cap_task_reparent_to_init,
@@ -117,14 +116,14 @@
{
{ .ctl_name = 1,
.procname = "any",
- .data = &any,
+ .data = &rt_any,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
},
{ .ctl_name = 2,
.procname = "gid",
- .data = &gid,
+ .data = &rt_gid,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
@@ -133,7 +132,7 @@
},
{ .ctl_name = 3,
.procname = "mlock",
- .data = &mlock,
+ .data = &rt_mlock,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec,
@@ -205,15 +204,15 @@
return -ENOMEM;
}
- if (any)
+ if (rt_any)
printk(KERN_INFO RT_LSM
- "initialized (all groups, mlock=%d)\n", mlock);
- else if (gid == -1)
+ "initialized (all groups, mlock=%d)\n", rt_mlock);
+ else if (rt_gid == -1)
printk(KERN_INFO RT_LSM
- "initialized (no groups, mlock=%d)\n", mlock);
+ "initialized (no groups, mlock=%d)\n", rt_mlock);
else
printk(KERN_INFO RT_LSM
- "initialized (group %d, mlock=%d)\n", gid, mlock);
+ "initialized (group %d, mlock=%d)\n", rt_gid, rt_mlock);
return 0;
}Quoted 4 lines · Chris Wright
- less generic variable names
- s/any/rt_any/
- s/gid/rt_gid/
- s/mlock/rt_mlock/
Is there a compelling reason for changing all the parameter names?
I would prefer not to do that. It is incompatible for our current user base, and really does not seem like an improvement. Those names only appear in the context of realtime', so the rt_' is completely redundant. For example...
# modprobe realtime gid=29 # sysctl -w security/realtime/mlock=0
Also, you forgot to update the documentation.
Signature · 1 line
joq
Quoted 7 lines · Jack O'Quin
Quoted 4 lines · Chris Wright
- less generic variable names
- s/any/rt_any/
- s/gid/rt_gid/
- s/mlock/rt_mlock/
Quoted 6 lines
Is there a compelling reason for changing all the parameter names?
I would prefer not to do that. It is incompatible for our current user base, and really does not seem like an improvement. Those names only appear in the context of
realtime', so thert_' is completely redundant. For example...
I think the reason was to make the code more readable. How about just mapping the parameters to internal names by prepending rt_?
Lee
Quoted 6 lines
Quoted 4 lines · Chris Wright
- less generic variable names
- s/any/rt_any/
- s/gid/rt_gid/
- s/mlock/rt_mlock/
Quoted 6 lines · Jack O'Quin
Is there a compelling reason for changing all the parameter names?
I would prefer not to do that. It is incompatible for our current user base, and really does not seem like an improvement. Those names only appear in the context of
realtime', so thert_' is completely redundant.
Studying his code, I see that I misunderstood what Chris had done.
Only the internal static variable names changed. There is no change to the user interface.
I have no objection at all to that, it's a good idea.
Signature · 1 line
joq
Quoted 6 lines · Jack O'Quin
Quoted 6 lines
Quoted 4 lines · Chris Wright
- less generic variable names
- s/any/rt_any/
- s/gid/rt_gid/
- s/mlock/rt_mlock/
OK for those of you not playing along at home, here is the latest version of the realtime LSM with all Chris' fixes, as a patch against 2.6.9-mm1.
http://krustophenia.net/realtime-lsm-2.6.9-mm1.patch
I think the only change still needed is to remove the sysctl stuff.
Signature · 1 line
Lee Revell <[email protected]>
Quoted 7 lines · Lee Revell
OK for those of you not playing along at home, here is the latest version of the realtime LSM with all Chris' fixes, as a patch against 2.6.9-mm1.
http://krustophenia.net/realtime-lsm-2.6.9-mm1.patch
I think the only change still needed is to remove the sysctl stuff.
Your diff picked up a bogus patch in `security/Kconfig.orig', mostly harmless, AFAICT, but it should be removed. The Makefile patch was missing, so realtime.c doesn't get compiled.
These minor corrections are included in the version appended below. I'll give it some testing tomorrow, let you know if I find a problem.
Signature · 326 lines
joq diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9/Documentation/realtime-lsm.txt linux-2.6.9-rt1/Documentation/realtime-lsm.txt --- linux-2.6.9/Documentation/realtime-lsm.txt Wed Dec 31 18:00:00 1969 +++ linux-2.6.9-rt1/Documentation/realtime-lsm.txt Fri Oct 22 23:26:21 2004 @@ -0,0 +1,38 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. A + `gid' of -1 disables group access. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + +Parameters can be changed dynamically via /proc/sys/security/realtime: + + # sysctl -w security/realtime/any=0 + # sysctl -w security/realtime/gid=29 + # sysctl -w security/realtime/mlock=1 + +Jack O'Quin, [email protected] diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9/include/linux/sysctl.h linux-2.6.9-rt1/include/linux/sysctl.h --- linux-2.6.9/include/linux/sysctl.h Mon Oct 18 16:54:31 2004 +++ linux-2.6.9-rt1/include/linux/sysctl.h Fri Oct 22 23:27:21 2004 @@ -61,7 +61,14 @@ CTL_DEV=7, /* Devices */ CTL_BUS=8, /* Busses */ CTL_ABI=9, /* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ + CTL_CPU=10, /* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ + SECURITY_REALTIME=1 /* Realtime LSM */ }; /* CTL_BUS names: */ diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9/security/Kconfig linux-2.6.9-rt1/security/Kconfig --- linux-2.6.9/security/Kconfig Mon Oct 18 16:54:39 2004 +++ linux-2.6.9-rt1/security/Kconfig Fri Oct 22 23:26:22 2004 @@ -44,6 +44,17 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + This module selectively grants realtime privileges + controlled by load-time parameters and + /proc/sys/security/realtime. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9/security/Makefile linux-2.6.9-rt1/security/Makefile --- linux-2.6.9/security/Makefile Mon Oct 18 16:54:39 2004 +++ linux-2.6.9-rt1/security/Makefile Fri Oct 22 23:59:30 2004 @@ -15,3 +15,4 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9/security/realtime.c linux-2.6.9-rt1/security/realtime.c --- linux-2.6.9/security/realtime.c Wed Dec 31 18:00:00 1969 +++ linux-2.6.9-rt1/security/realtime.c Fri Oct 22 23:27:21 2004 @@ -0,0 +1,230 @@ +/* + * Realtime Capabilities Linux Security Module + * + * Copyright (C) 2003 Torben Hohn + * Copyright (C) 2003, 2004 Jack O'Quin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/security.h> +#include <linux/file.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/pagemap.h> +#include <linux/swap.h> +#include <linux/smp_lock.h> +#include <linux/skbuff.h> +#include <linux/netlink.h> +#include <linux/ptrace.h> +#include <linux/sysctl.h> +#include <linux/moduleparam.h> + +#define RT_LSM "Realtime LSM " /* syslog module name prefix */ +#define RT_ERR "Realtime: " /* syslog error message prefix */ + +#include <linux/vermagic.h> +MODULE_INFO(vermagic,VERMAGIC_STRING); + +/* this is needed for the proc_dointvec_minmax for allowed GID */ +static int maxuid = 65535; +static int minuid = -1; + +/* module parameters + * + * These values could change at any time due to some process writing + * a new value to /proc/sys/security/realtime. This is OK, because + * each is referenced only once in each function call. Nothing + * depends on parameters having the same value every time. + */ + +/* if TRUE, any process is realtime */ +static int rt_any; +module_param_named(any, rt_any, int, 0644); +MODULE_PARM_DESC(any, " grant realtime privileges to any process."); + +/* realtime group id, or NO_GROUP */ +static int rt_gid = -1; +module_param_named(gid, rt_gid, int, 0644); +MODULE_PARM_DESC(gid, " the group ID with access to realtime privileges."); + +/* enable mlock() privileges */ +static int rt_mlock = 1; +module_param_named(mlock, rt_mlock, int, 0644); +MODULE_PARM_DESC(mlock, " enable memory locking privileges."); + +/* helper function for testing group membership */ +static inline int gid_ok(int gid) +{ + if (gid == -1) + return 0; + + if (gid == current->gid) + return 1; + + return in_egroup_p(gid); +} + +static void realtime_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) +{ + cap_bprm_apply_creds(bprm, unsafe); + + /* If a non-zero `any' parameter was specified, we grant + * realtime privileges to every process. If the `gid' + * parameter was specified and it matches the group id of the + * executable, of the current process or any supplementary + * groups, we grant realtime capabilites. + */ + + if (rt_any || gid_ok(rt_gid)) { + cap_raise(current->cap_effective, CAP_SYS_NICE); + if (rt_mlock) { + cap_raise(current->cap_effective, CAP_IPC_LOCK); + cap_raise(current->cap_effective, CAP_SYS_RESOURCE); + } + } +} + +static struct security_operations capability_ops = { + .ptrace = cap_ptrace, + .capget = cap_capget, + .capset_check = cap_capset_check, + .capset_set = cap_capset_set, + .capable = cap_capable, + .netlink_send = cap_netlink_send, + .netlink_recv = cap_netlink_recv, + .bprm_apply_creds = realtime_bprm_apply_creds, + .bprm_set_security = cap_bprm_set_security, + .bprm_secureexec = cap_bprm_secureexec, + .task_post_setuid = cap_task_post_setuid, + .task_reparent_to_init = cap_task_reparent_to_init, + .syslog = cap_syslog, + .vm_enough_memory = cap_vm_enough_memory, +}; + +#define MY_NAME __stringify(KBUILD_MODNAME) + +static ctl_table realtime_table[] = +{ + { .ctl_name = 1, + .procname = "any", + .data = &rt_any, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 2, + .procname = "gid", + .data = &rt_gid, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &minuid, + .extra2 = &maxuid + }, + { .ctl_name = 3, + .procname = "mlock", + .data = &rt_mlock, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { } +}; + +static ctl_table realtime_root_table[] = +{ + { .ctl_name = SECURITY_REALTIME, + .procname = "realtime", + .mode = 0555, + .child = realtime_table }, + { } +}; + +static ctl_table security_root_table[] = +{ + { .ctl_name = CTL_SECURITY, + .procname = "security", + .mode = 0555, + .child = realtime_root_table }, + { } +}; + +static struct ctl_table_header *sysctl_header; + +static void __exit exit_sysctl(void) +{ + unregister_sysctl_table(sysctl_header); +} + +static int secondary; /* flag to keep track of how we were registered */ + +static void exit_security(void) +{ + /* remove ourselves from the security framework */ + if (secondary) { + if (mod_unreg_security(MY_NAME, &capability_ops)) + printk(KERN_INFO RT_ERR "Failure unregistering " + "capabilities with primary module.\n"); + + } else if (unregister_security(&capability_ops)) { + printk(KERN_INFO RT_ERR + "Failure unregistering capabilities with the kernel\n"); + } + printk(KERN_INFO "Realtime Capability LSM exiting\n"); +} + +static int __init capability_init(void) +{ + /* register ourselves with the security framework */ + if (register_security(&capability_ops)) { + + /* try registering with primary module */ + if (mod_reg_security(MY_NAME, &capability_ops)) { + printk(KERN_INFO RT_ERR "Failure registering " + "capabilities with primary security module.\n"); + printk(KERN_INFO RT_ERR "Is kernel configured " + "with CONFIG_SECURITY_CAPABILITIES=m?\n"); + return -EINVAL; + } + secondary = 1; + } + + sysctl_header = register_sysctl_table(security_root_table, 0); + if (!sysctl_header) { + exit_security(); + return -ENOMEM; + } + + if (rt_any) + printk(KERN_INFO RT_LSM + "initialized (all groups, mlock=%d)\n", rt_mlock); + else if (rt_gid == -1) + printk(KERN_INFO RT_LSM + "initialized (no groups, mlock=%d)\n", rt_mlock); + else + printk(KERN_INFO RT_LSM + "initialized (group %d, mlock=%d)\n", rt_gid, rt_mlock); + + return 0; +} + +static void __exit capability_exit(void) +{ + exit_sysctl(); + exit_security(); +} + +late_initcall(capability_init); +module_exit(capability_exit); + +MODULE_DESCRIPTION("Realtime Capabilities Security Module"); +MODULE_LICENSE("GPL");
Quoted 2 lines · Jack O'Quin
These minor corrections are included in the version appended below. I'll give it some testing tomorrow, let you know if I find a problem.
AFAICT it works with 2.6.9, but the realtime performance is terrible (2.6.8.1 was much better). The appropriate threads are running SCHED_FIFO, but there are frequent xruns. Could some change in the kernel be affecting this?
I'm going to to try 2.6.9-mm1, to see if that works better.
Signature · 1 line
joq
Quoted 6 lines · Jack O'Quin
AFAICT it works with 2.6.9, but the realtime performance is terrible (2.6.8.1 was much better). The appropriate threads are running
SCHED_FIFO, but there are frequent xruns. Could some change in the kernel be affecting this?I'm going to to try 2.6.9-mm1, to see if that works better.
2.6.9-mm1 works fine. I'm appending an updated complete version of the patch for that kernel (the 2.6.9 patch did not apply cleanly).
As Lee already stated, this version is not final, because it still exposes its parameters to sysctl via /proc/sys/security/realtime.
Chris Wright prefers to do that differently, using sysfs. I defer to his judgement about that, but don't understand what he has in mind well enough to actually implement it myself. Clearly, this LSM should handle parameters however the others do or will.
Signature · 326 lines
joq diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9-mm1/Documentation/realtime-lsm.txt linux-2.6.9-mm1-rt1/Documentation/realtime-lsm.txt --- linux-2.6.9-mm1/Documentation/realtime-lsm.txt Wed Dec 31 18:00:00 1969 +++ linux-2.6.9-mm1-rt1/Documentation/realtime-lsm.txt Sun Oct 24 13:29:22 2004 @@ -0,0 +1,38 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. A + `gid' of -1 disables group access. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + +Parameters can be changed dynamically via /proc/sys/security/realtime: + + # sysctl -w security/realtime/any=0 + # sysctl -w security/realtime/gid=29 + # sysctl -w security/realtime/mlock=1 + +Jack O'Quin, [email protected] diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9-mm1/include/linux/sysctl.h linux-2.6.9-mm1-rt1/include/linux/sysctl.h --- linux-2.6.9-mm1/include/linux/sysctl.h Sun Oct 24 13:14:59 2004 +++ linux-2.6.9-mm1-rt1/include/linux/sysctl.h Sun Oct 24 13:29:22 2004 @@ -61,7 +61,14 @@ CTL_DEV=7, /* Devices */ CTL_BUS=8, /* Busses */ CTL_ABI=9, /* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ + CTL_CPU=10, /* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ + SECURITY_REALTIME=1 /* Realtime LSM */ }; /* CTL_BUS names: */ diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9-mm1/security/Kconfig linux-2.6.9-mm1-rt1/security/Kconfig --- linux-2.6.9-mm1/security/Kconfig Sun Oct 24 13:15:02 2004 +++ linux-2.6.9-mm1-rt1/security/Kconfig Sun Oct 24 13:29:22 2004 @@ -84,6 +84,17 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + This module selectively grants realtime privileges + controlled by load-time parameters and + /proc/sys/security/realtime. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9-mm1/security/Makefile linux-2.6.9-mm1-rt1/security/Makefile --- linux-2.6.9-mm1/security/Makefile Sun Oct 24 13:15:02 2004 +++ linux-2.6.9-mm1-rt1/security/Makefile Sun Oct 24 13:30:08 2004 @@ -17,3 +17,4 @@ obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o obj-$(CONFIG_SECURITY_SECLVL) += seclvl.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.9-mm1/security/realtime.c linux-2.6.9-mm1-rt1/security/realtime.c --- linux-2.6.9-mm1/security/realtime.c Wed Dec 31 18:00:00 1969 +++ linux-2.6.9-mm1-rt1/security/realtime.c Sun Oct 24 13:29:22 2004 @@ -0,0 +1,230 @@ +/* + * Realtime Capabilities Linux Security Module + * + * Copyright (C) 2003 Torben Hohn + * Copyright (C) 2003, 2004 Jack O'Quin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/security.h> +#include <linux/file.h> +#include <linux/mm.h> +#include <linux/mman.h> +#include <linux/pagemap.h> +#include <linux/swap.h> +#include <linux/smp_lock.h> +#include <linux/skbuff.h> +#include <linux/netlink.h> +#include <linux/ptrace.h> +#include <linux/sysctl.h> +#include <linux/moduleparam.h> + +#define RT_LSM "Realtime LSM " /* syslog module name prefix */ +#define RT_ERR "Realtime: " /* syslog error message prefix */ + +#include <linux/vermagic.h> +MODULE_INFO(vermagic,VERMAGIC_STRING); + +/* this is needed for the proc_dointvec_minmax for allowed GID */ +static int maxuid = 65535; +static int minuid = -1; + +/* module parameters + * + * These values could change at any time due to some process writing + * a new value to /proc/sys/security/realtime. This is OK, because + * each is referenced only once in each function call. Nothing + * depends on parameters having the same value every time. + */ + +/* if TRUE, any process is realtime */ +static int rt_any; +module_param_named(any, rt_any, int, 0644); +MODULE_PARM_DESC(any, " grant realtime privileges to any process."); + +/* realtime group id, or NO_GROUP */ +static int rt_gid = -1; +module_param_named(gid, rt_gid, int, 0644); +MODULE_PARM_DESC(gid, " the group ID with access to realtime privileges."); + +/* enable mlock() privileges */ +static int rt_mlock = 1; +module_param_named(mlock, rt_mlock, int, 0644); +MODULE_PARM_DESC(mlock, " enable memory locking privileges."); + +/* helper function for testing group membership */ +static inline int gid_ok(int gid) +{ + if (gid == -1) + return 0; + + if (gid == current->gid) + return 1; + + return in_egroup_p(gid); +} + +static void realtime_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) +{ + cap_bprm_apply_creds(bprm, unsafe); + + /* If a non-zero `any' parameter was specified, we grant + * realtime privileges to every process. If the `gid' + * parameter was specified and it matches the group id of the + * executable, of the current process or any supplementary + * groups, we grant realtime capabilites. + */ + + if (rt_any || gid_ok(rt_gid)) { + cap_raise(current->cap_effective, CAP_SYS_NICE); + if (rt_mlock) { + cap_raise(current->cap_effective, CAP_IPC_LOCK); + cap_raise(current->cap_effective, CAP_SYS_RESOURCE); + } + } +} + +static struct security_operations capability_ops = { + .ptrace = cap_ptrace, + .capget = cap_capget, + .capset_check = cap_capset_check, + .capset_set = cap_capset_set, + .capable = cap_capable, + .netlink_send = cap_netlink_send, + .netlink_recv = cap_netlink_recv, + .bprm_apply_creds = realtime_bprm_apply_creds, + .bprm_set_security = cap_bprm_set_security, + .bprm_secureexec = cap_bprm_secureexec, + .task_post_setuid = cap_task_post_setuid, + .task_reparent_to_init = cap_task_reparent_to_init, + .syslog = cap_syslog, + .vm_enough_memory = cap_vm_enough_memory, +}; + +#define MY_NAME __stringify(KBUILD_MODNAME) + +static ctl_table realtime_table[] = +{ + { .ctl_name = 1, + .procname = "any", + .data = &rt_any, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 2, + .procname = "gid", + .data = &rt_gid, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &minuid, + .extra2 = &maxuid + }, + { .ctl_name = 3, + .procname = "mlock", + .data = &rt_mlock, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { } +}; + +static ctl_table realtime_root_table[] = +{ + { .ctl_name = SECURITY_REALTIME, + .procname = "realtime", + .mode = 0555, + .child = realtime_table }, + { } +}; + +static ctl_table security_root_table[] = +{ + { .ctl_name = CTL_SECURITY, + .procname = "security", + .mode = 0555, + .child = realtime_root_table }, + { } +}; + +static struct ctl_table_header *sysctl_header; + +static void __exit exit_sysctl(void) +{ + unregister_sysctl_table(sysctl_header); +} + +static int secondary; /* flag to keep track of how we were registered */ + +static void exit_security(void) +{ + /* remove ourselves from the security framework */ + if (secondary) { + if (mod_unreg_security(MY_NAME, &capability_ops)) + printk(KERN_INFO RT_ERR "Failure unregistering " + "capabilities with primary module.\n"); + + } else if (unregister_security(&capability_ops)) { + printk(KERN_INFO RT_ERR + "Failure unregistering capabilities with the kernel\n"); + } + printk(KERN_INFO "Realtime Capability LSM exiting\n"); +} + +static int __init capability_init(void) +{ + /* register ourselves with the security framework */ + if (register_security(&capability_ops)) { + + /* try registering with primary module */ + if (mod_reg_security(MY_NAME, &capability_ops)) { + printk(KERN_INFO RT_ERR "Failure registering " + "capabilities with primary security module.\n"); + printk(KERN_INFO RT_ERR "Is kernel configured " + "with CONFIG_SECURITY_CAPABILITIES=m?\n"); + return -EINVAL; + } + secondary = 1; + } + + sysctl_header = register_sysctl_table(security_root_table, 0); + if (!sysctl_header) { + exit_security(); + return -ENOMEM; + } + + if (rt_any) + printk(KERN_INFO RT_LSM + "initialized (all groups, mlock=%d)\n", rt_mlock); + else if (rt_gid == -1) + printk(KERN_INFO RT_LSM + "initialized (no groups, mlock=%d)\n", rt_mlock); + else + printk(KERN_INFO RT_LSM + "initialized (group %d, mlock=%d)\n", rt_gid, rt_mlock); + + return 0; +} + +static void __exit capability_exit(void) +{ + exit_sysctl(); + exit_security(); +} + +late_initcall(capability_init); +module_exit(capability_exit); + +MODULE_DESCRIPTION("Realtime Capabilities Security Module"); +MODULE_LICENSE("GPL");
Quoted 8 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 4 lines · Chris Wright
- less generic variable names
- s/any/rt_any/
- s/gid/rt_gid/
- s/mlock/rt_mlock/Is there a compelling reason for changing all the parameter names?
primarly for namespace cleanliness. nice to avoid overly generic names if possible. makes it easier to search.
Quoted 4 lines
I would prefer not to do that. It is incompatible for our current user base, and really does not seem like an improvement. Those names only appear in the context of
realtime', so thert_' is completely redundant. For example...
Actually, I recall the change being 100% internal (not exposed externally), but I'm away at the moment, so it's just from memory.
Quoted 4 lines
# modprobe realtime gid=29 # sysctl -w security/realtime/mlock=0Also, you forgot to update the documentation.
I don't think it was needed due to above.
thanks,
-chris
Signature · 1 line
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net
Quoted 2 lines · Jody McIntyre
This patch still includes allcaps, which should be removed before it is merged.
The `allcaps' option is removed in this version, documentation updated, plus some minor comment changes.
Quoted 1 line
The patch is now against 2.6.9-pre2-mm4.
This patch was diff'ed against 2.6.8.1. Some of the offsets in 2.6.9-pre2-mm4 were slightly different, but the patch applied correctly anyway. I think it will work fine either way.
Quoted 9 lines
The realtime-lsm Linux Security Module, written by Torben Hohn and Jack O'Quin, selectively grants realtime capabilities to specific user groups or applications. The typical use for this is low latency audio, and the patch has been extensively field tested by Linux audio users. The realtime LSM is a major improvement in security over the 2.4 capablities patch and other workarounds like jackstart, which rely on
CAP_SETPCAP.Signed-off-by Lee Revell <[email protected]>Signed-off-by Jody McIntyre <[email protected]>
Documentation/realtime-lsm.txt +38 -0
@@ -0,0 +1,38 @@ + + Realtime Linux Security Module + + +This Linux Security Module (LSM) enables realtime capabilities. It +was written by Torben Hohn and Jack O'Quin, under the provisions of +the GPL (see the COPYING file). We make no warranty concerning the +safety, security or even stability of your system when using it. But, +we will fix problems if you report them. + +Once the LSM has been installed and the kernel for which it was built +is running, the root user can load it and pass parameters as follows: + + # modprobe realtime any=1 + + Any program can request realtime privileges. This allows any local + user to crash the system by hogging the CPU in a tight loop or + locking down too much memory. But, it is simple to administer. :-) + + # modprobe realtime gid=29 + + All users belonging to group 29 and programs that are setgid to that + group have realtime privileges. Use any group number you like. A + `gid' of -1 disables group access. + + # modprobe realtime mlock=0 + + Grants realtime scheduling privileges without the ability to lock + memory using mlock() or mlockall() system calls. This option can be + used in conjunction with any of the other options. + +Parameters can be changed dynamically via /proc/sys/security/realtime: + + # sysctl -w security/realtime/any=0 + # sysctl -w security/realtime/gid=29 + # sysctl -w security/realtime/mlock=1 + +Jack O'Quin, [email protected]
include/linux/sysctl.h +8 -1
@@ -61,7 +61,14 @@CTL_DEV =7 ,/* Devices */ CTL_BUS =8 ,/* Busses */ CTL_ABI =9 ,/* Binary emulation */ - CTL_CPU=10 /* CPU stuff (speed scaling, etc) */ +CTL_CPU =10 ,/* CPU stuff (speed scaling, etc) */ + CTL_SECURITY=11 /* Security modules */ +}; + +/* CTL_SECURITY names: */ +enum +{ +SECURITY_REALTIME =1 /* Realtime LSM */ };/* CTL_BUS names: */
security/Kconfig +11 -0
@@ -44,6 +44,17 @@ If you are unsure how to answer this question, answer N. +config SECURITY_REALTIME + tristate "Realtime Capabilities" + depends on SECURITY && SECURITY_CAPABILITIES!=y + default n + help + This module selectively grants realtime privileges + controlled by load-time parameters and + /proc/sys/security/realtime. + + If you are unsure how to answer this question, answer N. + source security/selinux/Kconfig endmenu
security/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o +obj-$(CONFIG_SECURITY_REALTIME) += commoncap.o realtime.o
security/realtime.c +267 -0
267 lines not on this page · raw message
Signature · 1 line
joq
security/realtime.c line 44
Quoted 3 lines · Jody McIntyre
security/realtime.c new file +3
-0+/* module parameters */ +static int any =0 ;/* if TRUE, any process is realtime */ +MODULE_PARM (any,"i" );
Please node that MODULE_PARM is deprecated. This looks like a job for "module_param(any, bool, 0400)" or even "0644". Please consider, and for the others.
Thanks,
Rusty.
Signature · 1 line
Anyone who quotes me in their signature is an idiot -- Rusty Russell
Quoted 8 lines · Rusty Russell
security/realtime.c line 44
Quoted 3 lines · Jody McIntyre
security/realtime.c new file +3
-0+/* module parameters */ +static int any =0 ;/* if TRUE, any process is realtime */ +MODULE_PARM (any,"i" );Please node that
MODULE_PARMis deprecated. This looks like a job for "module_param(any, bool, 0400)" or even "0644". Please consider, and for the others.
This change (along with many other improvements) was already made by Chris Wright. An updated patch will probably be posted soon.
Lee