| From: |
| Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> |
| To: |
| linux-security-module@vger.kernel.org, linux-fsdevel@vger.kernel.org |
| Subject: |
| [RFC] LSM/TOMOYO: LSM hooks for chmod/chown/chroot/mount/open/execve |
| Date: |
| Sun, 6 Sep 2009 14:28:50 +0900 |
| Archive-link: |
| Article, Thread
|
Hello.
I released TOMOYO 1.7.0 (non-LSM version of TOMOYO Linux).
http://sourceforge.jp/projects/tomoyo/lists/archive/users...
Before resuming TOMOYO 2.x (LSM version of TOMOYO Linux), I'd like to show you
what hooks I want to pick up from http://sourceforge.jp/projects/tomoyo/svn/view/trunk/1.7.... .
(1) TOMOYO 1.7 checks chmod()/chown()/chgrp() operations, and I'm planning to
check them in TOMOYO 2.x as well. Thus I'd like to add
security_path_chmod() in SYSCALL_DEFINE2(fchmod, ...) and
SYSCALL_DEFINE3(fchmodat, ...).
security_path_chown() in SYSCALL_DEFINE3(chown, ...) and
SYSCALL_DEFINE5(fchownat, ...) and SYSCALL_DEFINE3(lchown, ...) and
SYSCALL_DEFINE3(fchown, ...).
(2) TOMOYO 1.x checks chroot() operations, and I'm planning to check it in
TOMOYO 2.x as well. Thus I'd like to add
security_path_chroot() in SYSCALL_DEFINE1(chroot, ...).
(3) TOMOYO 1.x checks mount() operations with original mount 'flags'.
Currently, security_sb_mount() receives 'flags & ~(MS_NOSUID | MS_NOEXEC |
MS_NODEV | MS_ACTIVE | MS_NOATIME | MS_NODIRATIME | MS_RELATIME |
MS_KERNMOUNT | MS_STRICTATIME)'. I want to pass original mount 'flags' to
LSM hook.
(4) TOMOYO has unique set of permissions different from read/write/execute.
TOMOYO 1.7 doesn't check read/write permissions for open(pathname, 3)
because TOMOYO 1.7 instead checks ioctl permission. I'm planning to
implement it in TOMOYO 2.x as well. Currently, original flags passed to
open() is not passed to LSM hooks. Thus, TOMOYO 2.x can't tell
open(pathname, 3) from open(pathname, 2). I want to pass original lower
2 bits of flags to LSM so that TOMOYO 2.x can distinguish open for
read/write/ioctl and open for ioctl only.
(5) TOMOYO 1.6/1.7 have "execute handler". I'm planning to implement it in
TOMOYO 2.x as well. The "execute handler" is a mechanism for executing
a program which is different from a program passed to execve().
What this mechanism is doing is similar to load_script() defined in
fs/binfmt_script.c .
http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/security/...
The idea of this mechanism comes from anti-shellcode technique.
An old exploit program for Samba's trans2open vulnerability attempts to
execute /bin/sh . If there is no MAC, /bin/sh is executed. If there is MAC
and it rejects execution of /bin/sh from /usr/sbin/smbd , the exploit
program cannot execute /bin/sh . However, the exploit code repeats execute
request of /bin/sh until it succeeds. As a result, the victim process eats
100% of CPU resources.
If a process was hijacked by an exploit code, rejecting execve() request
unlikely recovers the hijacked process's control. In other words, returning
control back to the hijacked process is not useful. Then, I thought we have
a chance to do something better (by executing a different program) than
simply wasting CPU resource (by rejecting execve() requests forever).
After I came up to "execute handler" idea, I found another usage.
I found that we can use "execute handler" for validating (and manipulating)
parameters passed to execve() (e.g. file descriptors/argv[]/envp[]).
Although there is a disadvantage that there is no way to tell the caller
of execve() that the requested program was not executed, I verified that
"execute handler" is useful using TOMOYO 1.6 .
In some environments, /bin/egrep is implemented as
#!/bin/sh
exec grep -E ${1+"$@"}
which simply executes the requested program with modified command line.
An "execute handler" is implemented something like
#!/bin/sh
check_whether_to_execute_originally_requested_program_or_not || exit 1
exec originally_requested_program some_parameters
Unlike load_script(), I can't call search_binary_handler() from LSM hooks
because I can't let LSM hooks say "you don't need to call
search_binary_handler() because I already called search_binary_handler()".
This means that I can't use stack memory for remembering bprm->filename and
bprm->interp . Thus, I need to use kmalloc() and a LSM hook for kfree().
Which approach is better you think?
(a) Add post-execve() hook which is called after search_binary_handler()
finished. This approach can avoid addition of member to cred->security
that is only valid during execve().
(b) Hold the pointer to kmalloc()ed memory within bprm->cred->security and
kfree() the pointer at security_bprm_committing_creds().
This approach can avoid addition of new LSM hook.
(6) TOMOYO 1.6/1.7 have "process state variables". I'm planning to implement it
in TOMOYO 2.x as well. The "process state variables" is used for tracking
current process's state (to avoid "execute handler" loop etc.) and for
associating different permissions according to the process's behavior.
Which approach is better you think?
(a) Add per "struct task_struct" variable like
http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/l... .
This approach can simplify the code because we don't need to care about
error paths (prepare_creds() failures).
(b) Hold the variable within cred->security .
This approach can avoid modification of "struct task_struct".
Regards.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html