don't leak memory if exec() arguments are invalid.
This commit is contained in:
parent
6b79ee69b7
commit
d940fd122d
|
@ -421,10 +421,10 @@ sys_exec(void)
|
||||||
memset(argv, 0, sizeof(argv));
|
memset(argv, 0, sizeof(argv));
|
||||||
for(i=0;; i++){
|
for(i=0;; i++){
|
||||||
if(i >= NELEM(argv)){
|
if(i >= NELEM(argv)){
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
if(fetchaddr(uargv+sizeof(uint64)*i, (uint64*)&uarg) < 0){
|
if(fetchaddr(uargv+sizeof(uint64)*i, (uint64*)&uarg) < 0){
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
if(uarg == 0){
|
if(uarg == 0){
|
||||||
argv[i] = 0;
|
argv[i] = 0;
|
||||||
|
@ -434,7 +434,7 @@ sys_exec(void)
|
||||||
if(argv[i] == 0)
|
if(argv[i] == 0)
|
||||||
panic("sys_exec kalloc");
|
panic("sys_exec kalloc");
|
||||||
if(fetchstr(uarg, argv[i], PGSIZE) < 0){
|
if(fetchstr(uarg, argv[i], PGSIZE) < 0){
|
||||||
return -1;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,6 +444,11 @@ sys_exec(void)
|
||||||
kfree(argv[i]);
|
kfree(argv[i]);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
for(i = 0; i < NELEM(argv) && argv[i] != 0; i++)
|
||||||
|
kfree(argv[i]);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64
|
uint64
|
||||||
|
|
|
@ -2016,6 +2016,7 @@ sbrkbugs(char *s)
|
||||||
// has this bug, it will panic: balloc: out of blocks.
|
// has this bug, it will panic: balloc: out of blocks.
|
||||||
// assumed_free may need to be raised to be
|
// assumed_free may need to be raised to be
|
||||||
// more than the number of free blocks.
|
// more than the number of free blocks.
|
||||||
|
// this test takes a long time.
|
||||||
void
|
void
|
||||||
badwrite(char *s)
|
badwrite(char *s)
|
||||||
{
|
{
|
||||||
|
@ -2048,6 +2049,22 @@ badwrite(char *s)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test whether exec() leaks memory if one of the
|
||||||
|
// arguments is invalid. the test passes if
|
||||||
|
// the kernel doesn't panic.
|
||||||
|
void
|
||||||
|
badarg(char *s)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 50000; i++){
|
||||||
|
char *argv[2];
|
||||||
|
argv[0] = (char*)0xffffffff;
|
||||||
|
argv[1] = 0;
|
||||||
|
exec("echo", argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
// run each test in its own process. run returns 1 if child's exit()
|
// run each test in its own process. run returns 1 if child's exit()
|
||||||
// indicates success.
|
// indicates success.
|
||||||
int
|
int
|
||||||
|
@ -2087,7 +2104,8 @@ main(int argc, char *argv[])
|
||||||
} tests[] = {
|
} tests[] = {
|
||||||
{pgbug, "pgbug" },
|
{pgbug, "pgbug" },
|
||||||
{sbrkbugs, "sbrkbugs" },
|
{sbrkbugs, "sbrkbugs" },
|
||||||
{badwrite, "badwrite" },
|
// {badwrite, "badwrite" },
|
||||||
|
{badarg, "badarg" },
|
||||||
{reparent, "reparent" },
|
{reparent, "reparent" },
|
||||||
{twochildren, "twochildren"},
|
{twochildren, "twochildren"},
|
||||||
{forkfork, "forkfork"},
|
{forkfork, "forkfork"},
|
||||||
|
|
Loading…
Reference in a new issue