Skip to contentSkip to conversation

Realtime LSM

PATCH In review Lee Revell 11 participants 67 messages Sep 12, 2004 – Oct 25, 2004

Subsystems (3)
lore
Share & tools
lore

Lee Revell

author
#0 lore raw

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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/Documentation/realtime-lsm.txt linux-2.6.8.1-rt/Documentation/realtime-lsm.txt
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Kconfig linux-2.6.8.1-rt/security/Kconfig
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Makefile linux-2.6.8.1-rt/security/Makefile
@@ -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

#1 lore raw

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]>
#2 lore raw
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]>
#12 lore raw
In reply to Lee Revell

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.exclude linux-2.6.8.1/security/realtime.c linux-2.6.8.1-rt/security/realtime.c

security/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_NAME THIS_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
author
#3 lore raw
In reply to James Morris
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

#4 lore raw
In reply to James Morris
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
author
#13 lore raw
In reply to Kronos
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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/Documentation/realtime-lsm.txt linux-2.6.8.1-rt/Documentation/realtime-lsm.txt
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Kconfig linux-2.6.8.1-rt/security/Kconfig
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Makefile linux-2.6.8.1-rt/security/Makefile
@@ -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

#14 lore raw
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
author
#15 lore raw
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

#16 lore raw
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_FIFO processes and use mlockall() 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

author
#17 lore raw
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_FIFO processes and use mlockall() 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

#18 lore raw
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

#5 lore raw
In reply to Jack O'Quin
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
Index: linux/Documentation/realtime-lsm.txt
===================================================================
@@ -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
Index: linux/security/Makefile
===================================================================
@@ -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
Index: linux/include/linux/sysctl.h
===================================================================
@@ -61,7 +61,14 @@ enum
 	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 +14 -0
Index: linux/security/Kconfig
===================================================================
@@ -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
#6 lore raw
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 added CTL_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
#7 lore raw
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_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.

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
Index: linux/Documentation/realtime-lsm.txt
===================================================================
@@ -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
Index: linux/security/Makefile
===================================================================
@@ -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
Index: linux/include/linux/sysctl.h
===================================================================
@@ -61,7 +61,14 @@ enum
 	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 +15 -0
Index: linux/security/Kconfig
===================================================================
@@ -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
#8 lore raw
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
#9 lore raw
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
#10 lore raw
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
#11 lore raw
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 exec jackd' 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
#19 lore raw
In reply to Lee Revell

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

#20 lore raw
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
#21 lore raw
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 Kconfig dependency 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
#22 lore raw
In reply to Jody McIntyre

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
Index: linux/Documentation/realtime-lsm.txt
===================================================================
@@ -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
Index: linux/security/Makefile
===================================================================
@@ -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
Index: linux/include/linux/sysctl.h
===================================================================
@@ -61,7 +61,14 @@ enum
 	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
Index: linux/security/Kconfig
===================================================================
@@ -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
author
#23 lore raw
Quoted 6 lines · Jody McIntyre

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.

Another issue that was raised was that the mlock stuff is also unnecessary, because rlimits can do this now. Is this the case?

Lee

#24 lore raw
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
#25 lore raw
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
#26 lore raw
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
author
#27 lore raw
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

#28 lore raw
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_FIFO processes?

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
author
#29 lore raw
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

#30 lore raw
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
author
#31 lore raw
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

#32 lore raw
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
#64 lore raw
In reply to Jody McIntyre
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.

Documentation/realtime-lsm.txt +38 -0
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/Documentation/realtime-lsm.txt linux-2.6.8.1-rt02/Documentation/realtime-lsm.txt
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/include/linux/sysctl.h linux-2.6.8.1-rt02/include/linux/sysctl.h
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Kconfig linux-2.6.8.1-rt02/security/Kconfig
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Makefile linux-2.6.8.1-rt02/security/Makefile
@@ -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
#33 lore raw
In reply to Chris Wright
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
author
#34 lore raw
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

author
#35 lore raw
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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/Documentation/realtime-lsm.txt linux-2.6.8.1-rt02/Documentation/realtime-lsm.txt
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/include/linux/sysctl.h linux-2.6.8.1-rt02/include/linux/sysctl.h
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Kconfig linux-2.6.8.1-rt02/security/Kconfig
@@ -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
diff -ruN -X /home/joq/bin/kdiff.exclude linux-2.6.8.1/security/Makefile linux-2.6.8.1-rt02/security/Makefile
@@ -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

#36 lore raw
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.

author
#37 lore raw
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

author
#38 lore raw
In reply to Andrew Morton
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

#39 lore raw
In reply to Lee Revell

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.exclude linux-2.6.8.1/include/linux/sysctl.h linux-2.6.8.1-rt02/include/linux/sysctl.h

include/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.exclude linux-2.6.8.1/security/Kconfig linux-2.6.8.1-rt02/security/Kconfig

security/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
author
#40 lore raw
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

#41 lore raw
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 */
author
#42 lore raw
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

#43 lore raw
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_DESC is neccesary even when using module_param instear of MODULE_PARM?

YYeah, minor blemmish ;-)

thanks,
-chris

Signature · 1 line
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net
#44 lore raw
In reply to Lee Revell

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;
 }
 
#45 lore raw

(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)
author
#46 lore raw
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

#47 lore raw
Quoted 8 lines · * Lee Revell ([email protected]) wrote:
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?

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) {
author
#48 lore raw
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_p

Thanks! 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_security static
- don't mark exit_security __exit, it's called from an __init function

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

#49 lore raw
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 */
#50 lore raw
In reply to Chris Wright
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
#51 lore raw
Quoted 5 lines · * Jack O'Quin ([email protected]) wrote:
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?

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)
#52 lore raw
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() or in_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. 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
#53 lore raw
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 -0
 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.

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
#54 lore raw
Quoted 4 lines · * Jack O'Quin ([email protected]) wrote:
Quoted 3 lines

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.

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
#55 lore raw
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_gid from 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;
 }
#65 lore raw
In reply to Jody McIntyre

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
author
#66 lore raw
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_PARM is 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

#56 lore raw
In reply to Chris Wright
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
author
#57 lore raw
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 the rt_' 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

#58 lore raw
In reply to 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/

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 the rt_' 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
author
#59 lore raw
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]>
#60 lore raw
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");
#61 lore raw
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
#63 lore raw
In reply to Jack O'Quin
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 the rt_' 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=0

Also, 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
#62 lore raw
In reply to Jack O'Quin
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");