lkml.org 
[lkml]   [2010]   [Dec]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[Patch 18/21] Generate the data sections for ELF Core
    Generate the "data" for the memory regions. Also write down the section header 
    if we have, number of phdrs > PN_XNUM.

    The vma areas are read, page by page using access_process_vm() without an
    mmap_sem. If there are active threads, then we may miss a vma if it is removed
    while we are doing the read.

    Signed-off-by: Suzuki K. Poulose <suzuki@in.ibm.com>
    Signed-off-by: Ananth N. Mavinakayanahalli <ananth@in.ibm.com>
    ---
    fs/proc/gencore-elf.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++--
    1 file changed, 87 insertions(+), 3 deletions(-)

    Index: linux-2.6.36-rc7/fs/proc/gencore-elf.c
    ===================================================================
    --- linux-2.6.36-rc7.orig/fs/proc/gencore-elf.c
    +++ linux-2.6.36-rc7/fs/proc/gencore-elf.c
    @@ -333,10 +333,29 @@ static int create_elf_header(struct core
    return 0;
    }

    +/*
    + * Verify if the fpos asked for in read is valid.
    + * Returns the phdr corresponding to offset, else NULL.
    + */
    +static struct elf_phdr *get_pos_elfphdr(struct core_proc *cp, loff_t pos)
    +{
    + struct elfhdr *elf_hdr = (struct elfhdr *)cp->elf_buf;
    + struct elf_phdr *phdr = (struct elf_phdr*)(cp->elf_buf + elf_hdr->e_phoff);
    + int i;
    +
    + for (i = 0; i < cp->nphdrs; i++, phdr++) {
    + unsigned long end = phdr->p_offset + phdr->p_filesz;
    + if ((pos >= phdr->p_offset) && (pos < end))
    + return phdr;
    + }
    + return NULL;
    +}
    +
    ssize_t elf_read_gencore(struct core_proc *cp, char __user *buffer,
    size_t buflen, loff_t *fpos)
    {
    - ssize_t ret = 0;
    + ssize_t ret = 0, acc = 0;
    + struct elfhdr *elf_hdr = (struct elfhdr *)cp->elf_buf;

    if (!cp->notes_size) {
    if (!collect_notes(cp)) {
    @@ -367,16 +386,81 @@ ssize_t elf_read_gencore(struct core_pro
    ret = -EFAULT;
    goto out;
    } else {
    - ret = bcp;
    + acc = bcp;
    *fpos += bcp;
    buflen -= bcp;
    buffer += bcp;
    }
    }

    +
    if (*fpos > cp->size)
    - goto out;
    + goto done;
    +
    + /*
    + * Read from the vma segments
    + * a. verify if the *fpos is within a phdr
    + * b. Use access_process_vm() to get data page by page
    + * c. copy_to_user into user buffer
    + */
    +
    + while (buflen) {
    + size_t bufsz, offset, bytes;
    + char *readbuf;
    + struct elf_phdr *phdr = get_pos_elfphdr(cp, *fpos);
    +
    + if (!phdr)
    + break;
    +
    + bufsz = (buflen > PAGE_SIZE) ? PAGE_SIZE : buflen;
    + readbuf = kmalloc(bufsz, GFP_KERNEL);
    + if (!readbuf) {
    + ret = -ENOMEM;
    + goto out;
    + }
    +
    + offset = *fpos - phdr->p_offset;
    + bytes = access_process_vm(cp->task, (phdr->p_vaddr + offset),
    + readbuf, bufsz, 0);
    + if (!bytes) {
    + ret = -EIO;
    + goto out;
    + }
    + if (copy_to_user(buffer, readbuf, bytes)) {
    + ret = -EFAULT;
    + kfree(readbuf);
    + goto out;
    + } else
    + acc += bytes;
    +
    + kfree(readbuf);
    + buflen -= bytes;
    + buffer += bytes;
    + *fpos += bytes;
    + }
    +
    + /* Fill extnum section header if present */
    + if (buflen &&
    + elf_hdr->e_shoff &&
    + (*fpos >= elf_hdr->e_shoff) &&
    + (*fpos < (elf_hdr->e_shoff + sizeof(struct elf_shdr)))) {
    +
    + off_t offset = *fpos - elf_hdr->e_shoff;
    + size_t shdrsz = sizeof(struct elf_shdr) - offset;
    +
    + shdrsz = (buflen < shdrsz) ? buflen : shdrsz;
    + if (copy_to_user(buffer, ((char *)cp->shdr) + offset, shdrsz)) {
    + ret = -EFAULT;
    + goto out;
    + } else {
    + acc += shdrsz;
    + buflen -= shdrsz;
    + buffer += shdrsz;
    + }
    + }

    +done:
    + ret = acc;
    out:
    return ret;
    }

    \
     
     \ /
      Last update: 2010-12-14 11:25    [W:0.024 / U:60.940 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site