summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-04 06:51:01 -0400
committerRobert Morris <[email protected]>2019-06-04 06:51:01 -0400
commitb78894f34ebbceb23bcf36ff820fefb942b54ccf (patch)
treeede192dce7cd432e8abbdc66faacb7bf8e1385f8 /exec.c
parent0f684b9150b56c3fce1db099e93327ebaaca363a (diff)
downloadxv6-labs-b78894f34ebbceb23bcf36ff820fefb942b54ccf.tar.gz
xv6-labs-b78894f34ebbceb23bcf36ff820fefb942b54ccf.tar.bz2
xv6-labs-b78894f34ebbceb23bcf36ff820fefb942b54ccf.zip
check that arguments aren't more than a page in exec()
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/exec.c b/exec.c
index c854aae..63b5b62 100644
--- a/exec.c
+++ b/exec.c
@@ -13,7 +13,7 @@ exec(char *path, char **argv)
{
char *s, *last;
int i, off;
- uint64 argc, sz, sp, ustack[MAXARG+1];
+ uint64 argc, sz, sp, ustack[MAXARG+1], stackbase;
struct elfhdr elf;
struct inode *ip;
struct proghdr ph;
@@ -66,6 +66,7 @@ exec(char *path, char **argv)
if((sz = uvmalloc(pagetable, sz, sz + 2*PGSIZE)) == 0)
goto bad;
sp = sz;
+ stackbase = sp - PGSIZE;
// Push argument strings, prepare rest of stack in ustack.
for(argc = 0; argv[argc]; argc++) {
@@ -73,6 +74,8 @@ exec(char *path, char **argv)
goto bad;
sp -= strlen(argv[argc]) + 1;
sp -= sp % 16; // riscv sp must be 16-byte aligned
+ if(sp < stackbase)
+ goto bad;
if(copyout(pagetable, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
goto bad;
ustack[argc] = sp;
@@ -82,6 +85,8 @@ exec(char *path, char **argv)
// push the array of argv[] pointers.
sp -= (argc+1) * sizeof(uint64);
sp -= sp % 16;
+ if(sp < stackbase)
+ goto bad;
if(copyout(pagetable, sp, (char *)ustack, (argc+1)*sizeof(uint64)) < 0)
goto bad;