diff options
| author | Frans Kaashoek <kaashoek@mit.edu> | 2022-08-15 19:02:19 -0400 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@mit.edu> | 2022-08-15 19:02:19 -0400 | 
| commit | cef1b57d4a97f15e9858804e368f7928b579b88e (patch) | |
| tree | 8f59e7986c6b69e08f2a8d4a3f5449a83e4cf7ea /kernel | |
| parent | 2175c6b0b667b13e09c710c36e4a3ae8fc7c97dc (diff) | |
| download | xv6-labs-cef1b57d4a97f15e9858804e368f7928b579b88e.tar.gz xv6-labs-cef1b57d4a97f15e9858804e368f7928b579b88e.tar.bz2 xv6-labs-cef1b57d4a97f15e9858804e368f7928b579b88e.zip | |
Compile user binary to map text without W and data without X
Use the flags in elf header to set vm permissions
Modify pgbug() so that usertests text segment is without W
Add test to check app cannot write text segment
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/exec.c | 27 | 
1 files changed, 20 insertions, 7 deletions
| diff --git a/kernel/exec.c b/kernel/exec.c index 3c468e1..aee9345 100644 --- a/kernel/exec.c +++ b/kernel/exec.c @@ -7,7 +7,17 @@  #include "defs.h"  #include "elf.h" -static int loadseg(pde_t *pgdir, uint64 addr, struct inode *ip, uint offset, uint sz); +static int loadseg(pde_t *, uint64, uint, struct inode *, uint, uint); + +int flags2perm(int flags) +{ +    int perm = 0; +    if(flags & 0x1) +      perm = PTE_X; +    if(flags & 0x2) +      perm |= PTE_W; +    return perm; +}  int  exec(char *path, char **argv) @@ -32,6 +42,7 @@ exec(char *path, char **argv)    // Check ELF header    if(readi(ip, 0, (uint64)&elf, 0, sizeof(elf)) != sizeof(elf))      goto bad; +    if(elf.magic != ELF_MAGIC)      goto bad; @@ -48,13 +59,15 @@ exec(char *path, char **argv)        goto bad;      if(ph.vaddr + ph.memsz < ph.vaddr)        goto bad; +    if(ph.align != PGSIZE) +      goto bad; +    uint64 e = PGROUNDUP(ph.vaddr + ph.memsz);      uint64 sz1; -    if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz, PTE_X|PTE_W)) == 0) +    if((sz1 = uvmalloc(pagetable, sz, e, flags2perm(ph.flags))) == 0)        goto bad;      sz = sz1; -    if((ph.vaddr % PGSIZE) != 0) -      goto bad; -    if(loadseg(pagetable, ph.vaddr, ip, ph.off, ph.filesz) < 0) +    uint64 s = PGROUNDDOWN(ph.vaddr); +    if(loadseg(pagetable, s, ph.vaddr - s, ip, ph.off, ph.filesz) < 0)        goto bad;    }    iunlockput(ip); @@ -134,7 +147,7 @@ exec(char *path, char **argv)  // and the pages from va to va+sz must already be mapped.  // Returns 0 on success, -1 on failure.  static int -loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz) +loadseg(pagetable_t pagetable, uint64 va, uint poff, struct inode *ip, uint offset, uint sz)  {    uint i, n;    uint64 pa; @@ -147,7 +160,7 @@ loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz        n = sz - i;      else        n = PGSIZE; -    if(readi(ip, 0, (uint64)pa, offset+i, n) != n) +    if(readi(ip, 0, (uint64)pa+poff, offset+i, n) != n)        return -1;    } | 
