summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorrsc <rsc>2007-09-27 19:39:10 +0000
committerrsc <rsc>2007-09-27 19:39:10 +0000
commit39c3fb1b157927058f24b72d43be6f15c1d422b7 (patch)
treef02c00516eebdedd22e0ba59a2011c29398a5fc9 /proc.c
parent8c8b748a2f0f10188c1a58c529239fff3a3b1b01 (diff)
downloadxv6-labs-39c3fb1b157927058f24b72d43be6f15c1d422b7.tar.gz
xv6-labs-39c3fb1b157927058f24b72d43be6f15c1d422b7.tar.bz2
xv6-labs-39c3fb1b157927058f24b72d43be6f15c1d422b7.zip
overkill: use segments to catch stack overflow (delete before next year)
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/proc.c b/proc.c
index d060445..b80a08e 100644
--- a/proc.c
+++ b/proc.c
@@ -73,7 +73,7 @@ setupsegs(struct proc *p)
splhi();
c = &cpus[cpu()];
- c->ts.ss0 = SEG_KDATA << 3;
+ c->ts.ss0 = SEG_PROCSTACK << 3;
if(p)
c->ts.esp0 = (uint)(p->kstack + KSTACKSIZE);
else
@@ -84,12 +84,15 @@ setupsegs(struct proc *p)
c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
c->gdt[SEG_TSS] = SEG16(STS_T32A, (uint)&c->ts, sizeof(c->ts)-1, 0);
c->gdt[SEG_TSS].s = 0;
+ c->gdt[SEG_CPUSTACK] = SEG(STA_W|STA_E, 0, (uint)c->stack, 0);
if(p){
c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, (uint)p->mem, p->sz-1, DPL_USER);
c->gdt[SEG_UDATA] = SEG(STA_W, (uint)p->mem, p->sz-1, DPL_USER);
+ c->gdt[SEG_PROCSTACK] = SEG(STA_W|STA_E, 0, (uint)p->kstack, 0);
} else {
c->gdt[SEG_UCODE] = SEG_NULL;
c->gdt[SEG_UDATA] = SEG_NULL;
+ c->gdt[SEG_PROCSTACK] = SEG_NULL;
}
lgdt(c->gdt, sizeof(c->gdt));
@@ -140,6 +143,7 @@ copyproc(struct proc *p)
memset(&np->context, 0, sizeof(np->context));
np->context.eip = (uint)forkret;
np->context.esp = (uint)np->tf;
+ np->context.ss = SEG_PROCSTACK<<3;
// Clear %eax so that fork system call returns 0 in child.
np->tf->eax = 0;