X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=security%2Fcommoncap.c;h=cd90b22d738186a430587c585b9e4f4f58abff1d;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=f40fc73705d09bdae590e83d22b9ac5041da528d;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/security/commoncap.c b/security/commoncap.c index f40fc7370..cd90b22d7 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -7,6 +7,7 @@ * */ +#include #include #include #include @@ -24,23 +25,45 @@ #include #include +int cap_netlink_send(struct sock *sk, struct sk_buff *skb) +{ + NETLINK_CB(skb).eff_cap = current->cap_effective; + return 0; +} + +EXPORT_SYMBOL(cap_netlink_send); + +int cap_netlink_recv(struct sk_buff *skb) +{ + if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) + return -EPERM; + return 0; +} + +EXPORT_SYMBOL(cap_netlink_recv); + int cap_capable (struct task_struct *tsk, int cap) { /* Derived from include/linux/sched.h:capable. */ - if (cap_raised (tsk->cap_effective, cap)) + if (cap_raised(tsk->cap_effective, cap)) return 0; - else + return -EPERM; +} + +int cap_settime(struct timespec *ts, struct timezone *tz) +{ + if (!capable(CAP_SYS_TIME)) return -EPERM; + return 0; } int cap_ptrace (struct task_struct *parent, struct task_struct *child) { /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */ - if (!cap_issubset (child->cap_permitted, current->cap_permitted) && - !capable (CAP_SYS_PTRACE)) + if (!cap_issubset(child->cap_permitted, parent->cap_permitted) && + !__capable(parent, CAP_SYS_PTRACE)) return -EPERM; - else - return 0; + return 0; } int cap_capget (struct task_struct *target, kernel_cap_t *effective, @@ -120,14 +143,14 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) /* Derived from fs/exec.c:compute_creds. */ kernel_cap_t new_permitted, working; - new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); + new_permitted = cap_intersect (bprm->cap_permitted, vx_current_bcaps()); working = cap_intersect (bprm->cap_inheritable, current->cap_inheritable); new_permitted = cap_combine (new_permitted, working); if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || !cap_issubset (new_permitted, current->cap_permitted)) { - current->mm->dumpable = 0; + current->mm->dumpable = suid_dumpable; if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) { if (!capable(CAP_SETUID)) { @@ -289,85 +312,23 @@ void cap_task_reparent_to_init (struct task_struct *p) int cap_syslog (int type) { - if ((type != 3) && !capable(CAP_SYS_ADMIN)) + if ((type != 3 && type != 10) && + !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG)) return -EPERM; return 0; } -/* - * Check that a process has enough memory to allocate a new virtual - * mapping. 0 means there is enough memory for the allocation to - * succeed and -ENOMEM implies there is not. - * - * We currently support three overcommit policies, which are set via the - * vm.overcommit_memory sysctl. See Documentation/vm/overcommit-accounting - * - * Strict overcommit modes added 2002 Feb 26 by Alan Cox. - * Additional code 2002 Jul 20 by Robert Love. - */ int cap_vm_enough_memory(long pages) { - unsigned long free, allowed; - - vm_acct_memory(pages); - - /* - * Sometimes we want to use more memory than we have - */ - if (sysctl_overcommit_memory == 1) - return 0; - - if (sysctl_overcommit_memory == 0) { - unsigned long n; - - free = get_page_cache_size(); - free += nr_swap_pages; - - /* - * Any slabs which are created with the - * SLAB_RECLAIM_ACCOUNT flag claim to have contents - * which are reclaimable, under pressure. The dentry - * cache and most inode caches should fall into this - */ - free += atomic_read(&slab_reclaim_pages); - - /* - * Leave the last 3% for root - */ - if (!capable(CAP_SYS_ADMIN)) - free -= free / 32; - - if (free > pages) - return 0; - - /* - * nr_free_pages() is very expensive on large systems, - * only call if we're about to fail. - */ - n = nr_free_pages(); - if (!capable(CAP_SYS_ADMIN)) - n -= n / 32; - free += n; - - if (free > pages) - return 0; - vm_unacct_memory(pages); - return -ENOMEM; - } - - allowed = (totalram_pages - hugetlb_total_pages()) - * sysctl_overcommit_ratio / 100; - allowed += total_swap_pages; - - if (atomic_read(&vm_committed_space) < allowed) - return 0; - - vm_unacct_memory(pages); + int cap_sys_admin = 0; - return -ENOMEM; + if (cap_capable(current, CAP_SYS_ADMIN) == 0) + cap_sys_admin = 1; + return __vm_enough_memory(pages, cap_sys_admin); } EXPORT_SYMBOL(cap_capable); +EXPORT_SYMBOL(cap_settime); EXPORT_SYMBOL(cap_ptrace); EXPORT_SYMBOL(cap_capget); EXPORT_SYMBOL(cap_capset_check);