diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/defs.h | 2 | ||||
| -rw-r--r-- | kernel/exec.c | 21 | ||||
| -rw-r--r-- | kernel/proc.c | 2 | ||||
| -rw-r--r-- | kernel/vm.c | 4 | 
4 files changed, 20 insertions, 9 deletions
| diff --git a/kernel/defs.h b/kernel/defs.h index 7457b66..95fb94b 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -162,7 +162,7 @@ void            kvmmap(pagetable_t, uint64, uint64, uint64, int);  int             mappages(pagetable_t, uint64, uint64, uint64, int);  pagetable_t     uvmcreate(void);  void            uvmfirst(pagetable_t, uchar *, uint); -uint64          uvmalloc(pagetable_t, uint64, uint64); +uint64          uvmalloc(pagetable_t, uint64, uint64, int);  uint64          uvmdealloc(pagetable_t, uint64, uint64);  int             uvmcopy(pagetable_t, pagetable_t, uint64);  void            uvmfree(pagetable_t, uint64); diff --git a/kernel/exec.c b/kernel/exec.c index 09b4bdc..e18bbb6 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, 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,12 +59,12 @@ exec(char *path, char **argv)        goto bad;      if(ph.vaddr + ph.memsz < ph.vaddr)        goto bad; +    if(ph.vaddr % PGSIZE != 0) +      goto bad;      uint64 sz1; -    if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz)) == 0) +    if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz, 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)        goto bad;    } @@ -69,7 +80,7 @@ exec(char *path, char **argv)    // Use the second as the user stack.    sz = PGROUNDUP(sz);    uint64 sz1; -  if((sz1 = uvmalloc(pagetable, sz, sz + 2*PGSIZE)) == 0) +  if((sz1 = uvmalloc(pagetable, sz, sz + 2*PGSIZE, PTE_W)) == 0)      goto bad;    sz = sz1;    uvmclear(pagetable, sz-2*PGSIZE); diff --git a/kernel/proc.c b/kernel/proc.c index 8d0ca8c..959b778 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -264,7 +264,7 @@ growproc(int n)    sz = p->sz;    if(n > 0){ -    if((sz = uvmalloc(p->pagetable, sz, sz + n)) == 0) { +    if((sz = uvmalloc(p->pagetable, sz, sz + n, PTE_W)) == 0) {        return -1;      }    } else if(n < 0){ diff --git a/kernel/vm.c b/kernel/vm.c index 3c6f295..284b72d 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -218,7 +218,7 @@ uvmfirst(pagetable_t pagetable, uchar *src, uint sz)  // Allocate PTEs and physical memory to grow process from oldsz to  // newsz, which need not be page aligned.  Returns new size or 0 on error.  uint64 -uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz) +uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)  {    char *mem;    uint64 a; @@ -234,7 +234,7 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)        return 0;      }      memset(mem, 0, PGSIZE); -    if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0){ +    if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){        kfree(mem);        uvmdealloc(pagetable, a, oldsz);        return 0; | 
