On Sun, Sep 26, 2010 at 7:46 AM, Tetsuo Handa <[email protected]> wrote: > > Radoslaw Szkodzinski wrote: > > The hook would check the mask of the argument of mprotect, rejecting > > PROT_EXEC | PROT_WRITE, check whether a formerly PROT_WRITE page is > > being now mprotect()ed to PROT_EXEC > > or vice versa. > > It will be possible to reject A-2 and B-2 below > > (Step A-1) Create a vma as PROT_WRITE . > (Step A-2) Change that vma to PROT_EXECUTE . > > (Step B-1) Create a vma as PROT_EXECUTE . > (Step B-2) Change that vma to PROT_WRITE . > > by doing >
Do not touch vm_flags directly. grSecurity does that, because it's not an LSM hook... As I said before, mainline developers might not like touching them from a hook. Fixed: if ((reqprot & (VM_MAYWRITE | VM_MAYEXEC)) ^ (prot & (VM_MAYWRITE | VM_MAYEXEC))) && > !ccs_capable(CCS_USE_WRITABLE_EXECUTABLE_VMA)) > return -EPERM; (or possibly with the check of vma->vm_flags_ever_specified like that below ;) ) This means that pages already marked write and executable would stay that way and not throw -EPERM when being marked VM_MAYREAD. > > inside security_file_mprotect(vma, reqprot, prot). > > But it is impossible to reject C-3 below > > (Step C-1) Create a vma as PROT_WRITE . > (Step C-2) Change that vma to PROT_READ . > (Step C-3) Change that vma to PROT_READ|PROT_EXECUTE . > Correct, this needs storage of the flags ever set on said mapping. grSecurity seems to have a hole here. > unless "struct vm_area_struct" has a variable which remembers the bitwise OR > of > PROT_* flags ever specified since the moment a vma was created. I need to add Yes, exactly, that would close the hole if there were such a bitfield... That would go into vm_area_struct. > Also, I think > > (Step D-1) Create a vma as PROT_WRITE|PROT_EXECUTE . > > is possible by using mmap(). Yes, but only of an anonymous mapping, file mapping can be stopped with deny_open. This should be caught too, possibly by adding a new LSM hook... > If D-1 is possible, checking it at security_file_mprotect() is not sufficient. > What do you think? It isn't, but combined with a proposed security_mmap() hook it would be. > > > This means the all time state of access bits has to be checked. > > For the implementation, you could take a look at PaX (grSecurity) > > mprotect protection, > > here: http://www.grsecurity.net/~paxguy1/ > > Look for CONFIG_PAX_MPROTECT. > > TOMOYO touches only arch independent part. > CONFIG_PAX_MPROTECT is arch dependent and too complicated for me. No, PAX_MPROTECT alone isn't arch-dependent, rest of the PaX is. CONFIG_PAX_MPROTECT touches two files, fs/binfmt_elf.c (to check its enable/disable flag) and mm/mprotect.c. > (You can enable PaX and TOMOYO at the same time if you want to do so.) Except PaX isn't mainline and TOMOYO somewhat is. :-) Also, most of PaX is redundant now and useful only on older x86 machines without NX bit, kernel since about 2.6.25 has Exec Shield which provides a bit worse emulation of NX bit than PaX on machines without it and also provides ASLR. There are other useful things in PaX too, like port randomization, but those aren't critical and can be done elsewhere (e.g. with netfilter). > > > Especially elf_handle_mprotect() in the first file which would become your > > security_file_mprotect() with minor changes... but the problem is how > > to match vma to the domain. > > [File fs/binfmt_elf.c, line 29013 of the 2.6.35.4 patch.] > > > > If CONFIG_MM_OWNER is defined (select it in Kconfig), you could use > > vma->vm_mm->owner to find out which task the mapping belongs to, > > and then check its domain for the flags. > > If it's not defined, I'm not sure how to find out who owns the mapping > > from the hook. > > TOMOYO simply validates arguments passed to syscalls. TOMOYO does not track > owner of objects. TOMOYO tracks only subjects using domainnames > (e.g. <kernel> /usr/sbin/httpd ). I think CONFIG_MM_OWNER=n is not a problem. But the security_file_mprotect hook doesn't have a "domain" argument or anything linking the mapping directly to the task, neither does vm_addr_struct. How can you get domain info without the domain name? :) > Please be sure to call fflush() after writing a line (or use line buffering > mode) > if your appliocation's write method does not call write() syscall. Appreciated. > I tried to let /usr/sbin/ccs-queryd search a database and reply if $retry is 0 > and let /usr/sbin/ccs-queryd ask the user what to do if $retry is not 0. But I > haven't implemented it yet and therefore some dead code exists in queryd.c . > You can just ignore it. In fact, I want to implement exactly this, but a bit more involved. Client uses a proposed ccs-ask-daemon, which connects to ccs-queryd (with TLS authentication), sending the uid. ccs-queryd then sends all requests that are marked as "ask about it" and concern a process owned by that uid to the socket of ccs-ask-daemon. The other thing missing is a policy definition like an ability to enable or disable the prompt in the policy file, e.g. ask_permission no_ask_permission It'd be also nice to have allow_stat for listing the directories without allowing file read. > /usr/sbin/ccs-queryd supports monitoring remote machines (e.g. embedded > devices > running on emulator). ccs-editpolicy-agent can be used for waiting for TCP > connections from ccs-loadpolicy/ccs-editpolicy/ccs-savepolicy/ccs-queryd etc. > on remote machines. Its communication protocol is very simple. Sounds similar to what I want to do, but not exactly what I need. > I think you don't need to implement this feature for now. > Those who can use emulator know how to use CUI. Yes, but I'm not targetting users of emulators, but users in general, say, a typical Ubuntu user of Firefox, so that I could write: (in enforcing mode) <kernel> no_ask_permission # possibly default <kernel> /usr/lib/firefox/firefox-bin allow_read cookies allow_write cookies ... allow_network ... allow_transit /uid:1234 /usr/lib/firefox/firefox-bin if task.uid=1234 allow_transit /uid:777 /usr/lib/firefox/firefox-bin if task.uid=2345 allow_execute /usr/lib/firefox/plugin-container ask_permission <kernel> /usr/lib/firefox/firefox-bin /usr/lib/firefox/plugin-container allow_stat /store/downloads allow_write /store/downloads allow_execute flash allow_execute java ... ask_permission <kernel> /uid:1234 /usr/lib/firefox/firefox-bin allow_write /home/1234/downloads allow_read /home/1234/downloads allow_chmod 0770 /home/1234/downloads # to allow overwriting allow_rename /home/1234/downloads/* /home/1234/downloads/* ask_permission Then when, say, Flash or Java attempts to connect or open a socket, it will ask the user. The ccs-ask-daemon part could additionally filter what it asks about, and what it denies or allows automatically per user Or when firefox attempts to read or write something that's not in the downloads. _______________________________________________ tomoyo-users-en mailing list [email protected] http://lists.sourceforge.jp/mailman/listinfo/tomoyo-users-en
