Messages in this thread Patch in this message | | | Date | Wed, 14 Apr 1999 23:12:29 +0200 | From | Pavel Machek <> | Subject | [PATCH] Capabilities in elf |
| |
Hi!
Here is next version, this one is believed NOT to contain security hole. Please take a look, and comment i.e. post me things like "GREAT! this is going to be included in 2.2.6".
Pavel
--- clean//fs/binfmt_elf.c Fri Mar 26 17:46:23 1999 +++ linux/fs/binfmt_elf.c Tue Apr 13 20:50:54 1999 @@ -152,14 +152,14 @@ __put_user ((id), sp+(nr*2)); \ __put_user ((val), sp+(nr*2+1)); \ - sp -= 2; + sp -= 6; NEW_AUX_ENT(0, AT_NULL, 0); + NEW_AUX_ENT(1, AT_HWCAP, hwcap); + NEW_AUX_ENT(2, AT_LINUX_FPUCW, 0 /* FPUCW_DEFAULT */ ); if (k_platform) { sp -= 2; NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform); } - sp -= 2; - NEW_AUX_ENT(0, AT_HWCAP, hwcap); if (exec) { sp -= 11*2; @@ -425,8 +425,11 @@ retval = -ENOEXEC; /* First of all, some simple consistency checks */ - if (elf_ex.e_ident[0] != 0x7f || - strncmp(&elf_ex.e_ident[1], "ELF", 3) != 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) @@ -471,6 +474,53 @@ start_code = ~0UL; end_code = 0; end_data = 0; + + { + int size = elf_ex.e_shnum * sizeof(Elf32_Shdr); + char *buf = kmalloc(size, GFP_KERNEL); + Elf32_Shdr *shdr = buf; + int i; + + retval = read_exec(bprm->dentry, elf_ex.e_shoff, + buf, size, 1); + + for (i=0; i<elf_ex.e_shnum; i++) { + Elf32_Shdr *hdr = shdr+i; + struct elf_capabilities cap; + + if (hdr->sh_type != 0xca) + continue; + + printk( "Before: " ); + printk( "uid = %d, effective = %x, permitted = %x, inheritable = %x\n", bprm->e_uid, bprm->cap_effective, bprm->cap_permitted, bprm->cap_inheritable ); + printk( "Capabilities: " ); + + printk( "read: " ); + read_exec(bprm->dentry, hdr->sh_offset, (void *) &cap, sizeof(struct elf_capabilities), 1); + printk( "ok, " ); + + printk( "read, " ); + retval = -ENOEXEC; + if (cap.signature != 0xca5ab1e) { + printk( "signature = %x\n", cap.signature ); + goto out; + } + printk( "sig ok, " ); + if (!bprm->e_uid) { /* We only honour uid changes for root */ + if (cap.flags & ECF_MAKE_EUID_UID) + bprm->e_uid = current->uid; + if (cap.flags & ECF_MAKE_EUID_XUID) + bprm->e_uid = cap.xuid; + } + cap_mask( bprm->cap_effective, cap.capabilities ); + cap_mask( bprm->cap_permitted, cap.capabilities ); +#if 0 + cap_mask( current->cap_inheritable, cap.capabilities ); +#endif + printk( "uid = %d, effective = %x, permitted = %x, inheritable = %x\n", bprm->e_uid, bprm->cap_effective, bprm->cap_permitted, bprm->cap_inheritable ); + + } + } for (i = 0; i < elf_ex.e_phnum; i++) { if (elf_ppnt->p_type == PT_INTERP) { --- clean//include/linux/elf.h Thu Jun 25 17:38:14 1998 +++ linux/include/linux/elf.h Thu Apr 8 16:53:45 1999 @@ -27,6 +27,7 @@ #define PT_NOTE 4 #define PT_SHLIB 5 #define PT_PHDR 6 +#define PT_CAPABIL 7 #define PT_LOPROC 0x70000000 #define PT_HIPROC 0x7fffffff @@ -130,6 +131,8 @@ #define AT_PLATFORM 15 /* string identifying CPU for optimizations */ #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ +#define AT_LINUX_FPUCW 2134 + typedef struct dynamic{ Elf32_Sword d_tag; union{ @@ -275,6 +278,7 @@ /* Legal values for e_flags field of Elf64_Ehdr. */ #define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */ +#define EF_CAPABLE 2 /* Includes capabilities header */ typedef struct elf32_rel { @@ -322,19 +326,20 @@ typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; +/*16*/ Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; /* Entry point */ Elf32_Off e_phoff; - Elf32_Off e_shoff; +/*32*/ Elf32_Off e_shoff; Elf32_Word e_flags; - Elf32_Half e_ehsize; +/*40*/ Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; +/*52 == 0x34 */ } Elf32_Ehdr; typedef struct elf64_hdr { @@ -369,6 +374,7 @@ Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; +/*32 == 0x20*/ } Elf32_Phdr; typedef struct elf64_phdr { @@ -495,6 +501,17 @@ Elf32_Word n_descsz; /* Content size */ Elf32_Word n_type; /* Content type */ } Elf64_Nhdr; + +/* Capabilities support + */ +struct elf_capabilities { + Elf32_Word signature; + Elf32_Word capabilities; + Elf32_Word flags; +#define ECF_MAKE_EUID_UID 1 +#define ECF_MAKE_EUID_XUID 2 + Elf32_Word xuid; +}; #if ELF_CLASS == ELFCLASS32
-- I'm really pavel@atrey.karlin.mff.cuni.cz. Pavel Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).
- 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/
| |