summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/defs.h2
-rw-r--r--kernel/exec.c21
-rw-r--r--kernel/proc.c2
-rw-r--r--kernel/vm.c4
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;