* A question about PROT_NONE on Sparc and Sparc64
@ 2004-06-30 3:05 Jamie Lokier
2004-06-30 5:17 ` David S. Miller
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jamie Lokier @ 2004-06-30 3:05 UTC (permalink / raw)
To: Keith M. Wesolowski, sparclinux, David S. Miller, ultralinux; +Cc: linux-kernel
Hi folks,
I'm doing a survey of the different architectural implementations of
PROT_* flags for mmap() and mprotect(). I'm looking at linux-2.6.5.
The Sparc and Sparc64 implementations are very similar to plain x86:
read implies exec, exec implies read and write implies read.
(Aside: A comment in include/asm-sparc/pgtsrmmu.h says that finer-grained
access is possible. Quite a few other architectures do implement
finer-grained access, and even x86 is getting it now, so you may want
to revisit that. The code is already available, and tested, if you
cut that part out of the PaX security patch).
I see a potential bug with PROT_NONE. I'm not sure if it's real, so
could you please confirm? I don't know the Sparc well enough to tell.
In include/asm-sparc64/pgtable.h, there's:
#define __ACCESS_BITS (_PAGE_ACCESSED | _PAGE_READ | _PAGE_R)
#define PAGE_NONE __pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE)
#define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
__ACCESS_BITS)
PAGE_NONE has the hardware _PAGE_PRESENT bit set. However unlike
PAGE_READONLY, it doesn't have the hardware _PAGE_R and software
_PAGE_READ bits.
I guess that means that PAGE_NONE pages aren't readable from
userspace. Presumably the TLB handler takes care of it.
Does it prevent reads from kernel space as well?
I.e. can you confirm that write() won't succeed in reading the data
from a PROT_NONE page on Sparc64? I think that's probably the case.
You'll see why I ask, from the next one:
In include/asm-sparc/pgtsrmmu.h, there's:
#define SRMMU_PAGE_NONE __pgprot(SRMMU_VALID | SRMMU_CACHE | \
SRMMU_PRIV | SRMMU_REF)
#define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
SRMMU_EXEC | SRMMU_REF)
This one bothers me. The difference is that PROT_NONE pages are not
accessible to userspace, and not executable.
So userspace will get a fault if it tries to read a PROT_NONE page.
But what happens when the kernel reads one? Don't those bits mean
that the read will succeed? I.e. write() on a PROT_NONE page will
succeed, instead of returning EFAULT?
If so, this is a bug. A minor bug, perhaps, but nonetheless I wish to
document it.
I don't know if you would be able to rearrange the pte bits so that a
PROT_NONE page is not accessible to the kernel either. E.g. on i386
this is done by making PROT_NONE not set the "physical" present bit
but a different bit, and "pte_present()" tests both of those bits to
test the virtual present bit.
Alternatively, perhaps in this case simply omitting the SRMMU_REF bit
would be enough? Would that cause the TLB handler to be entered, and
the TLB handler could then refuse access? Again, I don't know enough
about Sparc to say more.
Looking at pgtsun4.h and pgtsun4c.h, I'm not sure about those either.
Thanks,
-- Jamie
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 3:05 A question about PROT_NONE on Sparc and Sparc64 Jamie Lokier
@ 2004-06-30 5:17 ` David S. Miller
2004-06-30 15:21 ` wesolows
2004-06-30 8:28 ` Jakub Jelinek
2004-07-02 1:03 ` A question about PROT_NONE on Sun4c 32-bit Sparc Jamie Lokier
2 siblings, 1 reply; 10+ messages in thread
From: David S. Miller @ 2004-06-30 5:17 UTC (permalink / raw)
To: Jamie Lokier; +Cc: wesolows, sparclinux, ultralinux, linux-kernel, wesolows
On Wed, 30 Jun 2004 04:05:03 +0100
Jamie Lokier <jamie@shareable.org> wrote:
> In include/asm-sparc64/pgtable.h, there's:
>
> #define __ACCESS_BITS (_PAGE_ACCESSED | _PAGE_READ | _PAGE_R)
> #define PAGE_NONE __pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE)
> #define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
> __ACCESS_BITS)
>
> PAGE_NONE has the hardware _PAGE_PRESENT bit set. However unlike
> PAGE_READONLY, it doesn't have the hardware _PAGE_R and software
> _PAGE_READ bits.
>
> I guess that means that PAGE_NONE pages aren't readable from
> userspace. Presumably the TLB handler takes care of it.
> Does it prevent reads from kernel space as well?
Neither user nor kernel can get at that page. If _PAGE_R is not set
we get a real fault no matter who attempts the access.
> I.e. can you confirm that write() won't succeed in reading the data
> from a PROT_NONE page on Sparc64? I think that's probably the case.
> You'll see why I ask, from the next one:
That's correct.
> In include/asm-sparc/pgtsrmmu.h, there's:
>
> #define SRMMU_PAGE_NONE __pgprot(SRMMU_VALID | SRMMU_CACHE | \
> SRMMU_PRIV | SRMMU_REF)
> #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
> SRMMU_EXEC | SRMMU_REF)
>
> This one bothers me. The difference is that PROT_NONE pages are not
> accessible to userspace, and not executable.
>
> So userspace will get a fault if it tries to read a PROT_NONE page.
>
> But what happens when the kernel reads one? Don't those bits mean
> that the read will succeed? I.e. write() on a PROT_NONE page will
> succeed, instead of returning EFAULT?
>
> If so, this is a bug. A minor bug, perhaps, but nonetheless I wish to
> document it.
Yes this one is a bug and not intentional.
Keith W., we need to fix this. Probably the simplest fix is just to
drop the SRMMU_VALID bit.
> Alternatively, perhaps in this case simply omitting the SRMMU_REF bit
> would be enough? Would that cause the TLB handler to be entered, and
> the TLB handler could then refuse access? Again, I don't know enough
> about Sparc to say more.
No, if it's SRMMU_VALID the hardware lets the translation succeed and
like on x86 the hardware does the page table walk and thus the SRMMU_REF
bit setting.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 3:05 A question about PROT_NONE on Sparc and Sparc64 Jamie Lokier
2004-06-30 5:17 ` David S. Miller
@ 2004-06-30 8:28 ` Jakub Jelinek
2004-06-30 20:54 ` David S. Miller
2004-07-02 1:03 ` A question about PROT_NONE on Sun4c 32-bit Sparc Jamie Lokier
2 siblings, 1 reply; 10+ messages in thread
From: Jakub Jelinek @ 2004-06-30 8:28 UTC (permalink / raw)
To: Jamie Lokier
Cc: Keith M. Wesolowski, sparclinux, David S. Miller, ultralinux,
linux-kernel
On Wed, Jun 30, 2004 at 04:05:03AM +0100, Jamie Lokier wrote:
> I'm doing a survey of the different architectural implementations of
> PROT_* flags for mmap() and mprotect(). I'm looking at linux-2.6.5.
>
> The Sparc and Sparc64 implementations are very similar to plain x86:
> read implies exec, exec implies read and write implies read.
>
> (Aside: A comment in include/asm-sparc/pgtsrmmu.h says that finer-grained
> access is possible. Quite a few other architectures do implement
> finer-grained access, and even x86 is getting it now, so you may want
> to revisit that. The code is already available, and tested, if you
> cut that part out of the PaX security patch).
I believe R!X and X!R pages ought to be possible on sparc64 too, just use a
different bit as "read" in the fast ITLB miss handler from the one fast DTLB
miss uses.
Jakub
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 5:17 ` David S. Miller
@ 2004-06-30 15:21 ` wesolows
0 siblings, 0 replies; 10+ messages in thread
From: wesolows @ 2004-06-30 15:21 UTC (permalink / raw)
To: David S. Miller; +Cc: Jamie Lokier, sparclinux, ultralinux, linux-kernel
On Tue, Jun 29, 2004 at 10:17:11PM -0700, David S. Miller wrote:
> > In include/asm-sparc/pgtsrmmu.h, there's:
> >
> > #define SRMMU_PAGE_NONE __pgprot(SRMMU_VALID | SRMMU_CACHE | \
> > SRMMU_PRIV | SRMMU_REF)
> > #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
> > SRMMU_EXEC | SRMMU_REF)
> >
> > This one bothers me. The difference is that PROT_NONE pages are not
> > accessible to userspace, and not executable.
> >
> > So userspace will get a fault if it tries to read a PROT_NONE page.
> >
> > But what happens when the kernel reads one? Don't those bits mean
> > that the read will succeed? I.e. write() on a PROT_NONE page will
> > succeed, instead of returning EFAULT?
> >
> > If so, this is a bug. A minor bug, perhaps, but nonetheless I wish to
> > document it.
>
> Yes this one is a bug and not intentional.
>
> Keith W., we need to fix this. Probably the simplest fix is just to
> drop the SRMMU_VALID bit.
Ok, I'll try this approach and see what happens.
--
Keith M Wesolowski
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 8:28 ` Jakub Jelinek
@ 2004-06-30 20:54 ` David S. Miller
2004-06-30 22:52 ` Jamie Lokier
0 siblings, 1 reply; 10+ messages in thread
From: David S. Miller @ 2004-06-30 20:54 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: jamie, wesolows, sparclinux, ultralinux, linux-kernel
On Wed, 30 Jun 2004 04:28:05 -0400
Jakub Jelinek <jakub@redhat.com> wrote:
> I believe R!X and X!R pages ought to be possible on sparc64 too, just use a
> different bit as "read" in the fast ITLB miss handler from the one fast DTLB
> miss uses.
That's correct. But I have no plans to implement this
any time soon :-)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 20:54 ` David S. Miller
@ 2004-06-30 22:52 ` Jamie Lokier
2004-07-01 5:25 ` David S. Miller
2004-07-01 7:47 ` David S. Miller
0 siblings, 2 replies; 10+ messages in thread
From: Jamie Lokier @ 2004-06-30 22:52 UTC (permalink / raw)
To: Jakub Jelinek
Cc: David S. Miller, wesolows, sparclinux, ultralinux, linux-kernel
David S. Miller wrote:
> On Wed, 30 Jun 2004 04:28:05 -0400
> Jakub Jelinek <jakub@redhat.com> wrote:
>
> > I believe R!X and X!R pages ought to be possible on sparc64 too,
> > just use a different bit as "read" in the fast ITLB miss handler
> > from the one fast DTLB miss uses.
>
> That's correct. But I have no plans to implement this
> any time soon :-)
The PaX security patch already implements R!X pages on Sparc64, so you
could just cut out that part of the patch. Just pick out the changes
to arch/sparc64/* and include/asm-sparc64/*:
http://pax.grsecurity.net/pax-linux-2.6.7-200406252135.patch
It appears to use exactly the technique Jakub describes, and has been tested.
-- Jamie
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 22:52 ` Jamie Lokier
@ 2004-07-01 5:25 ` David S. Miller
2004-07-01 7:47 ` David S. Miller
1 sibling, 0 replies; 10+ messages in thread
From: David S. Miller @ 2004-07-01 5:25 UTC (permalink / raw)
To: Jamie Lokier; +Cc: jakub, wesolows, sparclinux, ultralinux, linux-kernel
On Wed, 30 Jun 2004 23:52:20 +0100
Jamie Lokier <jamie@shareable.org> wrote:
> The PaX security patch already implements R!X pages on Sparc64, so you
> could just cut out that part of the patch. Just pick out the changes
> to arch/sparc64/* and include/asm-sparc64/*:
>
> http://pax.grsecurity.net/pax-linux-2.6.7-200406252135.patch
>
> It appears to use exactly the technique Jakub describes, and has been tested.
Great, I'm integrating something along these lines right now.
Do you have any idea who authored the sparc64 bits so I can give
them credit?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sparc and Sparc64
2004-06-30 22:52 ` Jamie Lokier
2004-07-01 5:25 ` David S. Miller
@ 2004-07-01 7:47 ` David S. Miller
1 sibling, 0 replies; 10+ messages in thread
From: David S. Miller @ 2004-07-01 7:47 UTC (permalink / raw)
To: Jamie Lokier; +Cc: jakub, wesolows, sparclinux, ultralinux, linux-kernel
On Wed, 30 Jun 2004 23:52:20 +0100
Jamie Lokier <jamie@shareable.org> wrote:
> The PaX security patch already implements R!X pages on Sparc64, so you
> could just cut out that part of the patch. Just pick out the changes
> to arch/sparc64/* and include/asm-sparc64/*:
>
> http://pax.grsecurity.net/pax-linux-2.6.7-200406252135.patch
>
> It appears to use exactly the technique Jakub describes, and has been tested.
Again, thanks for pointing this out. I'm going to push the following
upstream to Linus for 2.6.x and I'm going to backport this to 2.4.x
as well.
It makes your test_prot program do the following on my UltraSPARC-III
machine.
Requested PROT | --- R-- -W- RW- --X R-X -WX RWX
========================================================================
MAP_SHARED | --- r-- !w- rw- r-x r-x rwx rwx
MAP_PRIVATE | --- r-- !w- rw- r-x r-x rwx rwx
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
# 2004/07/01 00:38:22-07:00 davem@nuts.davemloft.net
# [SPARC64]: Non-executable page support.
#
# Based upon the PAX patches.
#
# Signed-off-by: David S. Miller <davem@redhat.com>
#
# include/asm-sparc64/pgtable.h
# 2004/07/01 00:37:55-07:00 davem@nuts.davemloft.net +21 -10
# [SPARC64]: Non-executable page support.
#
# Based upon the PAX patches.
#
# Signed-off-by: David S. Miller <davem@redhat.com>
#
# arch/sparc64/mm/fault.c
# 2004/07/01 00:37:55-07:00 davem@nuts.davemloft.net +11 -1
# [SPARC64]: Non-executable page support.
#
# Based upon the PAX patches.
#
# Signed-off-by: David S. Miller <davem@redhat.com>
#
# arch/sparc64/kernel/itlb_base.S
# 2004/07/01 00:37:55-07:00 davem@nuts.davemloft.net +3 -3
# [SPARC64]: Non-executable page support.
#
# Based upon the PAX patches.
#
# Signed-off-by: David S. Miller <davem@redhat.com>
#
# ChangeSet
# 2004/06/30 23:02:26-07:00 davem@nuts.davemloft.net
# [SPARC64]: Reserve a software PTE bit for _PAGE_EXEC.
#
# Based upon the PAX sparc64 patches. Also, reformat
# the comments here so the lines fit in 80 columns.
#
# Signed-off-by: David S. Miller <davem@redhat.com>
#
# include/asm-sparc64/pgtable.h
# 2004/06/30 23:02:00-07:00 davem@nuts.davemloft.net +42 -29
# [SPARC64]: Reserve a software PTE bit for _PAGE_EXEC.
#
# Based upon the PAX sparc64 patches. Also, reformat
# the comments here so the lines fit in 80 columns.
#
# Signed-off-by: David S. Miller <davem@redhat.com>
#
# ChangeSet
# 2004/06/30 20:21:47-07:00 davem@nuts.davemloft.net
# [SPARC64]: Document reserved and soft2 bits in PTE.
#
# include/asm-sparc64/pgtable.h
# 2004/06/30 20:21:22-07:00 davem@nuts.davemloft.net +3 -0
# [SPARC64]: Document reserved and soft2 bits in PTE.
#
diff -Nru a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S
--- a/arch/sparc64/kernel/itlb_base.S 2004-07-01 00:40:02 -07:00
+++ b/arch/sparc64/kernel/itlb_base.S 2004-07-01 00:40:02 -07:00
@@ -41,6 +41,9 @@
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE
1: brgez,pn %g5, 3f ! Not valid, branch out
+ sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot
+ andcc %g5, %g4, %g0 ! Executable?
+ be,pn %xcc, 3f ! Nope, branch.
nop ! Delay-slot
2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
retry ! Trap return
@@ -69,9 +72,6 @@
done ! Do it to it
/* ITLB ** ICACHE line 4: Unused... */
- nop
- nop
- nop
nop
nop
nop
diff -Nru a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
--- a/arch/sparc64/mm/fault.c 2004-07-01 00:40:02 -07:00
+++ b/arch/sparc64/mm/fault.c 2004-07-01 00:40:02 -07:00
@@ -257,7 +257,7 @@
* in that case.
*/
- if (!(fault_code & FAULT_CODE_WRITE) &&
+ if (!(fault_code & (FAULT_CODE_WRITE|FAULT_CODE_ITLB)) &&
(insn & 0xc0800000) == 0xc0800000) {
if (insn & 0x2000)
asi = (regs->tstate >> 24);
@@ -408,6 +408,16 @@
*/
good_area:
si_code = SEGV_ACCERR;
+
+ /* If we took a ITLB miss on a non-executable page, catch
+ * that here.
+ */
+ if ((fault_code & FAULT_CODE_ITLB) && !(vma->vm_flags & VM_EXEC)) {
+ BUG_ON(address != regs->tpc);
+ BUG_ON(regs->tstate & TSTATE_PRIV);
+ goto bad_area;
+ }
+
if (fault_code & FAULT_CODE_WRITE) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h 2004-07-01 00:40:02 -07:00
+++ b/include/asm-sparc64/pgtable.h 2004-07-01 00:40:02 -07:00
@@ -106,33 +106,49 @@
#endif /* !(__ASSEMBLY__) */
/* Spitfire/Cheetah TTE bits. */
-#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */
-#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date */
-#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */
-#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */
-#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */
-#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */
-#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */
-#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */
-#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */
-#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr [40:13]*/
-#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr [42:13] */
-#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */
-#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */
-#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */
-#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */
-#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */
-#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */
-#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */
-#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */
-
-/* Here are the SpitFire software bits we use in the TTE's. */
-#define _PAGE_FILE _AC(0x0000000000001000,UL) /* Pagecache page */
-#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */
-#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */
-#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */
-#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */
-#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */
+#define _PAGE_VALID _AC(0x8000000000000000,UL) /* Valid TTE */
+#define _PAGE_R _AC(0x8000000000000000,UL) /* Keep ref bit up to date*/
+#define _PAGE_SZ4MB _AC(0x6000000000000000,UL) /* 4MB Page */
+#define _PAGE_SZ512K _AC(0x4000000000000000,UL) /* 512K Page */
+#define _PAGE_SZ64K _AC(0x2000000000000000,UL) /* 64K Page */
+#define _PAGE_SZ8K _AC(0x0000000000000000,UL) /* 8K Page */
+#define _PAGE_NFO _AC(0x1000000000000000,UL) /* No Fault Only */
+#define _PAGE_IE _AC(0x0800000000000000,UL) /* Invert Endianness */
+#define _PAGE_SOFT2 _AC(0x07FC000000000000,UL) /* Software bits, set 2 */
+#define _PAGE_RES1 _AC(0x0003000000000000,UL) /* Reserved */
+#define _PAGE_SN _AC(0x0000800000000000,UL) /* (Cheetah) Snoop */
+#define _PAGE_RES2 _AC(0x0000780000000000,UL) /* Reserved */
+#define _PAGE_PADDR_SF _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/
+#define _PAGE_PADDR _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr[42:13] */
+#define _PAGE_SOFT _AC(0x0000000000001F80,UL) /* Software bits */
+#define _PAGE_L _AC(0x0000000000000040,UL) /* Locked TTE */
+#define _PAGE_CP _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */
+#define _PAGE_CV _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */
+#define _PAGE_E _AC(0x0000000000000008,UL) /* side-Effect */
+#define _PAGE_P _AC(0x0000000000000004,UL) /* Privileged Page */
+#define _PAGE_W _AC(0x0000000000000002,UL) /* Writable */
+#define _PAGE_G _AC(0x0000000000000001,UL) /* Global */
+
+/* Here are the SpitFire software bits we use in the TTE's.
+ *
+ * WARNING: If you are going to try and start using some
+ * of the soft2 bits, you will need to make
+ * modifications to the swap entry implementation.
+ * For example, one thing that could happen is that
+ * swp_entry_to_pte() would BUG_ON() if you tried
+ * to use one of the soft2 bits for _PAGE_FILE.
+ *
+ * Like other architectures, I have aliased _PAGE_FILE with
+ * _PAGE_MODIFIED. This works because _PAGE_FILE is never
+ * interpreted that way unless _PAGE_PRESENT is clear.
+ */
+#define _PAGE_EXEC _AC(0x0000000000001000,UL) /* Executable SW bit */
+#define _PAGE_MODIFIED _AC(0x0000000000000800,UL) /* Modified (dirty) */
+#define _PAGE_FILE _AC(0x0000000000000800,UL) /* Pagecache page */
+#define _PAGE_ACCESSED _AC(0x0000000000000400,UL) /* Accessed (ref'd) */
+#define _PAGE_READ _AC(0x0000000000000200,UL) /* Readable SW Bit */
+#define _PAGE_WRITE _AC(0x0000000000000100,UL) /* Writable SW Bit */
+#define _PAGE_PRESENT _AC(0x0000000000000080,UL) /* Present */
#if PAGE_SHIFT == 13
#define _PAGE_SZBITS _PAGE_SZ8K
@@ -164,16 +180,27 @@
/* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
#define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
- __ACCESS_BITS | _PAGE_WRITE)
+ __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
#define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
- __ACCESS_BITS)
+ __ACCESS_BITS | _PAGE_EXEC)
#define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
- __ACCESS_BITS)
+ __ACCESS_BITS | _PAGE_EXEC)
#define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
- __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
+ __PRIV_BITS | \
+ __ACCESS_BITS | __DIRTY_BITS | _PAGE_EXEC)
+
+#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
+ _PAGE_CACHE | \
+ __ACCESS_BITS | _PAGE_WRITE)
+
+#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
+ _PAGE_CACHE | __ACCESS_BITS)
+
+#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
+ _PAGE_CACHE | __ACCESS_BITS)
#define _PFN_MASK _PAGE_PADDR
@@ -181,18 +208,18 @@
__ACCESS_BITS | _PAGE_E)
#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
+#define __P001 PAGE_READONLY_NOEXEC
+#define __P010 PAGE_COPY_NOEXEC
+#define __P011 PAGE_COPY_NOEXEC
#define __P100 PAGE_READONLY
#define __P101 PAGE_READONLY
#define __P110 PAGE_COPY
#define __P111 PAGE_COPY
#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
+#define __S001 PAGE_READONLY_NOEXEC
+#define __S010 PAGE_SHARED_NOEXEC
+#define __S011 PAGE_SHARED_NOEXEC
#define __S100 PAGE_READONLY
#define __S101 PAGE_READONLY
#define __S110 PAGE_SHARED
^ permalink raw reply [flat|nested] 10+ messages in thread
* A question about PROT_NONE on Sun4c 32-bit Sparc
2004-06-30 3:05 A question about PROT_NONE on Sparc and Sparc64 Jamie Lokier
2004-06-30 5:17 ` David S. Miller
2004-06-30 8:28 ` Jakub Jelinek
@ 2004-07-02 1:03 ` Jamie Lokier
2004-07-02 4:11 ` Keith M. Wesolowski
2 siblings, 1 reply; 10+ messages in thread
From: Jamie Lokier @ 2004-07-02 1:03 UTC (permalink / raw)
To: Keith M. Wesolowski; +Cc: David S. Miller, linux-kernel, sparclinux
Hi Keith,
David Miller suggested I ask you specifically about the Sun4 & Sun4c
32-bit Sparc ports of Linux. He's confirmed a bug in the SRMMU 32-bit
Sparc port, and I just wanted you to confirm it isn't in the other
32-bit Sparc ports.
I would like to know if the Sun4 and Sun4c ports have the same bug.
I'm guessing not, but it's not clear to me from the code.
In linux-2.6.5/include/asm-sparc/pgtsun4.h (pgtsun4c.h is similar):
#define _SUN4C_PAGE_VALID 0x80000000
#define _SUN4C_PAGE_SILENT_READ 0x80000000 /* synonym */
#define _SUN4C_PAGE_DIRTY 0x40000000
#define _SUN4C_PAGE_SILENT_WRITE 0x40000000 /* synonym */
...
#define _SUN4C_PAGE_READ 0x00800000 /* implemented in software */
#define _SUN4C_PAGE_WRITE 0x00400000 /* implemented in software */
#define _SUN4C_PAGE_ACCESSED 0x00200000 /* implemented in software */
#define _SUN4C_PAGE_MODIFIED 0x00100000 /* implemented in software */
...
#define _SUN4C_READABLE (_SUN4C_PAGE_READ|_SUN4C_PAGE_SILENT_READ|\
_SUN4C_PAGE_ACCESSED)
#define _SUN4C_WRITEABLE (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE|\
_SUN4C_PAGE_MODIFIED)
...
#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_PRESENT)
#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE|\
_SUN4C_PAGE_WRITE)
#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE)
SUN4C_PAGE_NONE corresponds to PROT_NONE mmap memory protection.
The question is whether PROT_NONE pages are readable by the _kernel_.
I.e. whether write() would successfully read from those pages.
>From the names of the above macros, I'm guessing not. There's nothing
to indicate that they would be. I just wanted you to confirm, thanks.
(In the SRMMU 32-Sparc version, PROT_NONE pages _are_ readable in the
kernel, because of the way they are implemented by making them
priveleged pages.)
(By the way, as the sun4 files don't contain a definition of
_SUN4_PAGE_FILE or pgoff_to_pte, but the sun4c one do, I guess the
sun4 sub-architecture doesn't build in 2.6 but sun4c does?)
Thanks,
-- Jamie
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: A question about PROT_NONE on Sun4c 32-bit Sparc
2004-07-02 1:03 ` A question about PROT_NONE on Sun4c 32-bit Sparc Jamie Lokier
@ 2004-07-02 4:11 ` Keith M. Wesolowski
0 siblings, 0 replies; 10+ messages in thread
From: Keith M. Wesolowski @ 2004-07-02 4:11 UTC (permalink / raw)
To: Jamie Lokier; +Cc: David S. Miller, linux-kernel, sparclinux
On Fri, Jul 02, 2004 at 02:03:49AM +0100, Jamie Lokier wrote:
> I would like to know if the Sun4 and Sun4c ports have the same bug.
> I'm guessing not, but it's not clear to me from the code.
No, this code is ok.
> #define _SUN4C_PAGE_VALID 0x80000000
> #define _SUN4C_PAGE_SILENT_READ 0x80000000 /* synonym */
> ...
> #define _SUN4C_PAGE_READ 0x00800000 /* implemented in software */
> ...
> #define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_PRESENT)
> SUN4C_PAGE_NONE corresponds to PROT_NONE mmap memory protection.
> The question is whether PROT_NONE pages are readable by the _kernel_.
> I.e. whether write() would successfully read from those pages.
No, they are not. The _SUN4C_PAGE_SILENT_READ is the bit that allows
reading the page without trapping. If it's not set, you trap, and
do_sun4c_fault tests _SUN4C_PAGE_READ with no special case for
user/kernel. Since PROT_NONE doesn't include that bit, it's an oops.
> (By the way, as the sun4 files don't contain a definition of
> _SUN4_PAGE_FILE or pgoff_to_pte, but the sun4c one do, I guess the
> sun4 sub-architecture doesn't build in 2.6 but sun4c does?)
Correct, although I recently fixed this in my tree. It now builds but
nobody has tested it in ages and I believe it doesn't work.
--
Keith M Wesolowski
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2004-07-02 4:11 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-30 3:05 A question about PROT_NONE on Sparc and Sparc64 Jamie Lokier
2004-06-30 5:17 ` David S. Miller
2004-06-30 15:21 ` wesolows
2004-06-30 8:28 ` Jakub Jelinek
2004-06-30 20:54 ` David S. Miller
2004-06-30 22:52 ` Jamie Lokier
2004-07-01 5:25 ` David S. Miller
2004-07-01 7:47 ` David S. Miller
2004-07-02 1:03 ` A question about PROT_NONE on Sun4c 32-bit Sparc Jamie Lokier
2004-07-02 4:11 ` Keith M. Wesolowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox