Capabilities for elf

Pavel Machek (pavel@suse.cz)
Fri, 19 Nov 1999 22:45:20 +0100


Hi!

It is near-2.4 time, and any solution bringing capabilities to
filesystem metadata is not anywhere near. So maybe there's time for
elf capabilities hack after all? [Remember that 99% setuid programs
are elf, anyways]

Pavel
--- clean/fs/binfmt_elf.c Thu Nov 4 20:43:23 1999
+++ linux/fs/binfmt_elf.c Thu Nov 4 20:36:48 1999
@@ -7,6 +7,7 @@
* Tools".
*
* Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
+ * Capabilities copyright 1999 Pavel Machek (pavel@ucw.cz).
*/

#include <linux/module.h>
@@ -377,6 +378,26 @@
return elf_entry;
}

+static void
+restrict( struct linux_binprm * bprm, struct elf_capabilities *cap )
+{
+ if (cap->signature != 0xca5ab1e)
+ return;
+
+ /* I do not check versions... That is because current version
+ is 0 and I expect all changes to be backward - compabtible */
+ if (cap->flags & ECF_MAKE_EUID_UID) /* You may want to loose owner's uid */
+ bprm->e_uid = current->uid;
+ if ((!bprm->e_uid) && (cap->flags & ECF_MAKE_EUID_XUID))
+ bprm->e_uid = cap->xuid; /* We only honour random uid changes for root */
+ cap_mask( bprm->cap_effective, cap->effective );
+ cap_mask( bprm->cap_permitted, cap->permitted );
+ cap_mask( bprm->cap_inheritable, cap->inheritable );
+
+ printk( KERN_DEBUG "Now: uid = %d, effective = %x, permitted = %x, inheritable = %x\n", bprm->e_uid, bprm->cap_effective, bprm->cap_permitted, bprm->cap_inheritable );
+}
+
+
/*
* These are the functions used to load ELF style executables and shared
* libraries. There is no binary dependent code anywhere else.
@@ -386,6 +407,7 @@
#define INTERPRETER_AOUT 1
#define INTERPRETER_ELF 2

+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))

static inline int
do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
@@ -415,7 +437,11 @@

retval = -ENOEXEC;
/* First of all, some simple consistency checks */
- if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
+ if (elf_ex.e_ident[0] != 0x7f)
+ goto out;
+
+ if (strncmp(&elf_ex.e_ident[1], "ELF", 3) &&
+ strncmp(&elf_ex.e_ident[1], "FLE", 3))
goto out;

if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
@@ -464,6 +490,22 @@
end_data = 0;

for (i = 0; i < elf_ex.e_phnum; i++) {
+ if (elf_ppnt->p_type == PT_NOTE) {
+ struct elf_capabilities_note note;
+ int offset = elf_ppnt->p_offset;
+ int maxoffset = offset + elf_ppnt->p_filesz;
+
+ while (offset <= (maxoffset - sizeof(note))) {
+ int retval;
+ retval = read_exec(bprm->dentry, offset, (void *) &note,
+ sizeof(note), 1);
+ if (retval != sizeof(note))
+ goto skip;
+ if (note.note_signature == be32_to_cpu(0x43415053)) /* "CAPS" */
+ restrict(bprm, &note.cap);
+ offset += sizeof(Elf32_Nhdr) + roundup(note.nhdr.n_namesz, 4) + roundup(note.nhdr.n_descsz, 4);
+ }
+ }
if (elf_ppnt->p_type == PT_INTERP) {
retval = -EINVAL;
if (elf_interpreter)
@@ -524,6 +566,7 @@
interp_ex = *((struct exec *) bprm->buf);
interp_elf_ex = *((struct elfhdr *) bprm->buf);
}
+ skip:
elf_ppnt++;
}

--- clean/include/linux/elf.h Sat Oct 16 10:24:27 1999
+++ linux/include/linux/elf.h Thu Nov 4 21:09:09 1999
@@ -581,6 +581,27 @@
Elf32_Word n_type; /* Content type */
} Elf64_Nhdr;

+/* Capabilities support
+ */
+struct elf_capabilities {
+ __u32 signature;
+ __u32 version; /* Currently 0; this is so that you can append on the end painlessly */
+ __u32 flags;
+#define ECF_MAKE_EUID_UID 1
+#define ECF_MAKE_EUID_XUID 2
+ __u32 xuid; /* We want our set 128bit for future expansion */
+ __u32 effective, effective1, effective2, effective3;
+ __u32 permitted, permitted1, permitted2, permitted3;
+ __u32 inheritable, inheritable1, inheritable2, inheritable3;
+ __u32 known, known1, known2, known3;
+};
+
+struct elf_capabilities_note {
+ Elf32_Nhdr nhdr;
+ __u32 note_signature; /* == "CAPS" */
+ struct elf_capabilities cap;
+};
+
#if ELF_CLASS == ELFCLASS32

extern Elf32_Dyn _DYNAMIC [];

-- 
I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel.  Pavel
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/