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/

[akpm@linux-foundation.org: coding-syle fixes]
[akpm@linux-foundation.org: use get_task_comm()]
[ezk@cs.sunysb.edu: build fix]
[akpm@linux-foundation.org: do not initialise statics to 0 or NULL]
[akpm@linux-foundation.org: unused var]
[serue@us.ibm.com: export __cap_ symbols]
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: James Morris <jmorris@namei.org>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Andrew Morgan
2008-02-04 22:29:42 -08:00
committed by Linus Torvalds
parent 8f6936f4d2
commit e338d263a7
7 changed files with 349 additions and 125 deletions

View File

@@ -281,14 +281,23 @@ static inline char *task_sig(struct task_struct *p, char *buffer)
return buffer;
}
static char *render_cap_t(const char *header, kernel_cap_t *a, char *buffer)
{
unsigned __capi;
buffer += sprintf(buffer, "%s", header);
CAP_FOR_EACH_U32(__capi) {
buffer += sprintf(buffer, "%08x",
a->cap[(_LINUX_CAPABILITY_U32S-1) - __capi]);
}
return buffer + sprintf(buffer, "\n");
}
static inline char *task_cap(struct task_struct *p, char *buffer)
{
return buffer + sprintf(buffer, "CapInh:\t%016x\n"
"CapPrm:\t%016x\n"
"CapEff:\t%016x\n",
cap_t(p->cap_inheritable),
cap_t(p->cap_permitted),
cap_t(p->cap_effective));
buffer = render_cap_t("CapInh:\t", &p->cap_inheritable, buffer);
buffer = render_cap_t("CapPrm:\t", &p->cap_permitted, buffer);
return render_cap_t("CapEff:\t", &p->cap_effective, buffer);
}
static inline char *task_context_switch_counts(struct task_struct *p,