Commit e2801b51 authored by Anton Blanchard's avatar Anton Blanchard

[PATCH] ppc64: fix kernel access of user pages

Set the ks bit on userspace segments otherwise the kernel can read/write
into userspace mprotected pages.
parent 565a552f
......@@ -826,7 +826,14 @@ SystemCall_common:
_GLOBAL(do_hash_page_ISI)
li r4,0
_GLOBAL(do_hash_page_DSI)
rlwimi r4,r23,32-13,30,30 /* Insert MSR_PR as _PAGE_USER */
/*
* We need to set the _PAGE_USER bit if MSR_PR is set or if we are
* accessing a userspace segment (even from the kernel). We assume
* kernel addresses always have the high bit set.
*/
rotldi r0,r3,15 /* Move high bit into MSR_PR position */
orc r0,r23,r0
rlwimi r4,r0,32-13,30,30 /* Insert into _PAGE_USER */
ori r4,r4,1 /* add _PAGE_PRESENT */
mflr r21 /* Save LR in r21 */
......
......@@ -77,6 +77,8 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
unsigned long entry, group, old_esid, castout_entry, i;
unsigned int global_entry;
STE *ste, *castout_ste;
unsigned long kernel_segment = (REGION_ID(esid << SID_SHIFT) !=
USER_REGION_ID);
/* Search the primary group first. */
global_entry = (esid & 0x1f) << 3;
......@@ -89,6 +91,8 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
ste->dw1.dw1.vsid = vsid;
ste->dw0.dw0.esid = esid;
ste->dw0.dw0.kp = 1;
if (!kernel_segment)
ste->dw0.dw0.ks = 1;
asm volatile("eieio":::"memory");
ste->dw0.dw0.v = 1;
return (global_entry | entry);
......@@ -135,6 +139,8 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid)
old_esid = castout_ste->dw0.dw0.esid;
castout_ste->dw0.dw0.esid = esid;
castout_ste->dw0.dw0.kp = 1;
if (!kernel_segment)
castout_ste->dw0.dw0.ks = 1;
asm volatile("eieio" : : : "memory"); /* Order update */
castout_ste->dw0.dw0.v = 1;
asm volatile("slbie %0" : : "r" (old_esid << SID_SHIFT));
......@@ -344,6 +350,8 @@ static void make_slbe(unsigned long esid, unsigned long vsid, int large,
vsid_data.data.l = 1;
if (kernel_segment)
vsid_data.data.c = 1;
else
vsid_data.data.ks = 1;
esid_data.word0 = 0;
esid_data.data.esid = esid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment