Add 64-bit capability support to the kernel

The patch supports legacy (32-bit) capability userspace, and where possible
translates 32-bit capabilities to/from userspace and the VFS to 64-bit
kernel space capabilities.  If a capability set cannot be compressed into
32-bits for consumption by user space, the system call fails, with -ERANGE.

FWIW libcap-2.00 supports this change (and earlier capability formats)

 http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/

[[email protected]: coding-syle fixes]
[[email protected]: use get_task_comm()]
[[email protected]: build fix]
[[email protected]: do not initialise statics to 0 or NULL]
[[email protected]: unused var]
[[email protected]: export __cap_ symbols]
Signed-off-by: Andrew G. Morgan <[email protected]>
Cc: Stephen Smalley <[email protected]>
Acked-by: Serge Hallyn <[email protected]>
Cc: Chris Wright <[email protected]>
Cc: James Morris <[email protected]>
Cc: Casey Schaufler <[email protected]>
Signed-off-by: Erez Zadok <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
Andrew Morgan 2008-02-04 22:29:42 -08:00 • committed by Linus Torvalds
commit e338d263a7
7 changed files with 349 additions and 125 deletions

View file

@ -36,14 +36,19 @@ static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
kernel_cap_t * inheritable, kernel_cap_t * permitted)
{
*effective = *inheritable = *permitted = 0;
if (target->euid == 0) {
*permitted |= (~0 & ~CAP_FS_MASK);
*effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
cap_set_full(*permitted);
cap_set_init_eff(*effective);
} else {
cap_clear(*permitted);
cap_clear(*effective);
}
if (target->fsuid == 0) {
*permitted |= CAP_FS_MASK;
*effective |= CAP_FS_MASK;
cap_clear(*inheritable);
if (target->fsuid != 0) {
*permitted = cap_drop_fs_set(*permitted);
*effective = cap_drop_fs_set(*effective);
}
return 0;
}