--- commoncap.c.orig 2004-12-07 15:24:34.943336336 -0600 +++ commoncap.c 2004-12-07 15:27:38.750393416 -0600 @@ -49,9 +49,17 @@ int cap_capable (struct task_struct *tsk return -EPERM; } +static inline int check_cap_capable(int cap) +{ + if (cap_capable(current, cap)) + return 0; + current->flags |= PF_SUPERPRIV; + return 1; +} + int cap_settime(struct timespec *ts, struct timezone *tz) { - if (!capable(CAP_SYS_TIME)) + if (!check_cap_capable(CAP_SYS_TIME)) return -EPERM; return 0; } @@ -60,7 +68,7 @@ int cap_ptrace (struct task_struct *pare { /* Derived from arch/i386/kernel/ptrace.c:sys_ptrace. */ if (!cap_issubset (child->cap_permitted, current->cap_permitted) && - !capable(CAP_SYS_PTRACE)) + !check_cap_capable(CAP_SYS_PTRACE)) return -EPERM; return 0; } @@ -152,11 +160,11 @@ void cap_bprm_apply_creds (struct linux_ current->mm->dumpable = 0; if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) { - if (!capable(CAP_SETUID)) { + if (!check_cap_capable(CAP_SETUID)) { bprm->e_uid = current->uid; bprm->e_gid = current->gid; } - if (!capable (CAP_SETPCAP)) { + if (!check_cap_capable (CAP_SETPCAP)) { new_permitted = cap_intersect (new_permitted, current->cap_permitted); } @@ -196,7 +204,7 @@ int cap_inode_setxattr(struct dentry *de { if (!strncmp(name, XATTR_SECURITY_PREFIX, sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) + !check_cap_capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -205,7 +213,7 @@ int cap_inode_removexattr(struct dentry { if (!strncmp(name, XATTR_SECURITY_PREFIX, sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) + !check_cap_capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -311,7 +319,7 @@ void cap_task_reparent_to_init (struct t int cap_syslog (int type) { - if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN)) + if ((type != 3 && type != 10) && !check_cap_capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -356,7 +364,7 @@ int cap_vm_enough_memory(long pages) /* * Leave the last 3% for root */ - if (!capable(CAP_SYS_ADMIN)) + if (!check_cap_capable(CAP_SYS_ADMIN)) free -= free / 32; if (free > pages) @@ -367,7 +375,7 @@ int cap_vm_enough_memory(long pages) * only call if we're about to fail. */ n = nr_free_pages(); - if (!capable(CAP_SYS_ADMIN)) + if (!check_cap_capable(CAP_SYS_ADMIN)) n -= n / 32; free += n; @@ -382,7 +390,7 @@ int cap_vm_enough_memory(long pages) /* * Leave the last 3% for root */ - if (!capable(CAP_SYS_ADMIN)) + if (!check_cap_capable(CAP_SYS_ADMIN)) allowed -= allowed / 32; allowed += total_swap_pages;