devproc: fix fishy locking in proctext(), check proc validity, static functions
the locking in proctext() is wrong. we have to acquire Proc.seglock when reading segments from Proc.seg[] as segments do not have a private freelist and can therefore be reused for other data structures. once we have Proc.seglock acquired, check that the process pid is still valid so we wont accidentally read some other processes segments. (for both proctext() and procctlmemio()). this also should give better error message to distinguish the case when the process did segdetach() the segment in question before we could acquire Proc.seglock. declare private functions as static.
This commit is contained in:
parent
c45458b929
commit
12fa017f3f
1 changed files with 38 additions and 44 deletions
|
@ -154,11 +154,10 @@ static char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Fixed"
|
||||||
#define PID(q) ((q).vers)
|
#define PID(q) ((q).vers)
|
||||||
#define NOTEID(q) ((q).vers)
|
#define NOTEID(q) ((q).vers)
|
||||||
|
|
||||||
void procctlreq(Proc*, char*, int);
|
static void procctlreq(Proc*, char*, int);
|
||||||
long procctlmemio(Chan*, Proc*, uintptr, void*, long, int);
|
static long procctlmemio(Chan*, Proc*, uintptr, void*, long, int);
|
||||||
Chan* proctext(Chan*, Proc*);
|
static Chan* proctext(Chan*, Proc*);
|
||||||
int procstopped(void*);
|
static int procstopped(void*);
|
||||||
ulong procpagecount(Proc *);
|
|
||||||
|
|
||||||
static Traceevent *tevents;
|
static Traceevent *tevents;
|
||||||
static Lock tlock;
|
static Lock tlock;
|
||||||
|
@ -382,10 +381,10 @@ procopen(Chan *c, int omode0)
|
||||||
case Qtext:
|
case Qtext:
|
||||||
if(omode != OREAD)
|
if(omode != OREAD)
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
tc = proctext(c, p);
|
|
||||||
tc->offset = 0;
|
|
||||||
qunlock(&p->debug);
|
qunlock(&p->debug);
|
||||||
poperror();
|
poperror();
|
||||||
|
tc = proctext(c, p);
|
||||||
|
tc->offset = 0;
|
||||||
cclose(c);
|
cclose(c);
|
||||||
return tc;
|
return tc;
|
||||||
|
|
||||||
|
@ -1297,50 +1296,39 @@ Dev procdevtab = {
|
||||||
procwstat,
|
procwstat,
|
||||||
};
|
};
|
||||||
|
|
||||||
Chan*
|
static Chan*
|
||||||
proctext(Chan *c, Proc *p)
|
proctext(Chan *c, Proc *p)
|
||||||
{
|
{
|
||||||
Chan *tc;
|
Chan *tc;
|
||||||
Image *i;
|
Image *i;
|
||||||
Segment *s;
|
Segment *s;
|
||||||
|
|
||||||
s = p->seg[TSEG];
|
eqlock(&p->seglock);
|
||||||
if(s == nil)
|
if(waserror()){
|
||||||
error(Enonexist);
|
qunlock(&p->seglock);
|
||||||
if(p->state==Dead)
|
|
||||||
error(Eprocdied);
|
|
||||||
|
|
||||||
i = s->image;
|
|
||||||
if(i == nil)
|
|
||||||
error(Eprocdied);
|
|
||||||
|
|
||||||
lock(i);
|
|
||||||
if(waserror()) {
|
|
||||||
unlock(i);
|
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
if(p->state == Dead || p->pid != PID(c->qid))
|
||||||
|
error(Eprocdied);
|
||||||
|
if((s = p->seg[TSEG]) == nil)
|
||||||
|
error(Enonexist);
|
||||||
|
if((i = s->image) == nil)
|
||||||
|
error(Enonexist);
|
||||||
|
lock(i);
|
||||||
tc = i->c;
|
tc = i->c;
|
||||||
if(tc == nil)
|
if(i->notext || tc == nil || (tc->flag&COPEN) == 0 || tc->mode != OREAD){
|
||||||
error(Eprocdied);
|
unlock(i);
|
||||||
|
error(Enonexist);
|
||||||
if(incref(tc) == 1 || (tc->flag&COPEN) == 0 || tc->mode != OREAD) {
|
|
||||||
cclose(tc);
|
|
||||||
error(Eprocdied);
|
|
||||||
}
|
}
|
||||||
|
incref(tc);
|
||||||
if(p->pid != PID(c->qid)) {
|
|
||||||
cclose(tc);
|
|
||||||
error(Eprocdied);
|
|
||||||
}
|
|
||||||
|
|
||||||
unlock(i);
|
unlock(i);
|
||||||
|
qunlock(&p->seglock);
|
||||||
poperror();
|
poperror();
|
||||||
|
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
procstopwait(Proc *p, int ctl)
|
procstopwait(Proc *p, int ctl)
|
||||||
{
|
{
|
||||||
char *state;
|
char *state;
|
||||||
|
@ -1375,7 +1363,7 @@ procstopwait(Proc *p, int ctl)
|
||||||
error(Eprocdied);
|
error(Eprocdied);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
procctlclosefiles(Proc *p, int all, int fd)
|
procctlclosefiles(Proc *p, int all, int fd)
|
||||||
{
|
{
|
||||||
Fgrp *f;
|
Fgrp *f;
|
||||||
|
@ -1440,7 +1428,7 @@ parsetime(vlong *rt, char *s)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
procctlreq(Proc *p, char *va, int n)
|
procctlreq(Proc *p, char *va, int n)
|
||||||
{
|
{
|
||||||
Segment *s;
|
Segment *s;
|
||||||
|
@ -1636,13 +1624,13 @@ procctlreq(Proc *p, char *va, int n)
|
||||||
free(cb);
|
free(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
procstopped(void *a)
|
procstopped(void *a)
|
||||||
{
|
{
|
||||||
return ((Proc*)a)->state == Stopped;
|
return ((Proc*)a)->state == Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
long
|
static long
|
||||||
procctlmemio(Chan *c, Proc *p, uintptr offset, void *a, long n, int read)
|
procctlmemio(Chan *c, Proc *p, uintptr offset, void *a, long n, int read)
|
||||||
{
|
{
|
||||||
Segio *sio;
|
Segio *sio;
|
||||||
|
@ -1657,17 +1645,16 @@ procctlmemio(Chan *c, Proc *p, uintptr offset, void *a, long n, int read)
|
||||||
qunlock(&p->seglock);
|
qunlock(&p->seglock);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
sio = c->aux;
|
if(p->state == Dead || p->pid != PID(c->qid))
|
||||||
if(sio == nil){
|
error(Eprocdied);
|
||||||
sio = smalloc(sizeof(Segio));
|
|
||||||
c->aux = sio;
|
|
||||||
}
|
|
||||||
for(i = 0; i < NSEG; i++) {
|
for(i = 0; i < NSEG; i++) {
|
||||||
if(p->seg[i] == s)
|
if(p->seg[i] == s)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i == NSEG)
|
if(i == NSEG)
|
||||||
error(Egreg); /* segment gone */
|
error(Egreg); /* segment gone */
|
||||||
|
|
||||||
eqlock(s);
|
eqlock(s);
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
qunlock(s);
|
qunlock(s);
|
||||||
|
@ -1681,6 +1668,13 @@ procctlmemio(Chan *c, Proc *p, uintptr offset, void *a, long n, int read)
|
||||||
incref(s); /* for us while we copy */
|
incref(s); /* for us while we copy */
|
||||||
qunlock(s);
|
qunlock(s);
|
||||||
poperror();
|
poperror();
|
||||||
|
|
||||||
|
sio = c->aux;
|
||||||
|
if(sio == nil){
|
||||||
|
sio = smalloc(sizeof(Segio));
|
||||||
|
c->aux = sio;
|
||||||
|
}
|
||||||
|
|
||||||
qunlock(&p->seglock);
|
qunlock(&p->seglock);
|
||||||
poperror();
|
poperror();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue