2010-02-26 14:56:37

by wzt wzt

[permalink] [raw]
Subject: [PATCH] Security: Add __init to register_security to disable load a security module on runtime

LSM framework doesn't allow to load a security module on runtime, it must be loaded on boot time.
but in security/security.c:
int register_security(struct security_operations *ops)
{
...
if (security_ops != &default_security_ops)
return -EAGAIN;
...
}
if security_ops == &default_security_ops, it can access to register a security module. If selinux is enabled,
other security modules can't register, but if selinux is disabled on boot time, the security_ops was set to
default_security_ops, LSM allows other kernel modules to use register_security() to register a not trust
security module. For example:

disable selinux on boot time(selinux=0).

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/security.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("wzt");

extern int register_security(struct security_operations *ops);
int (*new_register_security)(struct security_operations *ops);

int rootkit_bprm_check_security(struct linux_binprm *bprm)
{
return 0;
}

struct security_operations rootkit_ops = {
.bprm_check_security = rootkit_bprm_check_security,
};

static int rootkit_init(void)
{
printk("Load LSM rootkit module.\n");

/* cat /proc/kallsyms | grep register_security */
new_register_security = 0xc0756689;
if (new_register_security(&rootkit_ops)) {
printk("Can't register rootkit module.\n");
return 0;
}
printk("Register rootkit module ok.\n");

return 0;
}

static void rootkit_exit(void)
{
printk("Unload LSM rootkit module.\n");
}

module_init(rootkit_init);
module_exit(rootkit_exit);

Signed-off-by: Zhitong Wang <[email protected]>

---
security/security.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/security/security.c b/security/security.c
index 122b748..7da630a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -110,7 +110,7 @@ int __init security_module_enable(struct security_operations *ops)
* If there is already a security module registered with the kernel,
* an error will be returned. Otherwise %0 is returned on success.
*/
-int register_security(struct security_operations *ops)
+int __init register_security(struct security_operations *ops)
{
if (verify(ops)) {
printk(KERN_DEBUG "%s could not verify "
--
1.6.5.3


2010-02-27 01:52:34

by Tetsuo Handa

[permalink] [raw]
Subject: Re: [PATCH] Security: Add __init to register_security to disable load a security module on runtime

Zhitong Wang wrote:
> LSM framework doesn't allow to load a security module on runtime, it must be loaded on boot time.
> but in security/security.c:
> int register_security(struct security_operations *ops)
> {
> ...
> if (security_ops != &default_security_ops)
> return -EAGAIN;
> ...
> }
> if security_ops == &default_security_ops, it can access to register a security module. If selinux is enabled,
> other security modules can't register, but if selinux is disabled on boot time, the security_ops was set to
> default_security_ops, LSM allows other kernel modules to use register_security() to register a not trust
> security module. For example:
>
> disable selinux on boot time(selinux=0).

That won't become a problem unless kernel command line is tampered.
Giving permissions to tamper kernel command line is the problem.

There are malicious security modules, but non malicious in-tree security
modules are bothered by two limitations since register_security() is not
exported to kernel modules since 2.6.24 .

One is the size of vmlinux. Since all security modules have to be compiled
into vmlinux, it makes difficult for distributors to include multiple security
modules into vmlinux when there is vmlinux's size limitation. A well-known
distributor is now considering including TOMOYO in addition to SELinux, but
the size limitation of vmlinux seems to be the only problem that prevents
inclusion.

The other is the support provided by distributors. Another well-known
distributor's support policy is that "We don't provide any support if vmlinux
or kernel modules provided by us are recompiled. But we provide support if
kernel modules provided by third party are used without modifying vmlinux and
kernel modules provided by us." This means that the only way to allow users to
use TOMOYO with distributor's support is to convince the distributor to include
TOMOYO into vmlinux. This is a very difficult problem since the distributor
recommends SELinux.

Honestly speaking, I prefer register_security() being exported to kernel
modules.

2010-02-27 03:02:42

by wzt wzt

[permalink] [raw]
Subject: Re: [PATCH] Security: Add __init to register_security to disable load a security module on runtime

>That won't become a problem unless kernel command line is tampered.
>Giving permissions to tamper kernel command line is the problem.

The user also can modify /etc/selinuc/config, set SELINUX=disabled.

>Honestly speaking, I prefer register_security() being exported to kernel modules.

New kernel doesn't export register_security() to kernel modules
anymore. For some reason the user disabled selinux, so the malicious
security modules have a chance to loaded on runtime. LSM original
intention is not allowed to load security modules on runtime, right?
But if selinux is disabled, they can.

On Sat, Feb 27, 2010 at 9:52 AM, Tetsuo Handa
<[email protected]> wrote:
> Zhitong Wang wrote:
>> LSM framework doesn't allow to load a security module on runtime, it must be loaded on boot time.
>> but in security/security.c:
>> int register_security(struct security_operations *ops)
>> {
>>         ...
>>         if (security_ops != &default_security_ops)
>>                 return -EAGAIN;
>>         ...
>> }
>> if security_ops == &default_security_ops, it can access to register a security module. If selinux is enabled,
>> other security modules can't register, but if selinux is disabled on boot time, the security_ops was set to
>> default_security_ops, LSM allows other kernel modules to use register_security() to register a not trust
>> security module. For example:
>>
>> disable selinux on boot time(selinux=0).
>
> That won't become a problem unless kernel command line is tampered.
> Giving permissions to tamper kernel command line is the problem.
>
> There are malicious security modules, but non malicious in-tree security
> modules are bothered by two limitations since register_security() is not
> exported to kernel modules since 2.6.24 .
>
> One is the size of vmlinux. Since all security modules have to be compiled
> into vmlinux, it makes difficult for distributors to include multiple security
> modules into vmlinux when there is vmlinux's size limitation. A well-known
> distributor is now considering including TOMOYO in addition to SELinux, but
> the size limitation of vmlinux seems to be the only problem that prevents
> inclusion.
>
> The other is the support provided by distributors. Another well-known
> distributor's support policy is that "We don't provide any support if vmlinux
> or kernel modules provided by us are recompiled. But we provide support if
> kernel modules provided by third party are used without modifying vmlinux and
> kernel modules provided by us." This means that the only way to allow users to
> use TOMOYO with distributor's support is to convince the distributor to include
> TOMOYO into vmlinux. This is a very difficult problem since the distributor
> recommends SELinux.
>
> Honestly speaking, I prefer register_security() being exported to kernel
> modules.
>

2010-02-27 06:30:11

by Tetsuo Handa

[permalink] [raw]
Subject: Re: [PATCH] Security: Add __init to register_security to disable load a security module on runtime

Zhitong Wang wrote:
> LSM original intention is not allowed to load security modules on runtime, right?

My understanding is that the reason register_security() became no longer
exported to loadable kernel modules is the difficulty of cleanly
initializing/finalizing security modules since security modules usually
allocate/release memory on various structures. When that change happened
(i.e. as of 2.6.24), SELinux was the only in-tree LSM user.

Those security modules which needn't to allocate/release memory on various
structures can be loaded on runtime, if register_security() is exported to
loadable kernel modules.

If a distribution user adds a loadable kernel module (which is not a security
module) which distributor didn't select, the user can get distributor's support
except problems caused by that module.

However, due to limitation that security modules cannot be added as loadable
kernel modules, when a distribution user wants to select security modules which
distributor didn't select, distributor's support is no longer provided
(i.e. not only problems caused by the security modules selected by the user
but also problems caused by the rest of kernel and userland).

What's the difference between a kernel module which uses LSM and a kernel
module which does not use LSM? Any kernel modules can cause severe problems.

My understanding is that LSM's original intention is to allow Linux users to
select security modules. Why LSM places security modules under adverse condition?

2010-02-28 05:56:39

by wzt wzt

[permalink] [raw]
Subject: Re: [PATCH] Security: Add __init to register_security to disable load a security module on runtime

Load a security module on runtime is not safe on SMP systems, LSM
framework doesn't have any locks.

On Sat, Feb 27, 2010 at 2:30 PM, Tetsuo Handa
<[email protected]> wrote:
> Zhitong Wang wrote:
>> LSM original intention is not allowed to load security modules on runtime, right?
>
> My understanding is that the reason register_security() became no longer
> exported to loadable kernel modules is the difficulty of cleanly
> initializing/finalizing security modules since security modules usually
> allocate/release memory on various structures. When that change happened
> (i.e. as of 2.6.24), SELinux was the only in-tree LSM user.
>
> Those security modules which needn't to allocate/release memory on various
> structures can be loaded on runtime, if register_security() is exported to
> loadable kernel modules.
>
> If a distribution user adds a loadable kernel module (which is not a security
> module) which distributor didn't select, the user can get distributor's support
> except problems caused by that module.
>
> However, due to limitation that security modules cannot be added as loadable
> kernel modules, when a distribution user wants to select security modules which
> distributor didn't select, distributor's support is no longer provided
> (i.e. not only problems caused by the security modules selected by the user
> but also problems caused by the rest of kernel and userland).
>
> What's the difference between a kernel module which uses LSM and a kernel
> module which does not use LSM? Any kernel modules can cause severe problems.
>
> My understanding is that LSM's original intention is to allow Linux users to
> select security modules. Why LSM places security modules under adverse condition?
>

2010-02-28 06:35:36

by Tetsuo Handa

[permalink] [raw]
Subject: Re: [PATCH] Security: Add __init to register_security to disable load a security module on runtime

Zhitong Wang wrote:
> Load a security module on runtime is not safe on SMP systems, LSM
> framework doesn't have any locks.

Unloading security module on runtime would be difficult. But loading security
module on runtime is not impossible. A security module can be loaded inside
initramfs if the security module provides appropriate lock.

When AppArmor get merged into mainline, do you want to bother distributors
about size of vmlinux when some wants to use SELinux, some wants to use Smack,
some wants to use TOMOYO, and some wants to use AppArmor. All of them have to
be built-in but only one of them can be enabled.

I think we should allow security modules to be loaded on runtime, if security
modules can provide appropriate lock for SMP-safe initialization.