kernel: reset up->setargs on sysexec(), fix race with devproc
up->setargs wasnt reset in sysexec(). also, up->args should only be exchanged/freed under up->debug qlock. otherwise double free could happen.
This commit is contained in:
parent
8a7a6f778d
commit
34cd9dc4c4
|
@ -737,7 +737,7 @@ struct Proc
|
||||||
ulong qpc; /* pc calling last blocking qlock */
|
ulong qpc; /* pc calling last blocking qlock */
|
||||||
QLock *eql; /* interruptable eqlock */
|
QLock *eql; /* interruptable eqlock */
|
||||||
|
|
||||||
int setargs;
|
int setargs; /* process changed its args */
|
||||||
|
|
||||||
void *ureg; /* User registers for notes */
|
void *ureg; /* User registers for notes */
|
||||||
void *dbgreg; /* User registers for devproc */
|
void *dbgreg; /* User registers for devproc */
|
||||||
|
|
|
@ -252,19 +252,20 @@ sysexec(ulong *arg)
|
||||||
ulong magic, text, entry, data, bss;
|
ulong magic, text, entry, data, bss;
|
||||||
Tos *tos;
|
Tos *tos;
|
||||||
|
|
||||||
indir = 0;
|
a = nil;
|
||||||
elem = nil;
|
elem = nil;
|
||||||
validaddr(arg[0], 1, 0);
|
validaddr(arg[0], 1, 0);
|
||||||
file0 = validnamedup((char*)arg[0], 1);
|
file0 = validnamedup((char*)arg[0], 1);
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
free(file0);
|
free(file0);
|
||||||
if(elem != up->text)
|
|
||||||
free(elem);
|
free(elem);
|
||||||
|
free(a);
|
||||||
/* Disaster after commit */
|
/* Disaster after commit */
|
||||||
if(!up->seg[SSEG])
|
if(!up->seg[SSEG])
|
||||||
pexit(up->errstr, 1);
|
pexit(up->errstr, 1);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
|
indir = 0;
|
||||||
file = file0;
|
file = file0;
|
||||||
for(;;){
|
for(;;){
|
||||||
tc = namec(file, Aopen, OEXEC, 0);
|
tc = namec(file, Aopen, OEXEC, 0);
|
||||||
|
@ -405,28 +406,21 @@ sysexec(ulong *arg)
|
||||||
charp += n;
|
charp += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(up->text);
|
|
||||||
up->text = elem;
|
|
||||||
|
|
||||||
/* copy args; easiest from new process's stack */
|
/* copy args; easiest from new process's stack */
|
||||||
n = charp - args;
|
n = charp - args;
|
||||||
if(n > 128) /* don't waste too much space on huge arg lists */
|
if(n > 128) /* don't waste too much space on huge arg lists */
|
||||||
n = 128;
|
n = 128;
|
||||||
a = up->args;
|
a = smalloc(n);
|
||||||
up->args = nil;
|
memmove(a, args, n);
|
||||||
free(a);
|
if(n>0 && a[n-1]!='\0'){
|
||||||
up->args = smalloc(n);
|
|
||||||
memmove(up->args, args, n);
|
|
||||||
if(n>0 && up->args[n-1]!='\0'){
|
|
||||||
/* make sure last arg is NUL-terminated */
|
/* make sure last arg is NUL-terminated */
|
||||||
/* put NUL at UTF-8 character boundary */
|
/* put NUL at UTF-8 character boundary */
|
||||||
for(i=n-1; i>0; --i)
|
for(i=n-1; i>0; --i)
|
||||||
if(fullrune(up->args+i, n-i))
|
if(fullrune(a+i, n-i))
|
||||||
break;
|
break;
|
||||||
up->args[i] = 0;
|
a[i] = 0;
|
||||||
n = i+1;
|
n = i+1;
|
||||||
}
|
}
|
||||||
up->nargs = n;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Committed.
|
* Committed.
|
||||||
|
@ -501,6 +495,13 @@ sysexec(ulong *arg)
|
||||||
free(file0);
|
free(file0);
|
||||||
|
|
||||||
qlock(&up->debug);
|
qlock(&up->debug);
|
||||||
|
free(up->text);
|
||||||
|
up->text = elem;
|
||||||
|
free(up->args);
|
||||||
|
up->args = a;
|
||||||
|
up->nargs = n;
|
||||||
|
up->setargs = 0;
|
||||||
|
|
||||||
up->nnote = 0;
|
up->nnote = 0;
|
||||||
up->notify = 0;
|
up->notify = 0;
|
||||||
up->notified = 0;
|
up->notified = 0;
|
||||||
|
|
Loading…
Reference in a new issue