lkml.org 
[lkml]   [1999]   [Apr]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRE: Latest capabilities patch(getting close)

    On 26-Apr-99 Y2K wrote:
    > Supports "soiled" and "pure draft".
    > Preliminary support for required caps in elf header.
    > per task or global securebits settings.
    > Elf note fixups.
    > ld scripts that might useful, might not.
    > I hope that this is close enough that some real testing might begin soon.
    > Once elf cap adder is finished then you can play with caps RSN.

    Here's my patch to binfmt_elf for finding the caps data. It's a little cleaner
    with respect to parsing the notes segment, but it contains no active
    ingredients.

    J

    ==== //depot/linux/local/fs/binfmt_elf.c#2 - /home/jeremy/perforce/work/linux/lo
    cal/fs/binfmt_elf.c ====
    @@ -396,12 +396,42 @@
    #define INTERPRETER_AOUT 1
    #define INTERPRETER_ELF 2

    +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
    +
    +/* Given a pointer to a set of notes, find the first with the given
    + name and type */
    +static void *find_note(char *buf, int bufsz, const char *notename, int type)
    +{
    + while(bufsz > sizeof(Elf32_Nhdr)) {
    + Elf32_Nhdr *nhdr = (Elf32_Nhdr *)buf;
    + char *name;
    + void *desc;
    + int sz;
    +
    + sz = sizeof(Elf32_Nhdr) +
    + roundup(nhdr->n_namesz, 4) +
    + roundup(nhdr->n_descsz, 4);
    + if (bufsz < sz)
    + break;
    + name = buf + sizeof(Elf32_Nhdr);
    + desc = name + roundup(nhdr->n_namesz, 4);

    + if (strncmp(name, notename, nhdr->n_namesz) == 0 &&
    + type == nhdr->n_type)
    + return desc;
    +
    + buf += sz;
    + bufsz -= sz;
    + }
    +
    + return NULL;
    +}
    +
    static inline int
    do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
    {
    struct file * file;
    - struct dentry *interpreter_dentry = NULL; /* to shut gcc up */
    + struct dentry *interpreter_dentry = NULL;
    unsigned long load_addr = 0, load_bias;
    int load_addr_set = 0;
    char * elf_interpreter = NULL;
    @@ -473,7 +503,42 @@
    end_data = 0;

    for (i = 0; i < elf_ex.e_phnum; i++) {
    - if (elf_ppnt->p_type == PT_INTERP) {
    + switch(elf_ppnt->p_type) {
    + case PT_NOTE: {
    + struct elf_capabilities_note *caps;
    + char *buf;
    +
    + retval = -ENOMEM;
    + buf = kmalloc(elf_ppnt->p_filesz, GFP_KERNEL);
    +
    + if (buf == NULL)
    + goto out_free_dentry;
    +
    + retval = read_exec(bprm->dentry, elf_ppnt->p_offset, buf,
    + elf_ppnt->p_filesz, 1);
    +
    + if (retval < 0) {
    + kfree(buf);
    + goto out_free_dentry;
    + }
    +
    + caps = (struct elf_capabilities_note *)find_note(buf, elf_ppnt->p_filesz,
    + "CAPS", 1);
    +
    + if (caps != NULL) {
    + /* what to do with multiple CAPS notes?
    + Find the most restrictive union? */
    +
    + /* process caps here */
    +
    + printk("found CAPS note!\n");
    + }
    +
    + kfree(buf);
    + }
    + break;
    +
    + case PT_INTERP: {
    retval = -EINVAL;
    if (elf_interpreter)
    goto out_free_interp;
    @@ -533,6 +598,8 @@
    interp_ex = *((struct exec *) bprm->buf);
    interp_elf_ex = *((struct elfhdr *) bprm->buf);
    }
    + break;
    + }
    elf_ppnt++;
    }

    @@ -777,7 +844,8 @@

    /* error cleanup */
    out_free_dentry:
    - dput(interpreter_dentry);
    + if (interpreter_dentry)
    + dput(interpreter_dentry);
    out_free_interp:
    if (elf_interpreter)
    kfree(elf_interpreter);
    \
     
     \ /
      Last update: 2005-03-22 13:51    [W:0.025 / U:29.880 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site