shithub: riscv

Download patch

ref: 3b661a96effa96d211676181aa5206d1a6e42113
parent: 0bc51a90b0e9903ede7edb4750c415e9d6f422c7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Aug 16 20:50:20 EDT 2014

kernel: make noswap flag exclude processes from killbig() if not eve, reset noswap flag on exec

--- a/sys/man/3/proc
+++ b/sys/man/3/proc
@@ -301,32 +301,39 @@
 and
 .IR exec (2).
 .TP 10n
-.B "close\ \fIn
-Close file descriptor
-.I n
-in the process.
-.TP 10n
-.B closefiles
-Close all open file descriptors in the process.
-.TP 10n
 .B nohang
 Clear the hang bit.
 .TP 10n
+.B private
+Make it impossible to read the process's user memory.
+This property is inherited on
+.IR fork (2),
+cleared on
+.IR exec (2),
+and is not otherwise resettable.
+.TP 10n
 .B noswap
 Don't allow this process to be swapped out.  This should
 be used carefully and sparingly or the system could run
 out of memory.  It is meant for processes that can't be
-swapped, like the ones implementing the swap device and for
-processes containing sensitive data.
+swapped, like the local fileserver implementing the swap
+device and for processes containing sensitive data.
+This property is inherited on
+.IR fork (2),
+cleared on
+.IR exec (2),
+and is not otherwise resettable.
 .TP 10n
 .B kill
 Kill the process the next time it crosses the user/kernel boundary.
 .TP 10n
-.B private
-Make it impossible to read the process's user memory.
-This property is inherited on fork, cleared on
-.IR exec (2),
-and is not otherwise resettable.
+.B "close\ \fIn
+Close file descriptor
+.I n
+in the process.
+.TP 10n
+.B closefiles
+Close all open file descriptors in the process.
 .TP 10n
 .B "pri\ \fIn
 Set the base priority for the process to the integer
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -492,7 +492,7 @@
 	if(p->pid != PID(c->qid))
 		error(Eprocdied);
 
-	if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0)
+	if(strcmp(up->user, p->user) != 0 && !iseve())
 		error(Eperm);
 
 	d = smalloc(sizeof(Dir)+n);
@@ -500,10 +500,9 @@
 	if(n == 0)
 		error(Eshortstat);
 	if(!emptystr(d->uid) && strcmp(d->uid, p->user) != 0){
-		if(strcmp(up->user, eve) != 0)
+		if(!iseve())
 			error(Eperm);
-		else
-			kstrdup(&p->user, d->uid);
+		kstrdup(&p->user, d->uid);
 	}
 	/* p->procmode determines default mode for files in /proc */
 	if(d->mode != ~0UL)
@@ -1528,32 +1527,6 @@
 procstopped(void *a)
 {
 	return ((Proc*)a)->state == Stopped;
-}
-
-ulong
-procpagecount(Proc *p)
-{
-	Segment *s;
-	ulong pages;
-	int i;
-
-	eqlock(&p->seglock);
-	if(waserror()){
-		qunlock(&p->seglock);
-		nexterror();
-	}
-	pages = 0;
-	for(i=0; i<NSEG; i++){
-		if((s = p->seg[i]) != nil){
-			eqlock(s);
-			pages += mcountseg(s);
-			qunlock(s);
-		}
-	}
-	qunlock(&p->seglock);
-	poperror();
-
-	return pages;
 }
 
 int
--- a/sys/src/9/port/error.h
+++ b/sys/src/9/port/error.h
@@ -37,7 +37,6 @@
 extern char Econinuse[];	/* connection in use */
 extern char Eintr[];		/* interrupted */
 extern char Enomem[];		/* kernel allocate failed */
-extern char Enoswap[];		/* swap space full */
 extern char Esoverlap[];	/* segments overlap */
 extern char Emouseset[];	/* mouse type already set */
 extern char Eshort[];		/* i/o count too small */
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -667,7 +667,7 @@
 	QLock	debug;		/* to access debugging elements of User */
 	Proc	*pdbg;		/* the debugging process */
 	ulong	procmode;	/* proc device default file mode */
-	ulong	privatemem;	/* proc does not let anyone read mem */
+	int	privatemem;	/* proc does not let anyone read mem */
 	int	hang;		/* hang at next exec for debug */
 	int	procctl;	/* Control for /proc debugging */
 	uintptr	pc;		/* DEBUG only */
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -225,9 +225,10 @@
 void		procctl(Proc*);
 void		procdump(void);
 int		procfdprint(Chan*, int, int, char*, int);
+void		procflushseg(Segment*);
 int		procindex(ulong);
 void		procinit0(void);
-void		procflushseg(Segment*);
+ulong		procpagecount(Proc*);
 void		procpriority(Proc*, int, int);
 Proc*		proctab(int);
 extern void	(*proctrace)(Proc*, int, vlong); 
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1491,6 +1491,32 @@
 	error(buf);
 }
 
+ulong
+procpagecount(Proc *p)
+{
+	Segment *s;
+	ulong pages;
+	int i;
+
+	eqlock(&p->seglock);
+	if(waserror()){
+		qunlock(&p->seglock);
+		nexterror();
+	}
+	pages = 0;
+	for(i=0; i<NSEG; i++){
+		if((s = p->seg[i]) != nil){
+			eqlock(s);
+			pages += mcountseg(s);
+			qunlock(s);
+		}
+	}
+	qunlock(&p->seglock);
+	poperror();
+
+	return pages;
+}
+
 void
 killbig(char *why)
 {
@@ -1503,25 +1529,20 @@
 	kp = nil;
 	ep = procalloc.arena+conf.nproc;
 	for(p = procalloc.arena; p < ep; p++) {
-		if(p->state == Dead || p->kp || !canqlock(&p->seglock))
+		if(p->state == Dead || p->kp)
 			continue;
-		l = 0;
-		for(i=1; i<NSEG; i++) {
-			s = p->seg[i];
-			if(s == nil || !canqlock(s))
-				continue;
-			l += mcountseg(s);
-			qunlock(s);
-		}
-		qunlock(&p->seglock);
-		if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) {
+		if((p->noswap || (p->procmode & 0222) == 0) && strcmp(eve, p->user) == 0)
+			continue;
+		l = procpagecount(p);
+		if(l > max){
 			kp = p;
 			max = l;
 		}
 	}
-	if(kp == nil || !canqlock(&kp->seglock))
+	if(kp == nil)
 		return;
 	print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
+	qlock(&kp->seglock);
 	for(p = procalloc.arena; p < ep; p++) {
 		if(p->state == Dead || p->kp)
 			continue;
@@ -1531,7 +1552,8 @@
 	kp->procctl = Proc_exitbig;
 	for(i = 0; i < NSEG; i++) {
 		s = kp->seg[i];
-		if(s != nil && canqlock(s)) {
+		if(s != nil) {
+			qlock(s);
 			mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
 			qunlock(s);
 		}
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -512,6 +512,7 @@
 	up->notify = 0;
 	up->notified = 0;
 	up->privatemem = 0;
+	up->noswap = 0;
 	procsetup(up);
 	qunlock(&up->debug);