git: 9front

Download patch

ref: 40042152f5dc3ba4db801b85f6ca4fb5dbbc188b
parent: dbee0efe67420cc925e1a46de6c6fd3f3ab5e70d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jul 12 17:42:26 EDT 2020

kernel: make segments non-executable when icache is not maintained

This change makes it mandatory for programs to call segflush() on
code that is not in the text segment if they want to execute it.

As a side effect, this means that everything but the text segment
will be non-executable by default, even without the SG_NOEXEC
attribute. Segments with the SG_NOEXEC attribute never become
executable, even when segflush() is called on them.

--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -221,7 +221,7 @@
 	}
 
 #ifdef PTENOEXEC
-	if((s->type & SG_NOEXEC) != 0)
+	if((s->type & SG_NOEXEC) != 0 || s->flushme == 0)
 		mmuphys |= PTENOEXEC;
 #endif
 
@@ -242,6 +242,8 @@
 	pg.ref = 1;
 	pg.va = addr;
 	pg.pa = s->pseg->pa+(addr-s->base);
+	if(s->flushme)
+		pg.txtflush = ~0;
 
 	mmuphys = PPN(pg.pa) | PTEVALID;
 	if((attr & SG_RONLY) == 0)
@@ -250,7 +252,7 @@
 		mmuphys |= PTERONLY;
 
 #ifdef PTENOEXEC
-	if((attr & SG_NOEXEC) != 0)
+	if((attr & SG_NOEXEC) != 0 || s->flushme == 0)
 		mmuphys |= PTENOEXEC;
 #endif
 
@@ -303,7 +305,7 @@
 			attr |= s->pseg->attr;
 
 		if((attr & SG_FAULT) != 0
-		|| read? (attr & SG_NOEXEC) != 0 && (addr & -BY2PG) == (pc & -BY2PG):
+		|| read? ((attr & SG_NOEXEC) != 0 || s->flushme == 0) && (addr & -BY2PG) == (pc & -BY2PG):
 			 (attr & SG_RONLY) != 0) {
 			qunlock(s);
 			up->psstate = sps;
--