(I modified subject line in order to split this thread into "mprotect restriction" part and "simple GUI for learning mode" part. This is the "mprotect restriction" part.)
Radoslaw Szkodzinski wrote: > 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... I don't modify vm_flags. I modify only vm_flags_ever_specified. What does "touch vm_flags" mean? Do you mean not only "modifying vm_flags" but also "reading vm_flags"? > 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 > ;) ) > I think vma->vm_flags_ever_specified is needed in order to handle C-3 . > This means that pages already marked write and executable would stay > that way and not throw -EPERM > when being marked VM_MAYREAD. > Why not to throw -EPERM? > > > > 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. > I see. > > 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. > As of 2.6.36-rc5, there are 6 callers of security_file_mmap(). However, only do_mmap_pgoff() (which is called by mmap() syscall in mm/mmap.c) and validate_mmap_request() (which is called by do_mmap_pgoff() which is called by mmap() syscall in mm/nommu.c) receive reqprot and prot arguments. 965 unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, 966 unsigned long len, unsigned long prot, 967 unsigned long flags, unsigned long pgoff) (...snipped...) 1095 error = security_file_mmap(file, reqprot, prot, flags, addr, 0); 1096 if (error) 1097 return error; 1098 1099 return mmap_region(file, addr, len, flags, vm_flags, pgoff); 815 static int validate_mmap_request(struct file *file, 816 unsigned long addr, 817 unsigned long len, 818 unsigned long prot, 819 unsigned long flags, 820 unsigned long pgoff, 821 unsigned long *_capabilities) (...snipped...) 982 ret = security_file_mmap(file, reqprot, prot, flags, addr, 0); Therefore, I think that checking VM_MAYWRITE | VM_MAYEXEC inside existing security_file_mmap() can cover D-1. Doing vma->vm_flags_ever_specified |= vma->vm_flags; if (((vma->vm_flags_ever_specified | (prot << 4)) & (VM_MAYWRITE | VM_MAYEXEC)) == (VM_MAYWRITE | VM_MAYEXEC) && !ccs_capable(CCS_USE_WRITABLE_EXECUTABLE_VMA)) return -EPERM; inside security_file_mmap() is not needed because the vma is not yet created. After all, what I need to do are add unsigned long vm_flags_ever_specified; to "struct vm_area_struct" and do if ((prot << 4) & (VM_MAYWRITE | VM_MAYEXEC)) == (VM_MAYWRITE | VM_MAYEXEC) && !ccs_capable(CCS_USE_WRITABLE_EXECUTABLE_VMA)) return -EPERM; inside security_file_mmap(file, reqprot, prot, flags, addr, addr_only) and do vma->vm_flags_ever_specified |= vma->vm_flags; if (((vma->vm_flags_ever_specified | (prot << 4)) & (VM_MAYWRITE | VM_MAYEXEC)) == (VM_MAYWRITE | VM_MAYEXEC) && !ccs_capable(CCS_USE_WRITABLE_EXECUTABLE_VMA)) return -EPERM; inside security_file_mprotect(vma, reqprot, prot). What do you think? > 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. config PAX_MPROTECT depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) and config PAX_PAGEEXEC depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MATOM || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7) and config PAX_SEGMEXEC depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32 . It seems to me that I can't clone code from PAX_MPROTECT without limiting archs. > > 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? :) > I couldn't understand it. What TOMOYO will control is whether current thread is allowed to specify PROT_WRITE|PROTO_EXEC when creating a VMA using mmap() syscall PROT_WRITE when modifying an existing VMA which ever had PROT_EXEC in the past using mprotect() syscall PROT_EXEC when modifying an existing VMA which ever had PROT_WRITE in the past using mprotect() syscall or not. TOMOYO doesn't care who owns a VMA (as with who created a file, whereas inode-based security cares it by allocating memory and using xattr on filesystems). TOMOYO's domainname is derived from "struct task_struct"->ccs_domain_info . Regards. _______________________________________________ tomoyo-users-en mailing list [email protected] http://lists.sourceforge.jp/mailman/listinfo/tomoyo-users-en
