Skip to contentSkip to conversation

LSM changes for 2.5.38

RFC Christoph Hellwig 7 participants 23 messages Sep 26, 2002 – Oct 2, 2002

lore
Share & tools
lore
#0 lore raw
Quoted 4 lines

/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)

Review line 71

Quoted 10 lines
(quoted diff) +6 -1
@@ -62,7 +63,12 @@
 		return -EINVAL;
 	if (turn_on && !capable(CAP_SYS_RAWIO))
 		return -EPERM;
-
+ 
+ 	ret = security_ops->ioperm(from, num, turn_on);
+ 	if (ret) {
+ 		return ret;
+ 	}
+ 

Sorry, but this is bullshit (like most of the lsm changes). Either you leave the capable in and say it's enough or you add your random hook and remove that one. Just adding more and more hooks without thinking gets us exactly nowhere except to an unmaintainable codebase.

Also is there a _real_ need to pass in all the arguments?

Review

Quoted 7 lines
(quoted diff) +5 -0
 			return -EPERM;
 	}
+	retval = security_ops->iopl(old, level);
+	if (retval) {
+		return retval;
+	}
+

again (and another few times)

Quoted 9 lines

+ * @module_create:
+ * Check the permission before allocating space for a module.
+ * @name contains the module name.
+ * @size contains the module size.
+ * Return 0 if permission is granted.
+ * @module_initialize:
+ * Check permission before initializing a module.
+ * @mod contains a pointer to the module being initialized.
+ * Return 0 if permission is granted.

Umm, you can't tell me you deny someone to initialize a module he has just created?

Quoted 8 lines

+ * @sethostname:
+ * Check permission before the hostname is set to @hostname.
+ * @hostname contains the new hostname
+ * Return 0 if permission is granted.
+ * @setdomainname:
+ * Check permission before the domainname is set to @domainname.
+ * @domainname contains the new domainname
+ * Return 0 if permission is granted.

You don't think this should maybe be just one hook?

Quoted 6 lines

+ * @ioperm:
+ * Check permission before setting port input/output permissions for the
+ * process for @num bytes starting from the port address @from to the
+ * value @turn_on.
+ * @from contains the starting port address.
+ * @num contains the number of bytes starting from @from.

Quoted 8 lines

+ * @turn_on contains the permissions value.
+ * Return 0 if permission is granted.
+ * @iopl:
+ * Check permission before changing the I/O privilege level of the current
+ * process from @old to @level.
+ * @old contains the old level.
+ * @level contains the new level.
+ * Return 0 if permission is granted.

Dito.

Quoted 6 lines

+ * @sysctl:
+ * Check permission before accessing the @table sysctl variable in the
+ * manner specified by @op.
+ * @table contains the ctl_table structure for the sysctl variable.
+ * @op contains the operation (001 = search, 002 = write, 004 = read).
+ * Return 0 if permission is granted.

Aha. So every LS module knows about every single sysctl in the kernel. Common, this is silly guys (and girls if there any)!

Quoted 10 lines

+ * @swapon:
+ * Check permission before enabling swapping to the file or block device
+ * identified by @swap.
+ * @swap contains the swap_info_struct structure for the swap file and device.
+ * Return 0 if permission is granted.
+ * @swapoff:
+ * Check permission before disabling swapping to the file or block device
+ * identified by @swap.
+ * @swap contains the swap_info_struct structure for the swap file and device.
+ * Return 0 if permission is granted.

You might be allowed to swapon but not swapoff?

Quoted 8 lines

diff -Nru a/kernel/sys.c b/kernel/sys.c

kernel/sys.c +1 -0
@@ -349,11 +349,17 @@
 asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
 {
 	char buffer[256];
+	int retval;

kernel/sys.c line 362

Quoted 10 lines
kernel/sys.c +5 -0
 
 	/* We only trust the superuser with rebooting the system. */
 	if (!capable(CAP_SYS_BOOT))
 		return -EPERM;
 
+	retval = security_ops->reboot(cmd);
+	if (retval) {
+		return retval;
+	}
+

What's the point of cmd here? Someone might be allowed to halt the system but not reboot?

[don't of stubfs snipped]

kernel/sys.c

Quoted 9 lines
kernel/sys.c +9 -0
+static int cap_swapon (struct swap_info_struct *swap)
+{
+	return 0;
+}
+
+static int cap_swapoff (struct swap_info_struct *swap)
+{
+	return 0;
+}

Live would be a lot simple if an unimplemented op would behave as returning zero..

Christoph (not speaking for SGI, just using the fastest mailserver)

#1 lore raw
Quoted 11 lines · Christoph Hellwig
Quoted 11 lines

/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)

(quoted diff) +3 -1
@@ -62,7 +63,12 @@
 		return -EINVAL;
 	if (turn_on && !capable(CAP_SYS_RAWIO))
 		return -EPERM;
-
+ 
+ 	ret = security_ops->ioperm(from, num, turn_on);
+ 	if (ret) {
Quoted 8 lines

Review line 71

Quoted 3 lines
(quoted diff) +3 -0
+ 		return ret;
+ 	}
+ 

Sorry, but this is bullshit (like most of the lsm changes). Either you leave the capable in and say it's enough or you add your random hook and remove that one. Just adding more and more hooks without thinking gets us exactly nowhere except to an unmaintainable codebase.

capable is needed to be checked, as we are not modifying the existing permission logic.

Quoted 1 line

Also is there a _real_ need to pass in all the arguments?

I'll let Stephen answer that one, as SELinux uses it.

Oops, ok, nevermind, I don't see _any_ security module using this hook. In fact they are using the capable(CAP_SYS_RAWIO) hook, which is exactly what you suggest :)

I'll go remove it.

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +5 -0
 			return -EPERM;
 	}
+	retval = security_ops->iopl(old, level);
+	if (retval) {
+		return retval;
+	}
+

again (and another few times)

Ok, again, no one is using it. I'll go remove it (and go audit all of the other hooks.)

Quoted 10 lines
Quoted 9 lines

+ * @module_create:
+ * Check the permission before allocating space for a module.
+ * @name contains the module name.
+ * @size contains the module size.
+ * Return 0 if permission is granted.
+ * @module_initialize:
+ * Check permission before initializing a module.
+ * @mod contains a pointer to the module being initialized.
+ * Return 0 if permission is granted.

Quoted 2 lines

Umm, you can't tell me you deny someone to initialize a module he has just created?

Bah, ok, again no one uses these either.

Consider me roasted, I'll go audit this whole thing to try to justify every one of the hooks we ask for.

Very sorry for bothering people.

thanks,

greg k-h

#6 lore raw
In reply to Christoph Hellwig
Quoted 4 lines · Christoph Hellwig

Sorry, but this is bullshit (like most of the lsm changes). Either you leave the capable in and say it's enough or you add your random hook and remove that one. Just adding more and more hooks without thinking gets us exactly nowhere except to an unmaintainable codebase.

The LSM hooks are primarily restrictive, i.e. a security module can deny access that would normally be granted by the existing Linux access checks. Hence, the LSM patch does not remove existing access checks. Minimal support for permissive behavior (granting what would normally be denied) is provided to support modularization of the capabilities logic, but this does not require removing the capable() calls from kernel functions. This approach reduces the invasiveness of the patch and the likelihood of introducing bugs into the base kernel access checking. See the LSM papers from Usenix Security and OLS, which should be available from lsm.immunix.org.

Quoted 1 line

Also is there a _real_ need to pass in all the arguments?

Define _real_. It is true that none of the existing open source security modules presently use this particular hook. SELinux doesn't presently use it, but it seems reasonable to support finer-grained control over ioperm() than the all-or-nothing CAP_SYS_RAWIO. Is the criteria that every hook and every parameter to every hook must be used by an existing open source security module? If so, then yes, this hook can be dropped.

Quoted 2 lines

Umm, you can't tell me you deny someone to initialize a module he has just created?

In sys_create_module, you only know the name and size of the module and who is performing the operation. In sys_init_module, you actually have information about the module available. Hence, you can make a finer-grained decision in the module_initialize hook, and possibly deny even after a successful module_create. As above, SELinux doesn't use these hooks presently.

Quoted 1 line

You don't think this should maybe be just one hook?

They are different operations, with different interpretations of the string parameter. If your security module is enforcing any kind of restriction based on the parameter, then you need to distinguish them. Again, not used by SELinux at present.

Quoted 2 lines

Aha. So every LS module knows about every single sysctl in the kernel. Common, this is silly guys (and girls if there any)!

SELinux does use the sysctl hook. It assigns security labels to sysctl variables and enforces a consistent control whether accessed via the sysctl() call or the /proc/sys interface. The granularity at which you distinguish the sysctl variables is configurable. For example, we assign an individual security label to /proc/sys/kernel/modprobe to suport fine-grained control over access to it. Most sysctl variables are grouped into equivalence classes based on the hierarchy, but it is entirely configurable in the security policy.

--
Stephen D. Smalley, NAI Labs
[email protected]

#7 lore raw
Quoted 9 lines · Stephen Smalley
Quoted 2 lines

Also is there a _real_ need to pass in all the arguments?

Define _real_. It is true that none of the existing open source security modules presently use this particular hook. SELinux doesn't presently use it, but it seems reasonable to support finer-grained control over ioperm() than the all-or-nothing CAP_SYS_RAWIO. Is the criteria that every hook and every parameter to every hook must be used by an existing open source security module? If so, then yes, this hook can be dropped.

Yes, I think that is the criteria for any security hook. So it (and others) should be dropped.

thanks,

greg k-h

#2 lore raw
In reply to Greg KH
Quoted 6 lines · Greg KH
Quoted 3 lines

leave the capable in and say it's enough or you add your random hook and remove that one. Just adding more and more hooks without thinking gets us exactly nowhere except to an unmaintainable codebase.

capable is needed to be checked, as we are not modifying the existing permission logic.

I odn't think it makes sense to have two security checks that both end up in the LSM code after each other..

#8 lore raw
In reply to Stephen Smalley
Quoted 10 lines · Stephen Smalley
Quoted 4 lines · Christoph Hellwig

Sorry, but this is bullshit (like most of the lsm changes). Either you leave the capable in and say it's enough or you add your random hook and remove that one. Just adding more and more hooks without thinking gets us exactly nowhere except to an unmaintainable codebase.

The LSM hooks are primarily restrictive, i.e. a security module can deny access that would normally be granted by the existing Linux access checks.

In 2.5 LSM hooks are part of the Linux access checks, and any reason to make your patch less intrusive inb 2.4 doesn't apply anymore. Having two checks for the same thing is indeed very bad in will cause harm and maintaince burden in the long term. Don't do it.

Quoted 3 lines
Quoted 1 line

Also is there a _real_ need to pass in all the arguments?

Define _real_.

Show me a useful example that needs this argument.

Quoted 6 lines

It is true that none of the existing open source security modules presently use this particular hook. SELinux doesn't presently use it, but it seems reasonable to support finer-grained control over ioperm() than the all-or-nothing CAP_SYS_RAWIO. Is the criteria that every hook and every parameter to every hook must be used by an existing open source security module? If so, then yes, this hook can be dropped.

Linus traditionally uses a keep it simple approach and so far that has helped a lot to keep the system in a maintainable state. Given that these `hooks allow plugin in large, unaudited codebases like selinux or even propritary modules this seems even more important to me.

Quoted 6 lines

In sys_create_module, you only know the name and size of the module and who is performing the operation. In sys_init_module, you actually have information about the module available. Hence, you can make a finer-grained decision in the module_initialize hook, and possibly deny even after a successful module_create. As above, SELinux doesn't use these hooks presently.

And WTF is the use a security policy that checks module arguments? Do you want to disallow options that are quotes from books on the index or not political correct enough for a US state agency?

#3 lore raw
In reply to Christoph Hellwig
Quoted 5 lines · Christoph Hellwig
Quoted 2 lines

capable is needed to be checked, as we are not modifying the existing permission logic.

I odn't think it makes sense to have two security checks that both end up in the LSM code after each other..

For cases like the module_* hooks, and the other examples you pointed out, I agree.

For other cases, capable() is just not fine grained enough to actually know what is going on (like CAP_SYS_ADMIN). In those cases you need an extra hook to determine where in the kernel you are.

thanks,

greg k-h

#4 lore raw
Quoted 6 lines · Greg KH

For cases like the module_* hooks, and the other examples you pointed out, I agree.

For other cases, capable() is just not fine grained enough to actually know what is going on (like CAP_SYS_ADMIN). In those cases you need an extra hook to determine where in the kernel you are.

Either we make capable fine grained enough (64 or 128bit capability vectors, I have some old code for that around and I know SGI used that more than a year ago) or we replace the capable in those cases with hooks entirely.

#5 lore raw
Quoted 4 lines · Christoph Hellwig
Quoted 3 lines · Greg KH

For cases like the module_* hooks, and the other examples you pointed out, I agree.

Quoted 8 lines
Quoted 3 lines

For other cases, capable() is just not fine grained enough to actually know what is going on (like CAP_SYS_ADMIN). In those cases you need an extra hook to determine where in the kernel you are.

Either we make capable fine grained enough (64 or 128bit capability vectors, I have some old code for that around and I know SGI used that more than a year ago) or we replace the capable in those cases with hooks entirely.

I don't have a problem with either of these things, but don't see them being completed any time soon. Unless you have some time to work on this?

thanks,

greg k-h

#9 lore raw
In reply to Christoph Hellwig
Quoted 3 lines · Christoph Hellwig

And WTF is the use a security policy that checks module arguments? Do you want to disallow options that are quotes from books on the index or not political correct enough for a US state agency?

How about a security policy that says:

1) Thou mayest do an 'modprobe wvlan_cs'

2) Thou mayest not do 'modprobe wvlan_cs eth=0'.

'eth=0' causes it to create the interface as 'wvlan0' 'wvlan1' etc rather than 'eth0', 'eth1', etc. This makes a difference if you have iptables rules that say '-i eth+' or '-i wvlan+' that implement different rulesets for wireless and hard-wired connections.

Signature · 3 lines
				Valdis Kletnieks
				Computer Systems Senior Engineer
				Virginia Tech
#10 lore raw
Quoted 8 lines · On Fri, Sep 27, 2002 at 02:09:02PM -0400, [email protected] wrote:
Quoted 3 lines · Christoph Hellwig

And WTF is the use a security policy that checks module arguments? Do you want to disallow options that are quotes from books on the index or not political correct enough for a US state agency?

How about a security policy that says:

Quoted 8 lines

1) Thou mayest do an 'modprobe wvlan_cs'

2) Thou mayest not do 'modprobe wvlan_cs eth=0'.

'eth=0' causes it to create the interface as 'wvlan0' 'wvlan1' etc rather than 'eth0', 'eth1', etc. This makes a difference if you have iptables rules that say '-i eth+' or '-i wvlan+' that implement different rulesets for wireless and hard-wired connections.

So I have to download the driver source and change the parameter to i_m_to_fscking_intelligent_for_the_nsa_eth=0?

#11 lore raw
Quoted 2 lines · Christoph Hellwig

So I have to download the driver source and change the parameter to i_m_to_fscking_intelligent_for_the_nsa_eth=0?

By the same token, at that point you can download the kernel source and build it without LSM. What I showed was a way to bypass the iptables rules set up *WITHOUT REPLACING A MODULE* (which might be detected by tripwire, or totally refused because the LSM rejects any writes in /lib/modules).

Signature · 3 lines
				Valdis Kletnieks
				Computer Systems Senior Engineer
				Virginia Tech
#12 lore raw
Quoted 4 lines · On Fri, Sep 27, 2002 at 02:54:25PM -0400, [email protected] wrote:

By the same token, at that point you can download the kernel source and build it without LSM. What I showed was a way to bypass the iptables rules set up *WITHOUT REPLACING A MODULE* (which might be detected by tripwire, or totally refused because the LSM rejects any writes in /lib/modules).

insmod doesn't require modules to be in /lib/modules. Anyway I could even change the device name _after_ it was loaded. this is linux and not BSD..

Given that we really want to fine-grained control who's netdevice can get what names we'd` better place a hook in dev_alloc_name.

And that's my whole point: LSM adds random hooks all over the place without even thinking what they intend to protect.

#20 lore raw
In reply to Christoph Hellwig
Quoted 4 lines · Christoph Hellwig

In 2.5 LSM hooks are part of the Linux access checks, and any reason to make your patch less intrusive inb 2.4 doesn't apply anymore. Having two checks for the same thing is indeed very bad in will cause harm and maintaince burden in the long term. Don't do it.

So you want to move the 'if (turn_on && !capable(CAP_SYS_RAWIO)) return -EPERM;' from the base kernel into the security module's ioperm() hook function, in addition to whatever additional logic the module may implement? [Assuming for the moment that we kept the ioperm() hook, even though that isn't likely given its current lack of use and architecture-specific nature].

If so, what about the rest of the kernel access checking logic? Do you want all of the permission() logic pushed into the security module's inode_permission() hook function? Do you want the bad_signal() logic pushed into the security module's task_kill() hook function? That kind of change was considered and discussed on linux-security-module long ago, but it will yield a very invasive patch for very little gain. It also requires cleanly separating all access checking logic from functional logic (it is sometimes fairly intertwined) and determining exactly which is which (e.g. is enforcing a read-only mount a security behavior or a functional behavior?).

Quoted 1 line

Show me a useful example that needs this argument.

Do you want every process that can use ioperm() to be able to access the full range of ports accessible by that call? If not, then you need something finer-grained than CAP_SYS_RAWIO. But as I said, we don't presently use this hook, and it is architecture-dependent.

Quoted 3 lines

And WTF is the use a security policy that checks module arguments? Do you want to disallow options that are quotes from books on the index or not political correct enough for a US state agency?

The LSM module_initialize hook is called with a pointer to the kernel's copy of the relocated module image with the struct module header. Hence, the security module is free to perform whatever validation it wants on that image prior to the execution of the init function. But if the criteria is that there must be a specific existing security module that uses the hook, then this one will go away too.

--
Stephen D. Smalley, NAI Labs
[email protected]

#22 lore raw
In reply to Christoph Hellwig
Quoted 11 lines · * Christoph Hellwig ([email protected]) wrote:

Review

Quoted 10 lines
(quoted diff) +6 -1
 	if (turn_on && !capable(CAP_SYS_RAWIO))
 		return -EPERM;
-
+ 
+ 	ret = security_ops->ioperm(from, num, turn_on);
+ 	if (ret) {
+ 		return ret;
+ 	}
+ 
Quoted 3 lines

Sorry, but this is bullshit (like most of the lsm changes). Either you leave the capable in and say it's enough or you add your random hook and remove that one.

I agree, this is the way started, however it touches so much driver code (not to mention core code) that it seemed likely to be rejected. I'm all for replacing capable() calls, but it's not a consistent interface and can't always be simply exchanged. I see no reason not to remove the obvious ones right away.

Quoted 2 lines

Just adding more and more hooks without thinking gets us exactly nowhere except to an unmaintainable codebase.

Your point is well-taken. Of course, we do not want to produce unmaintainable code. The hook creation/placement has been thought about and discussed quite a bit.

Quoted 1 line

Also is there a _real_ need to pass in all the arguments?

It was placed there as an obvious contol point over which ioports could be accessed. We will definitely revisit this since it's not being used.

Quoted 10 lines
Quoted 9 lines

+ * @module_create:
+ * Check the permission before allocating space for a module.
+ * @name contains the module name.
+ * @size contains the module size.
+ * Return 0 if permission is granted.
+ * @module_initialize:
+ * Check permission before initializing a module.
+ * @mod contains a pointer to the module being initialized.
+ * Return 0 if permission is granted.

Quoted 2 lines

Umm, you can't tell me you deny someone to initialize a module he has just created?

Coming from two separate system calls there is no guarantee the callers will be in the same execution domain.

Quoted 10 lines
Quoted 8 lines

+ * @sethostname:
+ * Check permission before the hostname is set to @hostname.
+ * @hostname contains the new hostname
+ * Return 0 if permission is granted.
+ * @setdomainname:
+ * Check permission before the domainname is set to @domainname.
+ * @domainname contains the new domainname
+ * Return 0 if permission is granted.

You don't think this should maybe be just one hook?

sure, uts releated hooks could be collapsed.

Quoted 1 line

You might be allowed to swapon but not swapoff?

yes, again there is no assumption the execution domains would be the same.

Quoted 7 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+static int cap_swapoff (struct swap_info_struct *swap)
+{
+	return 0;
+}

Live would be a lot simple if an unimplemented op would behave as returning zero..

Yes, I agree. We've had a few patches that did this, nothing committed to the LSM tree currently.

thanks,
-chris

Signature · 1 line
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net
#13 lore raw
In reply to Christoph Hellwig
Quoted 1 line · Christoph Hellwig

insmod doesn't require modules to be in /lib/modules.

This would probably be closed by this code in sys_create_module():

        /* check that we have permission to do this */
        error = security_ops->module_ops->create_module(name, size);
        if (error)
                goto err1;

Similarly, there are other hooks that will stop renaming of the interface (I have to admit I haven't had enough caffeine to verify whether doing a /bin/mv to rename an interface will change the name that's presented to the iptables rulesets), or did you have other "rename" methods in mind?

Quoted 2 lines

Given that we really want to fine-grained control who's netdevice can get what names we'd` better place a hook in dev_alloc_name.

However, you're missing the point - I was using that as *AN EXAMPLE* of "you might want to check what parameters are being passed". Are you prepared to make the same sort of analysis for *EVERY* parameter of *every* module, and every combination thereof (including interacting parameters of different modules)?

In order to assert that the hook to check parameters in module loading is useless, you'd have to verify that there exist *NO* modules that can have their security status changed by changing the parameters. And even more importantly, you'd have to make this a permanent restriction on module parameters, which puts the onus on "getting it right" on the module author, rather than on the LSM author who's in a better position to know what is/isn't acceptable for his module.

Quoted 2 lines

And that's my whole point: LSM adds random hooks all over the place without even thinking what they intend to protect.

And quite a bit of thought *did* go into it - a *LOT* of those hooks got added along the way precisely *because* the writers of a module found that they were trying to enforce a policy, and found it could be backdoored by means like module parameters. Yes, there are some hooks that are unused by anything at the current time (and there's discussion on the LSM list about pruning those hooks), but I'll bet if you ask "why is hook XYZ in there?" on the LSM list, somebody will be able to reply with "to close the hole of ABC".

Signature · 3 lines
				Valdis Kletnieks
				Computer Systems Senior Engineer
				Virginia Tech
#14 lore raw
Quoted 10 lines · On Mon, 2002-09-30 at 15:19, [email protected] wrote:
Quoted 1 line · Christoph Hellwig

insmod doesn't require modules to be in /lib/modules.

This would probably be closed by this code in sys_create_module():

        /* check that we have permission to do this */
        error = security_ops->module_ops->create_module(name, size);
        if (error)
                goto err1;

This is part of the problem as ever. The name that is used is meaningless. The module loader needs to make meaningful decisions. That really means it needs to be able to see the actual loaded module. If we go to Rusty's kernel module loader then we can fix this because we can pass the actual module code/data block and sizes to the LSM. At that point the LSM can do meaningful things like GPG.

In the current form you can say that module creation can only be done by the right kind of user, and the program "insmod", but even in this case the module name fed to the LSM seems worthless

#15 lore raw
In reply to [email protected]
Quoted 11 lines · On Mon, Sep 30, 2002 at 10:19:18AM -0400, [email protected] wrote:
Quoted 1 line · Christoph Hellwig

insmod doesn't require modules to be in /lib/modules.

This would probably be closed by this code in sys_create_module():

        /* check that we have permission to do this */
        error = security_ops->module_ops->create_module(name, size);
        if (error)
                goto err1;

It wouldn't. sys_create_module doesn't get the absolute path of the module passed.

Quoted 4 lines

Similarly, there are other hooks that will stop renaming of the interface (I have to admit I haven't had enough caffeine to verify whether doing a /bin/mv to rename an interface will change the name that's presented to the iptables rulesets), or did you have other "rename" methods in mind?

For gods sake, what interface do you want to /bin/mv? network device don't have associated special files in Linux (or BSD). I'm talking about SIOCSIFNAME.

Quoted 5 lines

However, you're missing the point - I was using that as *AN EXAMPLE* of "you might want to check what parameters are being passed". Are you prepared to make the same sort of analysis for *EVERY* parameter of *every* module, and every combination thereof (including interacting parameters of different modules)?

If I wanted to implement a trusted system: yes. I you wanted and paid me enough for it: also yes. And that's exactly my point. If you want a trusted system you're not done by adding a few hooks in places that look strategic, you have to a proper audit of _all_ code in your project.

Let me repeat _ALL_ code. Yes, you have to understand WTF is going on, and that's where LSM fail miserably.

Quoted 3 lines

In order to assert that the hook to check parameters in module loading is useless, you'd have to verify that there exist *NO* modules that can have their security status changed by changing the parameters.

Noooh! You got something very wrong. You (or rather the LSM people) want to add a new feature, and they have to prove it useful. An as long as there is no standard on what a specific string in a module option means for the kernel in the end such a check is pretty damn useless.

Quoted 5 lines

And even more importantly,
you'd have to make this a permanent restriction on module parameters, which puts the onus on "getting it right" on the module author, rather than on the LSM author who's in a better position to know what is/isn't acceptable for his module.

How does the lsm author know what the option x=y means for my module? In my module a it means print lots of nice windowish nagscreen, but in my friend Paul's module (who works for the German BND) it means scribble all over my disk because only someone who has stolen the notebook might be stupid enough to use such a silly option.

See what I mean?

Quoted 6 lines

And quite a bit of thought *did* go into it - a *LOT* of those hooks got added along the way precisely *because* the writers of a module found that they were trying to enforce a policy, and found it could be backdoored by means like module parameters.

From my reading of the LSM lists a hgook usually got added because author A

of the unaudited module B though that it might help him in imlpementing what he and only he thinks his module should do if it worked properly.

#21 lore raw
In reply to Stephen Smalley
Quoted 6 lines · Stephen Smalley

So you want to move the 'if (turn_on && !capable(CAP_SYS_RAWIO)) return -EPERM;' from the base kernel into the security module's ioperm() hook function, in addition to whatever additional logic the module may implement? [Assuming for the moment that we kept the ioperm() hook, even though that isn't likely given its current lack of use and architecture-specific nature].

Exactly.

Quoted 4 lines

If so, what about the rest of the kernel access checking logic? Do you want all of the permission() logic pushed into the security module's inode_permission() hook function?

permission() switches into per-fs code.

Quoted 2 lines

Do you want the bad_signal() logic
pushed into the security module's task_kill() hook function?

Only the capable() check. Unless of course we make uid/gid checking optional. Which seems like a very bad idea given the mess even with just the current LSM hooks.

Quoted 6 lines

That kind of
change was considered and discussed on linux-security-module long ago, but it will yield a very invasive patch for very little gain. It also requires cleanly separating all access checking logic from functional logic (it is sometimes fairly intertwined) and determining exactly which is which

Umm. Clean and nicely separated code is a lot of gain. Making Linux's access clean instead of a lot more messy is a good think. Much better than any feature addition. (Unless, of course, you get paid for adding features..)

Quoted 2 lines

(e.g. is enforcing a read-only mount a security behavior or a functional behavior?).

For the kernel it's a functional behavior. The administrator can chose to apply it for security reasons, but that's policy and thus not the kernel's issue.

Quoted 7 lines
Quoted 2 lines

Show me a useful example that needs this argument.

Do you want every process that can use ioperm() to be able to access the full range of ports accessible by that call? If not, then you need something finer-grained than CAP_SYS_RAWIO. But as I said, we don't presently use this hook, and it is architecture-dependent.

Okay, this does actually makes sense. Point taken.

Quoted 11 lines
Quoted 4 lines

And WTF is the use a security policy that checks module arguments? Do you want to disallow options that are quotes from books on the index or not political correct enough for a US state agency?

The LSM module_initialize hook is called with a pointer to the kernel's copy of the relocated module image with the struct module header. Hence, the security module is free to perform whatever validation it wants on that image prior to the execution of the init function. But if the criteria is that there must be a specific existing security module that uses the hook, then this one will go away too.

Yes, a hook without a intree user or at least a properly defined and available out-of-tree user is pointless.

#16 lore raw
In reply to Christoph Hellwig
Quoted 2 lines · Christoph Hellwig

For gods sake, what interface do you want to /bin/mv? network device don't have associated special files in Linux (or BSD). I'm talking about SIOCSIFNAME.

Well, I figured that you must have meant something else, since ioctl() is hooked, so an attacker couldn't use THAT method if the security module didn't want him to.

Of course, that means we probably should pull that ioctl() hook too, since obviously there's ways to bypass it. And at that point, we may as well pull the OTHER hooks too. Hmm.. I'm starting to see a pattern here. ;)

So we shouldn't deploy a check on module parameters to prevent renaming an interface, and we shouldn't bother having OTHER checks to stop it because they could always load a module and bypass it - if you feel THAT strongly that the whole concept of a security framework is that pointless, you're free not to use it. ;)

Quoted 1 line

How does the lsm author know what the option x=y means for my module? In my

Umm.. the same way that *I* noticed that 'eth=0' has a security implication.

It seems to me that you're arguing both sides here - first you say that a full code audit is needed so you know 'WTF is going on', and then you're saying that it's impossible to know.

Either that, or you're saying "yes you can do a code audit, but having identified module parameters that are *KNOWN* to be a problem, you're not allowed to stop them".

Quoted 3 lines

From my reading of the LSM lists a hgook usually got added because author A of the unaudited module B though that it might help him in imlpementing what he and only he thinks his module should do if it worked properly.

OK - so to summarize: You're saying that somebody conceives of a reasonable security model, finds a set of 10 or 15 hooks that implement 95% of what he needs, but there's a code path that a hook doesn't catch that lets a user subvert the model - and then it's a *BAD THING* that the kernel be modified to *actually solve a problem*?

Somehow, this goes against the whole spirit of the Linux kernel - I wonder what miniscule percent of the current kernel wasn't done to solve a problem...

Signature · 3 lines
				Valdis Kletnieks
				Computer Systems Senior Engineer
				Virginia Tech
#17 lore raw
Quoted 8 lines · On Wed, Oct 02, 2002 at 01:55:14PM -0400, [email protected] wrote:
Quoted 2 lines · Christoph Hellwig

For gods sake, what interface do you want to /bin/mv? network device don't have associated special files in Linux (or BSD). I'm talking about SIOCSIFNAME.

Well, I figured that you must have meant something else, since ioctl() is hooked, so an attacker couldn't use THAT method if the security module didn't want him to.

Just that no 'security' module implements a special handler for it. E.g. in selinux it ends up in

		/* default case assumes that the command will go
   		 * to the file's ioctl() function.
      		 */
      		default:
      			error = file_has_perm(current, file, FILE__IOCTL);
Quoted 2 lines

Of course, that means we probably should pull that ioctl() hook too, since obviously there's ways to bypass it.

Right. an hook for ->ioctl() is completly useless. Remember that ioctl is nothing but a magic backdoor to add syscalls. You need to do the permission check in code that actually knows what it is doing, not in the dispatcher.

Quoted 3 lines

So we shouldn't deploy a check on module parameters to prevent renaming an interface, and we shouldn't bother having OTHER checks to stop it because they could always load a module and bypass it

You should add a check where the name isactually assigned in this case. Not that I think a check on the device name is generally a good idea..

Quoted 3 lines

- if you feel THAT
strongly that the whole concept of a security framework is that pointless, you're free not to use it. ;)

You've missed the point. I never wanted to use it. I care about the crap that it adds to the kernel which I do want to use, develop and keep clean.

Quoted 3 lines
Quoted 1 line

How does the lsm author know what the option x=y means for my module? In my

Umm.. the same way that *I* noticed that 'eth=0' has a security implication.

Without ever seeing that module?

Quoted 3 lines

It seems to me that you're arguing both sides here - first you say that a full code audit is needed so you know 'WTF is going on', and then you're saying that it's impossible to know.

The person who performs the audit can know it. But how often will that be the author of the LSM module?

Quoted 5 lines

OK - so to summarize: You're saying that somebody conceives of a reasonable security model, finds a set of 10 or 15 hooks that implement 95% of what he needs, but there's a code path that a hook doesn't catch that lets a user subvert the model - and then it's a *BAD THING* that the kernel be modified to *actually solve a problem*?

It's not bad to solve a problem. It's a bad idea trying to 'solve' a problem you don';t understand fully.

Quoted 2 lines

Somehow, this goes against the whole spirit of the Linux kernel - I wonder what miniscule percent of the current kernel wasn't done to solve a problem...

Adding random hack without resolving the underlying problem is not the way linux kernel development usually works.

#18 lore raw
Quoted 6 lines · Christoph Hellwig
Quoted 3 lines

It seems to me that you're arguing both sides here - first you say that a full code audit is needed so you know 'WTF is going on', and then you're saying that it's impossible to know.

The person who performs the audit can know it. But how often will that be the author of the LSM module?

We've said on this list a few times that it is important for security module authors to understand the implications of their decisions. Deciding to not mediate module parameters is a valid decision. Deciding to mediate module parameters is a valid decision. One requires very little thought and sidesteps the matter entirely. The other requires quite a bit of thought and is difficult to get right -- but that is not a problem for LSM, per se; it is for the authors of security modules.

Signature · 1 line
http://immunix.org/
#19 lore raw
Quoted 7 lines · Seth Arnold

We've said on this list a few times that it is important for security module authors to understand the implications of their decisions. Deciding to not mediate module parameters is a valid decision. Deciding to mediate module parameters is a valid decision. One requires very little thought and sidesteps the matter entirely. The other requires quite a bit of thought and is difficult to get right -- but that is not a problem for LSM, per se; it is for the authors of security modules.

In many cases I disagree. Garbage in - garbage out. That goes for security policy decisions as well as the revenue. The security modules must get data that is sufficient to make the decision, locked correctly and with a defined scope and lifespan.

For example passing an ascii path without thought is useless because you would race name lookups against things like symlinks. The same goes for audit stuff which is one of the reasons snare needs a lot of work yet

Alan