Re: [PATCH 1/2] No-exec support for ppc64

2005-03-16 Thread Jake Moilanen
On Wed, 16 Mar 2005 17:10:57 +1100
Paul Mackerras <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]>

---

 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(¤t->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

Re: [PATCH 1/2] No-exec support for ppc64

2005-03-15 Thread Paul Mackerras
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.

Paul.

diff -urN linux-2.5/arch/ppc64/kernel/head.S test/arch/ppc64/kernel/head.S
--- linux-2.5/arch/ppc64/kernel/head.S  2005-03-07 10:46:38.0 +1100
+++ test/arch/ppc64/kernel/head.S   2005-03-15 17:14:44.0 +1100
@@ -950,11 +950,12 @@
 * accessing a userspace segment (even from the kernel). We assume
 * kernel addresses always have the high bit set.
 */
-   rlwinm  r4,r4,32-23,29,29   /* DSISR_STORE -> _PAGE_RW */
+   rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
rotldi  r0,r3,15/* Move high bit into MSR_PR posn */
orc r0,r12,r0   /* MSR_PR | ~high_bit */
rlwimi  r4,r0,32-13,30,30   /* becomes _PAGE_USER access bit */
ori r4,r4,1 /* add _PAGE_PRESENT */
+   rlwimi  r4,r5,22+2,31-2,31-2/* Set _PAGE_EXEC if trap is 0x400 */
 
/*
 * On iSeries, we soft-disable interrupts here, then
diff -urN linux-2.5/arch/ppc64/kernel/iSeries_htab.c 
test/arch/ppc64/kernel/iSeries_htab.c
--- linux-2.5/arch/ppc64/kernel/iSeries_htab.c  2004-09-21 17:22:33.0 
+1000
+++ test/arch/ppc64/kernel/iSeries_htab.c   2005-03-15 17:15:36.0 
+1100
@@ -144,6 +144,10 @@
 
HvCallHpt_get(&hpte, slot);
if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {
+   /*
+* Hypervisor expects bits as NPPP, which is
+* different from how they are mapped in our PP.
+*/
HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1));
iSeries_hunlock(slot);
return 0;
diff -urN linux-2.5/arch/ppc64/kernel/iSeries_setup.c 
test/arch/ppc64/kernel/iSeries_setup.c
--- linux-2.5/arch/ppc64/kernel/iSeries_setup.c 2005-03-07 10:46:38.0 
+1100
+++ test/arch/ppc64/kernel/iSeries_setup.c  2005-03-15 16:55:05.0 
+1100
@@ -633,6 +633,10 @@
unsigned long vpn = va >> PAGE_SHIFT;
unsigned long slot = HvCallHpt_findValid(&hpte, vpn);
 
+   /* Make non-kernel text non-executable */
+   if (!in_kernel_text(ea))
+   mode_rw |= HW_NO_EXEC;
+
if (hpte.dw0.dw0.v) {
/* HPTE exists, so just bolt it */
HvCallHpt_setSwBits(slot, 0x10, 0);
diff -urN linux-2.5/arch/ppc64/kernel/module.c test/arch/ppc64/kernel/module.c
--- linux-2.5/arch/ppc64/kernel/module.c2004-05-10 21:25:58.0 
+1000
+++ test/arch/ppc64/kernel/module.c 2005-03-15 16:55:05.0 +1100
@@ -102,7 +102,8 @@
 {
if (size == 0)
return NULL;
-   return vmalloc(size);
+
+   return vmalloc_exec(size);
 }
 
 /* Free memory returned from module_alloc */
diff -urN linux-2.5/arch/ppc64/kernel/pSeries_lpar.c 
test/arch/ppc64/kernel/pSeries_lpar.c
--- linux-2.5/arch/ppc64/kernel/pSeries_lpar.c  2005-03-07 10:46:38.0 
+1100
+++ test/arch/ppc64/kernel/pSeries_lpar.c   2005-03-15 16:55:02.0 
+1100
@@ -470,7 +470,7 @@
slot = pSeries_lpar_hpte_find(vpn);
BUG_ON(slot == -1);
 
-   flags = newpp & 3;
+   flags = newpp & 7;
lpar_rc = plpar_pte_protect(flags, slot, 0);
 
BUG_ON(lpar_rc != H_Success);
diff -urN linux-2.5/arch/ppc64/mm/fault.c test/arch/ppc64/mm/fault.c
--- linux-2.5/arch/ppc64/mm/fault.c 2005-01-04 10:49:20.0 +1100
+++ test/arch/ppc64/mm/fault.c  2005-03-15 17:13:05.0 +1100
@@ -91,8 +91,9 @@
struct mm_struct *mm = current->mm;
siginfo_t info;
unsigned long code = SEGV_MAPERR;
-   unsigned long is_write = error_code & 0x0200;
+   unsigned long is_write = error_code & DSISR_ISSTORE;
unsigned long trap = TRAP(regs);
+   unsigned long is_exec = trap == 0x400;
 
BUG_ON((trap == 0x380) || (trap == 0x480));
 
@@ -109,7 +110,7 @@
if (!user_mode(regs) && (address >= TASK_SIZE))
return SIGSEGV;
 
-   if (error_code & 0x0040) {
+   if (error_code & DSISR_DABRMATCH) {
if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
11, SIGSEGV) == NOTIFY_STOP)
return 0;
@@ -199,16 +200,19 @@
 good_area:
code = SEGV_ACCERR;
 
+   if (is_exec) {
+   /* protection fault */
+   if (error_code & DSISR_PROTFAULT)
+   goto bad_area;
+   if (!(vma->vm_flags & VM_EXEC))
+   goto bad_area;
/* a write */
-   if (is_write) {
+   } else if (is_write) {
if (!(vma->vm_flags & VM_WR

Re: [PATCH 1/2] No-exec support for ppc64

2005-03-15 Thread Jake Moilanen
On Wed, 16 Mar 2005 09:18:36 +1030
Alan Modra <[EMAIL PROTECTED]> wrote:

> On Tue, Mar 15, 2005 at 03:51:35PM -0600, Jake Moilanen wrote:
> > I believe the problem is that the last PT_LOAD entry does not have the
> > correct size, and we only mmap up to the sbss.  The .sbss, .plt, and
> > .bss do not get mmapped with the section.
> 
> Huh?  .sbss, .plt and .bss have no file contents, so of course p_filesz
> doesn't cover them.

Your right, those shouldn't be mmapped.  

set_brk() call is called on sbss, plt and bss.  There needs to be some
method to set execute permission, on those pieces as well.  Currently it
has no concept of what permission should be set.

Jake   
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] No-exec support for ppc64

2005-03-15 Thread Alan Modra
On Tue, Mar 15, 2005 at 03:51:35PM -0600, Jake Moilanen wrote:
> I believe the problem is that the last PT_LOAD entry does not have the
> correct size, and we only mmap up to the sbss.  The .sbss, .plt, and
> .bss do not get mmapped with the section.

Huh?  .sbss, .plt and .bss have no file contents, so of course p_filesz
doesn't cover them.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] No-exec support for ppc64

2005-03-15 Thread Jake Moilanen
On Tue, 15 Mar 2005 09:18:04 +1100
Paul Mackerras <[EMAIL PROTECTED]> wrote:

> Jake Moilanen writes:
> 
> > > I don't think I can push that upstream.  What happens if you leave
> > > that out?
> > 
> > The bss and the plt are in the same segment, and plt obviously needs to
> > be executable.
> 
> Yes... what I was asking was "do things actually break if you leave
> that out, or does the binfmt_elf loader honour the 'x' permission on
> the PT_LOAD entry for the data/bss region, meaning that it all just
> works anyway?"

It does not work w/o the sys_mprotect.  It will hang in one of the first
few binaries.

I believe the problem is that the last PT_LOAD entry does not have the
correct size, and we only mmap up to the sbss.  The .sbss, .plt, and
.bss do not get mmapped with the section.

Here is /bin/bash on SLES 9:

Section Headers:
  [Nr] Name  TypeAddr OffSize   ES Flg Lk Inf Al
  [ 0]   NULL 00 00 00  0   0  0
  [ 1] .interp   PROGBITS1174 000174 0d 00   A  0   0  1
...
...
  [19] .data PROGBITS1008ca80 07ca80 001b34 00  WA  0   0  4
  [20] .eh_frame PROGBITS1008e5b4 07e5b4 b4 00   A  0   0  4
  [21] .got2 PROGBITS1008e668 07e668 10 00  WA  0   0  1
  [22] .dynamic  DYNAMIC 1008e678 07e678 e8 08  WA  6   0  4
  [23] .ctorsPROGBITS1008e760 07e760 08 00  WA  0   0  4
  [24] .dtorsPROGBITS1008e768 07e768 08 00  WA  0   0  4
  [25] .jcr  PROGBITS1008e770 07e770 04 00  WA  0   0  4
  [26] .got  PROGBITS1008e774 07e774 14 04 WAX  0   0  4
  [27] .sdataPROGBITS1008e788 07e788 d4 00  WA  0   0  4
  [28] .sbss NOBITS  1008e860 07e860 000704 00  WA  0   0  8
  [29] .plt  NOBITS  1008ef64 07e860 000aa4 00 WAX  0   0  4
  [30] .bss  NOBITS  1008fa10 07e868 0062f0 00  WA  0   0 16


Program Headers:
  Type   Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR   0x34 0x1034 0x1034 0x00120 0x00120 R E 0x4
  INTERP 0x000174 0x1174 0x1174 0xd 0xd R   0x1
  [Requesting program interpreter: /lib/ld.so.1]
  LOAD   0x00 0x1000 0x1000 0x7ca80 0x7ca80 R E 0x1
  LOAD   0x07ca80 0x1008ca80 0x1008ca80 0x01ddc 0x09280 RWE 0x1
  DYNAMIC0x07e678 0x1008e678 0x1008e678 0x000e8 0x000e8 RW  0x4
  NOTE   0x000184 0x1184 0x1184 0x00020 0x00020 R   0x4
  NOTE   0x0001a4 0x11a4 0x11a4 0x00018 0x00018 R   0x4
  GNU_EH_FRAME   0x07ca54 0x1007ca54 0x1007ca54 0x0002c 0x0002c R   0x4
  STACK  0x00 0x 0x 0x0 0x0 RW  0x4


 Section to Segment mapping:
  Segment Sections...
   00
   01 .interp
   02 .interp .note.ABI-tag .note.SuSE .hash .dynsym .dynstr .gnu.version .g
nu.version_r .rela.dyn .rela.plt .init .text text.unlikely text.hot .fini .rodat
a .eh_frame_hdr
   03 .data .eh_frame .got2 .dynamic .ctors .dtors .jcr .got .sdata .sbss .p
lt .bss
   04 .dynamic
   05 .note.ABI-tag
   06 .note.SuSE
   07 .eh_frame_hdr
   08

In the program headers section, the FileSiz for the last PT_LOAD is
0x1ddc.  If we go back to the Section Headers and look at .data it is at
0x1008ca80.  So the segment should end at 0x1008e85c.  We round up for
alignment and we get 0x1008e860 or .sbss.  The sbss, plt, and bss are
not mmapped.  So the sys_mprotect is used to pick it up.  

Did I miss something to explain this?  Can you think of another way to
fix it?

Jake


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] No-exec support for ppc64

2005-03-14 Thread Paul Mackerras
Jake Moilanen writes:

> > I don't think I can push that upstream.  What happens if you leave
> > that out?
> 
> The bss and the plt are in the same segment, and plt obviously needs to
> be executable.

Yes... what I was asking was "do things actually break if you leave
that out, or does the binfmt_elf loader honour the 'x' permission on
the PT_LOAD entry for the data/bss region, meaning that it all just
works anyway?"

I did an objdump -p on some random 32-bit binaries, and they all have
"rwx" flags on the data/bss segment (the second PT_LOAD entry).  And
when I look in /proc//maps, it seems that the heap is in fact
marked executable (this is without your patch).  So why do we need the
hack in binfmt_elf.c?

Paul.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] No-exec support for ppc64

2005-03-14 Thread Jake Moilanen
On Mon, 14 Mar 2005 21:13:36 +1100
Paul Mackerras <[EMAIL PROTECTED]> wrote:

> Jake Moilanen writes:
> 
> > diff -puN fs/binfmt_elf.c~nx-user-ppc64 fs/binfmt_elf.c
> > --- linux-2.6-bk/fs/binfmt_elf.c~nx-user-ppc64  2005-03-08 16:08:54 
> > -06:00
> > +++ linux-2.6-bk-moilanen/fs/binfmt_elf.c   2005-03-08 16:08:54 -06:00
> > @@ -99,6 +99,8 @@ static int set_brk(unsigned long start, 
> > up_write(¤t->mm->mmap_sem);
> > if (BAD_ADDR(addr))
> > return addr;
> > +
> > +   sys_mprotect(start, end-start, PROT_READ|PROT_WRITE|PROT_EXEC);
> 
> I don't think I can push that upstream.  What happens if you leave
> that out?

The bss and the plt are in the same segment, and plt obviously needs to
be executable.

Section Headers:
  [Nr] Name  TypeAddr OffSize   ES Flg Lk Inf Al
  [ 0]   NULL 00 00 00  0   0  0
  [ 1] .interp   PROGBITS1154 000154 0d 00   A  0   0  1
...
...
  [26] .plt  NOBITS  10013c5c 003c34 000210 00 WAX  0   0  4
  [27] .bss  NOBITS  10013e6c 003c34 000128 00  WA  0   0  4


 Segment Sections...
   00
   01 .interp
   02 .interp .note.ABI-tag .note.SuSE .hash .dynsym .dynstr .gnu.version 
.gnu.version_r .rela.dyn .rela.plt .init .text .fini .rodata
   03 .data .eh_frame .got2 .dynamic .ctors .dtors .jcr .got .sdata .sbss 
.plt .bss
   04 .dynamic
   05 .note.ABI-tag
   06 .note.SuSE
   07

Anton mentioned that Alan was considering putting plt into a new segment. 
 
> More generally, we are making a user-visible change, even for programs
> that aren't marked as having non-executable stack or heap, because we
> are now enforcing that the program can't execute from mappings that
> don't have PROT_EXEC.  Perhaps we should enforce the requirement for
> execute permission only on those programs that indicate somehow that
> they can handle it?

Unless a program is compiled w/ pt_gnu_stacks we will set the
READ_IMPLIES_EXEC personality and those applications should still
work as normal.

Jake
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] No-exec support for ppc64

2005-03-14 Thread Paul Mackerras
Jake Moilanen writes:

> diff -puN fs/binfmt_elf.c~nx-user-ppc64 fs/binfmt_elf.c
> --- linux-2.6-bk/fs/binfmt_elf.c~nx-user-ppc642005-03-08 16:08:54 
> -06:00
> +++ linux-2.6-bk-moilanen/fs/binfmt_elf.c 2005-03-08 16:08:54 -06:00
> @@ -99,6 +99,8 @@ static int set_brk(unsigned long start, 
>   up_write(¤t->mm->mmap_sem);
>   if (BAD_ADDR(addr))
>   return addr;
> +
> + sys_mprotect(start, end-start, PROT_READ|PROT_WRITE|PROT_EXEC);

I don't think I can push that upstream.  What happens if you leave
that out?

More generally, we are making a user-visible change, even for programs
that aren't marked as having non-executable stack or heap, because we
are now enforcing that the program can't execute from mappings that
don't have PROT_EXEC.  Perhaps we should enforce the requirement for
execute permission only on those programs that indicate somehow that
they can handle it?

Paul.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] No-exec support for ppc64

2005-03-10 Thread Jake Moilanen
On Wed, 9 Mar 2005 21:22:13 -0600
[EMAIL PROTECTED] (Olof Johansson) wrote:

> On Tue, Mar 08, 2005 at 05:08:26PM -0600, Jake Moilanen wrote:
> > No-exec base and user space support for PPC64.  
> 
> Hi, a couple of comments below.
> 

Here's the revised user & base support for no-exec on ppc64 with Olof
and Ben's comments.

Signed-off-by: Jake Moilanen <[EMAIL PROTECTED]>

---

 linux-2.6-bk-moilanen/arch/ppc64/kernel/head.S |5 +
 linux-2.6-bk-moilanen/arch/ppc64/kernel/iSeries_htab.c |4 +
 linux-2.6-bk-moilanen/arch/ppc64/kernel/pSeries_lpar.c |2 
 linux-2.6-bk-moilanen/arch/ppc64/mm/fault.c|   14 +++--
 linux-2.6-bk-moilanen/arch/ppc64/mm/hash_low.S |   12 ++--
 linux-2.6-bk-moilanen/arch/ppc64/mm/hugetlbpage.c  |   10 +++
 linux-2.6-bk-moilanen/fs/binfmt_elf.c  |2 
 linux-2.6-bk-moilanen/include/asm-ppc64/elf.h  |7 ++
 linux-2.6-bk-moilanen/include/asm-ppc64/page.h |   19 ++-
 linux-2.6-bk-moilanen/include/asm-ppc64/pgtable.h  |   46 +
 10 files changed, 85 insertions(+), 36 deletions(-)

diff -puN arch/ppc64/kernel/head.S~nx-user-ppc64 arch/ppc64/kernel/head.S
--- linux-2.6-bk/arch/ppc64/kernel/head.S~nx-user-ppc64 2005-03-08 16:08:54 
-06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/kernel/head.S  2005-03-08 16:08:54 
-06:00
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include
 #include 
 
 #ifdef CONFIG_PPC_ISERIES
@@ -950,11 +951,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 * accessing a userspace segment (even from the kernel). We assume
 * kernel addresses always have the high bit set.
 */
-   rlwinm  r4,r4,32-23,29,29   /* DSISR_STORE -> _PAGE_RW */
+   rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
rotldi  r0,r3,15/* Move high bit into MSR_PR posn */
orc r0,r12,r0   /* MSR_PR | ~high_bit */
rlwimi  r4,r0,32-13,30,30   /* becomes _PAGE_USER access bit */
-   ori r4,r4,1 /* add _PAGE_PRESENT */
+   rlwimi  r4,r5,22+2,31-2,31-2/* Set _PAGE_EXEC if trap is 0x400 */
 
/*
 * On iSeries, we soft-disable interrupts here, then
diff -puN arch/ppc64/kernel/iSeries_htab.c~nx-user-ppc64 
arch/ppc64/kernel/iSeries_htab.c
--- linux-2.6-bk/arch/ppc64/kernel/iSeries_htab.c~nx-user-ppc64 2005-03-08 
16:08:54 -06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/kernel/iSeries_htab.c  2005-03-08 
16:08:54 -06:00
@@ -144,6 +144,10 @@ static long iSeries_hpte_updatepp(unsign
 
HvCallHpt_get(&hpte, slot);
if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {
+   /*
+* Hypervisor expects bit's as NPPP, which is
+* different from how they are mapped in our PP.
+*/
HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1));
iSeries_hunlock(slot);
return 0;
diff -puN arch/ppc64/kernel/pSeries_lpar.c~nx-user-ppc64 
arch/ppc64/kernel/pSeries_lpar.c
--- linux-2.6-bk/arch/ppc64/kernel/pSeries_lpar.c~nx-user-ppc64 2005-03-08 
16:08:54 -06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/kernel/pSeries_lpar.c  2005-03-08 
16:08:54 -06:00
@@ -470,7 +470,7 @@ static void pSeries_lpar_hpte_updatebolt
slot = pSeries_lpar_hpte_find(vpn);
BUG_ON(slot == -1);
 
-   flags = newpp & 3;
+   flags = newpp & 7;
lpar_rc = plpar_pte_protect(flags, slot, 0);
 
BUG_ON(lpar_rc != H_Success);
diff -puN arch/ppc64/mm/fault.c~nx-user-ppc64 arch/ppc64/mm/fault.c
--- linux-2.6-bk/arch/ppc64/mm/fault.c~nx-user-ppc642005-03-08 16:08:54 
-06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/mm/fault.c 2005-03-10 16:14:45 -06:00
@@ -93,6 +93,7 @@ int do_page_fault(struct pt_regs *regs, 
unsigned long code = SEGV_MAPERR;
unsigned long is_write = error_code & 0x0200;
unsigned long trap = TRAP(regs);
+   unsigned long is_exec = trap == 0x400;  
 
BUG_ON((trap == 0x380) || (trap == 0x480));
 
@@ -199,16 +200,19 @@ int do_page_fault(struct pt_regs *regs, 
 good_area:
code = SEGV_ACCERR;
 
+   if (is_exec) {
+   /* protection fault */
+   if (error_code & 0x0800) 
+   goto bad_area;
+   if (!(vma->vm_flags & VM_EXEC)) 
+   goto bad_area;
/* a write */
-   if (is_write) {
+   } else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
/* a read */
} else {
-   /* protection fault */
-   if (error_code & 0x0800)
-   goto bad_area;
-   if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+   if (!(vma->vm_flags & VM_READ))
goto bad_area;
}
 
diff -puN arch/ppc64/mm/hash_low.S~nx-user-ppc64 arch/ppc64/mm/hash_low.S
--- linux-2.6-bk/arch/

Re: [PATCH 1/2] No-exec support for ppc64

2005-03-09 Thread Olof Johansson
On Tue, Mar 08, 2005 at 05:08:26PM -0600, Jake Moilanen wrote:
> No-exec base and user space support for PPC64.  

Hi, a couple of comments below.


-Olof

> @@ -786,6 +786,7 @@ int hash_huge_page(struct mm_struct *mm,
>   pte_t old_pte, new_pte;
>   unsigned long hpteflags, prpn;
>   long slot;
> + int is_exec;
>   int err = 1;
>  
>   spin_lock(&mm->page_table_lock);
> @@ -796,6 +797,10 @@ int hash_huge_page(struct mm_struct *mm,
>   va = (vsid << 28) | (ea & 0x0fff);
>   vpn = va >> HPAGE_SHIFT;
>  
> + is_exec = access & _PAGE_EXEC;
> + if (unlikely(is_exec && !(pte_val(*ptep) & _PAGE_EXEC)))
> + goto out;

You only use is_exec this one time, you can probably skip it and just
add the mask in the if statement.

> @@ -898,6 +908,7 @@ repeat:
>   err = 0;
>  
>   out:
> +
>   spin_unlock(&mm->page_table_lock);

Whitespace change

> diff -puN include/asm-ppc64/pgtable.h~nx-user-ppc64 
> include/asm-ppc64/pgtable.h
> --- linux-2.6-bk/include/asm-ppc64/pgtable.h~nx-user-ppc642005-03-08 
> 16:08:54 -06:00
> +++ linux-2.6-bk-moilanen/include/asm-ppc64/pgtable.h 2005-03-08 16:08:54 
> -06:00
> @@ -82,14 +82,14 @@
>  #define _PAGE_PRESENT0x0001 /* software: pte contains a translation 
> */
>  #define _PAGE_USER   0x0002 /* matches one of the PP bits */
>  #define _PAGE_FILE   0x0002 /* (!present only) software: pte holds file 
> offset */
> -#define _PAGE_RW 0x0004 /* software: user write access allowed */
> +#define _PAGE_EXEC   0x0004 /* No execute on POWER4 and newer (we invert) */

Good to see the comment there, I remember we talked about that earlier.
It can be somewhat confusing. :-)

>  #define _PAGE_GUARDED0x0008
>  #define _PAGE_COHERENT   0x0010 /* M: enforce memory coherence (SMP 
> systems) */
>  #define _PAGE_NO_CACHE   0x0020 /* I: cache inhibit */
>  #define _PAGE_WRITETHRU  0x0040 /* W: cache write-through */
>  #define _PAGE_DIRTY  0x0080 /* C: page changed */
>  #define _PAGE_ACCESSED   0x0100 /* R: page referenced */
> -#define _PAGE_EXEC   0x0200 /* software: i-cache coherence required */
> +#define _PAGE_RW 0x0200 /* software: user write access allowed */
>  #define _PAGE_HASHPTE0x0400 /* software: pte has an associated HPTE 
> */
>  #define _PAGE_BUSY   0x0800 /* software: PTE & hash are busy */ 
>  #define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
> @@ -100,7 +100,7 @@
>  /* PAGE_MASK gives the right answer below, but only by accident */
>  /* It should be preserving the high 48 bits and then specifically */
>  /* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
> -#define _PAGE_CHG_MASK   (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | 
> _PAGE_HPTEFLAGS)
> +#define _PAGE_CHG_MASK (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | 
> _PAGE_WRITETHRU | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HPTEFLAGS | PAGE_MASK)

Can you break it into 80 columns with \ ?

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] No-exec support for ppc64

2005-03-08 Thread Jake Moilanen
No-exec base and user space support for PPC64.  

This will prohibit user space apps that a compile w/ PT_GNU_STACK from
executing in segments that are non-executable.  Non-PT_GNU_STACK
compiled apps will work as well, but will not be able to take advantage
of the no-exec feature.

Signed-off-by: Jake Moilanen <[EMAIL PROTECTED]>

---

 linux-2.6-bk-moilanen/arch/ppc64/kernel/head.S |5 +
 linux-2.6-bk-moilanen/arch/ppc64/kernel/iSeries_htab.c |4 +
 linux-2.6-bk-moilanen/arch/ppc64/kernel/pSeries_lpar.c |2 
 linux-2.6-bk-moilanen/arch/ppc64/mm/fault.c|   14 +++--
 linux-2.6-bk-moilanen/arch/ppc64/mm/hash_low.S |   12 ++--
 linux-2.6-bk-moilanen/arch/ppc64/mm/hugetlbpage.c  |   13 
 linux-2.6-bk-moilanen/fs/binfmt_elf.c  |2 
 linux-2.6-bk-moilanen/include/asm-ppc64/elf.h  |7 ++
 linux-2.6-bk-moilanen/include/asm-ppc64/page.h |   19 ++-
 linux-2.6-bk-moilanen/include/asm-ppc64/pgtable.h  |   45 +
 10 files changed, 87 insertions(+), 36 deletions(-)

diff -puN arch/ppc64/kernel/head.S~nx-user-ppc64 arch/ppc64/kernel/head.S
--- linux-2.6-bk/arch/ppc64/kernel/head.S~nx-user-ppc64 2005-03-08 16:08:54 
-06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/kernel/head.S  2005-03-08 16:08:54 
-06:00
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include
 #include 
 
 #ifdef CONFIG_PPC_ISERIES
@@ -950,11 +951,11 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 * accessing a userspace segment (even from the kernel). We assume
 * kernel addresses always have the high bit set.
 */
-   rlwinm  r4,r4,32-23,29,29   /* DSISR_STORE -> _PAGE_RW */
+   rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
rotldi  r0,r3,15/* Move high bit into MSR_PR posn */
orc r0,r12,r0   /* MSR_PR | ~high_bit */
rlwimi  r4,r0,32-13,30,30   /* becomes _PAGE_USER access bit */
-   ori r4,r4,1 /* add _PAGE_PRESENT */
+   rlwimi  r4,r5,22+2,31-2,31-2/* Set _PAGE_EXEC if trap is 0x400 */
 
/*
 * On iSeries, we soft-disable interrupts here, then
diff -puN arch/ppc64/kernel/iSeries_htab.c~nx-user-ppc64 
arch/ppc64/kernel/iSeries_htab.c
--- linux-2.6-bk/arch/ppc64/kernel/iSeries_htab.c~nx-user-ppc64 2005-03-08 
16:08:54 -06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/kernel/iSeries_htab.c  2005-03-08 
16:08:54 -06:00
@@ -144,6 +144,10 @@ static long iSeries_hpte_updatepp(unsign
 
HvCallHpt_get(&hpte, slot);
if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {
+   /*
+* Hypervisor expects bit's as NPPP, which is
+* different from how they are mapped in our PP.
+*/
HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1));
iSeries_hunlock(slot);
return 0;
diff -puN arch/ppc64/kernel/pSeries_lpar.c~nx-user-ppc64 
arch/ppc64/kernel/pSeries_lpar.c
--- linux-2.6-bk/arch/ppc64/kernel/pSeries_lpar.c~nx-user-ppc64 2005-03-08 
16:08:54 -06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/kernel/pSeries_lpar.c  2005-03-08 
16:08:54 -06:00
@@ -470,7 +470,7 @@ static void pSeries_lpar_hpte_updatebolt
slot = pSeries_lpar_hpte_find(vpn);
BUG_ON(slot == -1);
 
-   flags = newpp & 3;
+   flags = newpp & 7;
lpar_rc = plpar_pte_protect(flags, slot, 0);
 
BUG_ON(lpar_rc != H_Success);
diff -puN arch/ppc64/mm/fault.c~nx-user-ppc64 arch/ppc64/mm/fault.c
--- linux-2.6-bk/arch/ppc64/mm/fault.c~nx-user-ppc642005-03-08 16:08:54 
-06:00
+++ linux-2.6-bk-moilanen/arch/ppc64/mm/fault.c 2005-03-08 16:08:54 -06:00
@@ -93,6 +93,7 @@ int do_page_fault(struct pt_regs *regs, 
unsigned long code = SEGV_MAPERR;
unsigned long is_write = error_code & 0x0200;
unsigned long trap = TRAP(regs);
+   unsigned long is_exec = trap == 0x400;  
 
BUG_ON((trap == 0x380) || (trap == 0x480));
 
@@ -199,16 +200,19 @@ int do_page_fault(struct pt_regs *regs, 
 good_area:
code = SEGV_ACCERR;
 
+   if (is_exec) {
+   /* protection fault */
+   if (error_code & 0x0800) 
+   goto bad_area;
+   if (!(vma->vm_flags & VM_EXEC)) 
+   goto bad_area;
/* a write */
-   if (is_write) {
+   } else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
/* a read */
} else {
-   /* protection fault */
-   if (error_code & 0x0800)
-   goto bad_area;
-   if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+   if (!(vma->vm_flags & VM_READ))
goto bad_area;
}
 
diff -puN arch/ppc64/mm/hash_low.S~nx-user-ppc64 arch/ppc64/mm/hash_low.S
--- linux-2.6-bk/arch/ppc64/mm/hash_low.S~nx-user-ppc64 2005-03-0