kernel: make noswap flag exclude processes from killbig() if not eve, reset noswap flag on exec
This commit is contained in:
parent
0bc51a90b0
commit
3b661a96ef
7 changed files with 68 additions and 65 deletions
|
@ -301,6 +301,32 @@ This bit is inherited across
|
||||||
and
|
and
|
||||||
.IR exec (2).
|
.IR exec (2).
|
||||||
.TP 10n
|
.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 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 "close\ \fIn
|
.B "close\ \fIn
|
||||||
Close file descriptor
|
Close file descriptor
|
||||||
.I n
|
.I n
|
||||||
|
@ -309,25 +335,6 @@ in the process.
|
||||||
.B closefiles
|
.B closefiles
|
||||||
Close all open file descriptors in the process.
|
Close all open file descriptors in the process.
|
||||||
.TP 10n
|
.TP 10n
|
||||||
.B nohang
|
|
||||||
Clear the hang bit.
|
|
||||||
.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.
|
|
||||||
.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.
|
|
||||||
.TP 10n
|
|
||||||
.B "pri\ \fIn
|
.B "pri\ \fIn
|
||||||
Set the base priority for the process to the integer
|
Set the base priority for the process to the integer
|
||||||
.IR n .
|
.IR n .
|
||||||
|
|
|
@ -492,7 +492,7 @@ procwstat(Chan *c, uchar *db, int n)
|
||||||
if(p->pid != PID(c->qid))
|
if(p->pid != PID(c->qid))
|
||||||
error(Eprocdied);
|
error(Eprocdied);
|
||||||
|
|
||||||
if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0)
|
if(strcmp(up->user, p->user) != 0 && !iseve())
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
|
|
||||||
d = smalloc(sizeof(Dir)+n);
|
d = smalloc(sizeof(Dir)+n);
|
||||||
|
@ -500,10 +500,9 @@ procwstat(Chan *c, uchar *db, int n)
|
||||||
if(n == 0)
|
if(n == 0)
|
||||||
error(Eshortstat);
|
error(Eshortstat);
|
||||||
if(!emptystr(d->uid) && strcmp(d->uid, p->user) != 0){
|
if(!emptystr(d->uid) && strcmp(d->uid, p->user) != 0){
|
||||||
if(strcmp(up->user, eve) != 0)
|
if(!iseve())
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
else
|
kstrdup(&p->user, d->uid);
|
||||||
kstrdup(&p->user, d->uid);
|
|
||||||
}
|
}
|
||||||
/* p->procmode determines default mode for files in /proc */
|
/* p->procmode determines default mode for files in /proc */
|
||||||
if(d->mode != ~0UL)
|
if(d->mode != ~0UL)
|
||||||
|
@ -1530,32 +1529,6 @@ procstopped(void *a)
|
||||||
return ((Proc*)a)->state == Stopped;
|
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
|
int
|
||||||
procctlmemio(Proc *p, uintptr offset, int n, void *va, int read)
|
procctlmemio(Proc *p, uintptr offset, int n, void *va, int read)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,6 @@ extern char Econrefused[]; /* connection refused */
|
||||||
extern char Econinuse[]; /* connection in use */
|
extern char Econinuse[]; /* connection in use */
|
||||||
extern char Eintr[]; /* interrupted */
|
extern char Eintr[]; /* interrupted */
|
||||||
extern char Enomem[]; /* kernel allocate failed */
|
extern char Enomem[]; /* kernel allocate failed */
|
||||||
extern char Enoswap[]; /* swap space full */
|
|
||||||
extern char Esoverlap[]; /* segments overlap */
|
extern char Esoverlap[]; /* segments overlap */
|
||||||
extern char Emouseset[]; /* mouse type already set */
|
extern char Emouseset[]; /* mouse type already set */
|
||||||
extern char Eshort[]; /* i/o count too small */
|
extern char Eshort[]; /* i/o count too small */
|
||||||
|
|
|
@ -667,7 +667,7 @@ struct Proc
|
||||||
QLock debug; /* to access debugging elements of User */
|
QLock debug; /* to access debugging elements of User */
|
||||||
Proc *pdbg; /* the debugging process */
|
Proc *pdbg; /* the debugging process */
|
||||||
ulong procmode; /* proc device default file mode */
|
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 hang; /* hang at next exec for debug */
|
||||||
int procctl; /* Control for /proc debugging */
|
int procctl; /* Control for /proc debugging */
|
||||||
uintptr pc; /* DEBUG only */
|
uintptr pc; /* DEBUG only */
|
||||||
|
|
|
@ -225,9 +225,10 @@ ulong procalarm(ulong);
|
||||||
void procctl(Proc*);
|
void procctl(Proc*);
|
||||||
void procdump(void);
|
void procdump(void);
|
||||||
int procfdprint(Chan*, int, int, char*, int);
|
int procfdprint(Chan*, int, int, char*, int);
|
||||||
|
void procflushseg(Segment*);
|
||||||
int procindex(ulong);
|
int procindex(ulong);
|
||||||
void procinit0(void);
|
void procinit0(void);
|
||||||
void procflushseg(Segment*);
|
ulong procpagecount(Proc*);
|
||||||
void procpriority(Proc*, int, int);
|
void procpriority(Proc*, int, int);
|
||||||
Proc* proctab(int);
|
Proc* proctab(int);
|
||||||
extern void (*proctrace)(Proc*, int, vlong);
|
extern void (*proctrace)(Proc*, int, vlong);
|
||||||
|
|
|
@ -1491,6 +1491,32 @@ exhausted(char *resource)
|
||||||
error(buf);
|
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
|
void
|
||||||
killbig(char *why)
|
killbig(char *why)
|
||||||
{
|
{
|
||||||
|
@ -1503,25 +1529,20 @@ killbig(char *why)
|
||||||
kp = nil;
|
kp = nil;
|
||||||
ep = procalloc.arena+conf.nproc;
|
ep = procalloc.arena+conf.nproc;
|
||||||
for(p = procalloc.arena; p < ep; p++) {
|
for(p = procalloc.arena; p < ep; p++) {
|
||||||
if(p->state == Dead || p->kp || !canqlock(&p->seglock))
|
if(p->state == Dead || p->kp)
|
||||||
continue;
|
continue;
|
||||||
l = 0;
|
if((p->noswap || (p->procmode & 0222) == 0) && strcmp(eve, p->user) == 0)
|
||||||
for(i=1; i<NSEG; i++) {
|
continue;
|
||||||
s = p->seg[i];
|
l = procpagecount(p);
|
||||||
if(s == nil || !canqlock(s))
|
if(l > max){
|
||||||
continue;
|
|
||||||
l += mcountseg(s);
|
|
||||||
qunlock(s);
|
|
||||||
}
|
|
||||||
qunlock(&p->seglock);
|
|
||||||
if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) {
|
|
||||||
kp = p;
|
kp = p;
|
||||||
max = l;
|
max = l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(kp == nil || !canqlock(&kp->seglock))
|
if(kp == nil)
|
||||||
return;
|
return;
|
||||||
print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
|
print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
|
||||||
|
qlock(&kp->seglock);
|
||||||
for(p = procalloc.arena; p < ep; p++) {
|
for(p = procalloc.arena; p < ep; p++) {
|
||||||
if(p->state == Dead || p->kp)
|
if(p->state == Dead || p->kp)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1531,7 +1552,8 @@ killbig(char *why)
|
||||||
kp->procctl = Proc_exitbig;
|
kp->procctl = Proc_exitbig;
|
||||||
for(i = 0; i < NSEG; i++) {
|
for(i = 0; i < NSEG; i++) {
|
||||||
s = kp->seg[i];
|
s = kp->seg[i];
|
||||||
if(s != nil && canqlock(s)) {
|
if(s != nil) {
|
||||||
|
qlock(s);
|
||||||
mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
|
mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
|
||||||
qunlock(s);
|
qunlock(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -512,6 +512,7 @@ sysexec(va_list list)
|
||||||
up->notify = 0;
|
up->notify = 0;
|
||||||
up->notified = 0;
|
up->notified = 0;
|
||||||
up->privatemem = 0;
|
up->privatemem = 0;
|
||||||
|
up->noswap = 0;
|
||||||
procsetup(up);
|
procsetup(up);
|
||||||
qunlock(&up->debug);
|
qunlock(&up->debug);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue