lkml.org 
[lkml]   [2005]   [Mar]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH 1/2] No-exec support for ppc64
    On Wed, 16 Mar 2005 17:10:57 +1100
    Paul Mackerras <paulus@samba.org> wrote:

    > Jake Moilanen writes:
    >
    > > It does not work w/o the sys_mprotect. It will hang in one of the first
    > > few binaries.
    >
    > Hmmm, what distro is this with? I just tried a kernel with the patch
    > below on a SLES9 install and a Debian install and it came up and ran
    > just fine in both cases.

    I'm not sure that the patch you sent is actually doing protection
    correctly.

    To test I commented out this line:

    > +#define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))

    and then ran a non-pt_gnu_stack binary which should have executed on a non-exec
    segment, it did not segfault.

    > + *
    > + * Note due to the way vm flags are laid out, the bits are XWR
    > */
    > #define __P000 PAGE_NONE
    > -#define __P001 PAGE_READONLY_X
    > +#define __P001 PAGE_READONLY
    > #define __P010 PAGE_COPY
    > #define __P011 PAGE_COPY_X
    > #define __P100 PAGE_READONLY
    > #define __P101 PAGE_READONLY_X
    > -#define __P110 PAGE_COPY
    > +#define __P110 PAGE_COPY_X
    > #define __P111 PAGE_COPY_X


    I think the problem was this hunk. __P011 should be PAGE_COPY and
    __P100 should be PAGE_READONLY_X.

    Here is a patch ontop of the last patch you sent to fix this problem and
    take another crack at doing the sys_mprotect less hackish.

    Signed-off-by: Jake Moilanen <moilanen@austin.ibm.com>

    ---

    linux-2.6.11.4-paulus-moilanen/fs/binfmt_elf.c | 18 +++++++++----
    linux-2.6.11.4-paulus-moilanen/include/asm-ppc64/pgtable.h | 4 +-
    2 files changed, 15 insertions(+), 7 deletions(-)

    diff -puN fs/binfmt_elf.c~more-nx fs/binfmt_elf.c
    --- linux-2.6.11.4-paulus/fs/binfmt_elf.c~more-nx 2005-03-16 09:35:28 -06:00
    +++ linux-2.6.11.4-paulus-moilanen/fs/binfmt_elf.c 2005-03-16 11:03:15 -06:00
    @@ -88,7 +88,7 @@ static struct linux_binfmt elf_format =

    #define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)

    -static int set_brk(unsigned long start, unsigned long end)
    +static int set_brk(unsigned long start, unsigned long end, int prot)
    {
    start = ELF_PAGEALIGN(start);
    end = ELF_PAGEALIGN(end);
    @@ -99,6 +99,9 @@ static int set_brk(unsigned long start,
    up_write(&current->mm->mmap_sem);
    if (BAD_ADDR(addr))
    return addr;
    +
    + sys_mprotect(start, end-start, prot);
    +
    }
    current->mm->start_brk = current->mm->brk = end;
    return 0;
    @@ -529,6 +532,7 @@ static int load_elf_binary(struct linux_
    struct files_struct *files;
    int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT;
    unsigned long def_flags = 0;
    + int bss_prot = 0;
    struct {
    struct elfhdr elf_ex;
    struct elfhdr interp_elf_ex;
    @@ -811,7 +815,7 @@ static int load_elf_binary(struct linux_
    before this one. Map anonymous pages, if needed,
    and clear the area. */
    retval = set_brk (elf_bss + load_bias,
    - elf_brk + load_bias);
    + elf_brk + load_bias, bss_prot);
    if (retval) {
    send_sig(SIGKILL, current, 0);
    goto out_free_dentry;
    @@ -883,15 +887,19 @@ static int load_elf_binary(struct linux_

    k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;

    - if (k > elf_bss)
    + if (k > elf_bss) {
    elf_bss = k;
    + bss_prot = elf_prot;
    + }
    if ((elf_ppnt->p_flags & PF_X) && end_code < k)
    end_code = k;
    if (end_data < k)
    end_data = k;
    k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
    - if (k > elf_brk)
    + if (k > elf_brk) {
    elf_brk = k;
    + bss_prot = elf_prot;
    + }
    }

    loc->elf_ex.e_entry += load_bias;
    @@ -907,7 +915,7 @@ static int load_elf_binary(struct linux_
    * mapping in the interpreter, to make sure it doesn't wind
    * up getting placed where the bss needs to go.
    */
    - retval = set_brk(elf_bss, elf_brk);
    + retval = set_brk(elf_bss, elf_brk, bss_prot);
    if (retval) {
    send_sig(SIGKILL, current, 0);
    goto out_free_dentry;
    diff -puN include/asm-ppc64/pgtable.h~more-nx include/asm-ppc64/pgtable.h
    --- linux-2.6.11.4-paulus/include/asm-ppc64/pgtable.h~more-nx 2005-03-16 09:35:44 -06:00
    +++ linux-2.6.11.4-paulus-moilanen/include/asm-ppc64/pgtable.h 2005-03-16 09:35:53 -06:00
    @@ -137,8 +137,8 @@
    #define __P000 PAGE_NONE
    #define __P001 PAGE_READONLY
    #define __P010 PAGE_COPY
    -#define __P011 PAGE_COPY_X
    -#define __P100 PAGE_READONLY
    +#define __P011 PAGE_COPY
    +#define __P100 PAGE_READONLY_X
    #define __P101 PAGE_READONLY_X
    #define __P110 PAGE_COPY_X
    #define __P111 PAGE_COPY_X
    _
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:11    [W:0.029 / U:31.684 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site