Messages in this thread Patch in this message | | | Date | Wed, 7 Apr 1999 21:48:33 +0200 | From | Pavel Machek <> | Subject | [PATCH] So you want capabilities? |
| |
Hi!
So you want capabilities in elf? There was too much talk, already, and not enough code, yet.
Usage is:
Make it suid root, and add header with capabilities at end of executable which says exactly which capabilities you want to give it.
If you want this NOT to run on older kernels, turn "ELF" signature into "FLE". New kernel will recognize it, old will not -> executable will fail.
Pavel
PS: This should work, but I do not feel too well having header at fixed position from end of elf executable. If you have better solution...
Here is trivial uitility for adding headers: (GPL) [It needs to be improved _very_ much in order to be usefull. We should probably aim for compatibility with similar utilities on other systems. Also utility for listing these info is needed.]
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> #include <unistd.h>
#include <linux/elf.h> #include <linux/capability.h>
void main(int argc, char *argv[]) { int h; struct elf32_hdr hdr; struct elf_capabilities cap;
h = open(argv[1], O_RDWR); read(h, &hdr, sizeof(hdr)); hdr.e_flags |= EF_CAPABLE; lseek(h, 0, SEEK_SET); write(h, &hdr, sizeof(hdr));
lseek(h, 0, SEEK_END); cap.signature = 0xca5ab1e; cap.capabilities = 1<<CAP_NET_RAW; cap.flags = ECF_MAKE_EUID_UID; cap.xuid = 0x12345678; write(h, &cap, sizeof(cap)); }
And now, here is the diff. This is more proof of concept etc rather than anything else... Still it would be nice to see it in 2.2.6.
--- clean/include/linux/elf.h Thu Jun 25 17:38:14 1998 +++ linux/include/linux/elf.h Wed Apr 7 19:34:36 1999 @@ -275,6 +277,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 { @@ -495,6 +498,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 --- clean/fs/binfmt_elf.c Fri Mar 26 17:46:23 1999 +++ linux/fs/binfmt_elf.c Wed Apr 7 20:25:18 1999 @@ -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) @@ -440,6 +443,29 @@ goto out; } #endif + if (elf_ex.e_flags & EF_CAPABLE) { + struct elf_capabilities cap; + 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( "Executable with capabilities, here: " ); + + read_exec(bprm->dentry, bprm->dentry->d_inode->i_size-sizeof(struct elf_capabilities), (void *) &cap, sizeof(struct elf_capabilities), 1); + printk( "read, " ); + retval = -ENOEXEC; + if (cap.signature != 0xca5ab1e) + goto out; + printk( "sig ok, " ); + 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 ); + } if (!bprm->dentry->d_inode->i_op || !bprm->dentry->d_inode->i_op->default_file_ops || !bprm->dentry->d_inode->i_op->default_file_ops->mmap)
-- 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/
| |