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
This commit is contained in:
parent
2175c6b0b6
commit
cef1b57d4a
2
Makefile
2
Makefile
|
@ -90,7 +90,7 @@ tags: $(OBJS) _init
|
||||||
ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o
|
ULIB = $U/ulib.o $U/usys.o $U/printf.o $U/umalloc.o
|
||||||
|
|
||||||
_%: %.o $(ULIB)
|
_%: %.o $(ULIB)
|
||||||
$(LD) $(LDFLAGS) -N -e _main -Ttext 0 -o $@ $^
|
$(LD) $(LDFLAGS) -verbose -e _main -Ttext 0 -o $@ $^
|
||||||
$(OBJDUMP) -S $@ > $*.asm
|
$(OBJDUMP) -S $@ > $*.asm
|
||||||
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
|
$(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,17 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "elf.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
|
int
|
||||||
exec(char *path, char **argv)
|
exec(char *path, char **argv)
|
||||||
|
@ -32,6 +42,7 @@ exec(char *path, char **argv)
|
||||||
// Check ELF header
|
// Check ELF header
|
||||||
if(readi(ip, 0, (uint64)&elf, 0, sizeof(elf)) != sizeof(elf))
|
if(readi(ip, 0, (uint64)&elf, 0, sizeof(elf)) != sizeof(elf))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if(elf.magic != ELF_MAGIC)
|
if(elf.magic != ELF_MAGIC)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
@ -48,13 +59,15 @@ exec(char *path, char **argv)
|
||||||
goto bad;
|
goto bad;
|
||||||
if(ph.vaddr + ph.memsz < ph.vaddr)
|
if(ph.vaddr + ph.memsz < ph.vaddr)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
if(ph.align != PGSIZE)
|
||||||
|
goto bad;
|
||||||
|
uint64 e = PGROUNDUP(ph.vaddr + ph.memsz);
|
||||||
uint64 sz1;
|
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;
|
goto bad;
|
||||||
sz = sz1;
|
sz = sz1;
|
||||||
if((ph.vaddr % PGSIZE) != 0)
|
uint64 s = PGROUNDDOWN(ph.vaddr);
|
||||||
goto bad;
|
if(loadseg(pagetable, s, ph.vaddr - s, ip, ph.off, ph.filesz) < 0)
|
||||||
if(loadseg(pagetable, ph.vaddr, ip, ph.off, ph.filesz) < 0)
|
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
iunlockput(ip);
|
iunlockput(ip);
|
||||||
|
@ -134,7 +147,7 @@ exec(char *path, char **argv)
|
||||||
// and the pages from va to va+sz must already be mapped.
|
// and the pages from va to va+sz must already be mapped.
|
||||||
// Returns 0 on success, -1 on failure.
|
// Returns 0 on success, -1 on failure.
|
||||||
static int
|
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;
|
uint i, n;
|
||||||
uint64 pa;
|
uint64 pa;
|
||||||
|
@ -147,7 +160,7 @@ loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz
|
||||||
n = sz - i;
|
n = sz - i;
|
||||||
else
|
else
|
||||||
n = PGSIZE;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2508,17 +2508,40 @@ stacktest(char *s)
|
||||||
exit(xstatus);
|
exit(xstatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check that writes to text segment fault
|
||||||
|
void
|
||||||
|
texttest(char *s)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
int xstatus;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if(pid == 0) {
|
||||||
|
volatile int *addr = (int *) 0;
|
||||||
|
*addr = 10;
|
||||||
|
exit(1);
|
||||||
|
} else if(pid < 0){
|
||||||
|
printf("%s: fork failed\n", s);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
wait(&xstatus);
|
||||||
|
if(xstatus == -1) // kernel killed child?
|
||||||
|
exit(0);
|
||||||
|
else
|
||||||
|
exit(xstatus);
|
||||||
|
}
|
||||||
|
|
||||||
// regression test. copyin(), copyout(), and copyinstr() used to cast
|
// regression test. copyin(), copyout(), and copyinstr() used to cast
|
||||||
// the virtual page address to uint, which (with certain wild system
|
// the virtual page address to uint, which (with certain wild system
|
||||||
// call arguments) resulted in a kernel page faults.
|
// call arguments) resulted in a kernel page faults.
|
||||||
|
void *big = (void*) 0xeaeb0b5b00002f5e;
|
||||||
void
|
void
|
||||||
pgbug(char *s)
|
pgbug(char *s)
|
||||||
{
|
{
|
||||||
char *argv[1];
|
char *argv[1];
|
||||||
argv[0] = 0;
|
argv[0] = 0;
|
||||||
exec((char*)0xeaeb0b5b00002f5e, argv);
|
exec(big, argv);
|
||||||
|
pipe(big);
|
||||||
pipe((int*)0xeaeb0b5b00002f5e);
|
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -2607,6 +2630,7 @@ sbrklast(char *s)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// does sbrk handle signed int32 wrap-around with
|
// does sbrk handle signed int32 wrap-around with
|
||||||
// negative arguments?
|
// negative arguments?
|
||||||
void
|
void
|
||||||
|
@ -2617,6 +2641,7 @@ sbrk8000(char *s)
|
||||||
*(top-1) = *(top-1) + 1;
|
*(top-1) = *(top-1) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// regression test. does write() with an invalid buffer pointer cause
|
// regression test. does write() with an invalid buffer pointer cause
|
||||||
// a block to be allocated for a file that is then not freed when the
|
// a block to be allocated for a file that is then not freed when the
|
||||||
// file is deleted? if the kernel has this bug, it will panic: balloc:
|
// file is deleted? if the kernel has this bug, it will panic: balloc:
|
||||||
|
|
Loading…
Reference in a new issue