add KSTACK_CHECK_MAGIC. discussed on tech-kern.

This commit is contained in:
yamt 2002-07-02 20:27:44 +00:00
parent a7f2b918d3
commit d96bff0e27
6 changed files with 125 additions and 9 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.2 1994/10/26 08:02:21 cgd Exp $ */
/* $NetBSD: proc.h,v 1.3 2002/07/02 20:27:44 yamt Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@ -47,3 +47,9 @@ struct mdproc {
/* md_flags */
#define MDP_AST 0x0001 /* async trap pending */
/* kernel stack params */
#define KSTACK_LOWEST_ADDR(p) \
((caddr_t)(p)->p_addr + (REDZONEADDR + VAX_NBPG))
#define KSTACK_SIZE \
(USPACE - (REDZONEADDR + VAX_NBPG))

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.539 2002/06/28 23:27:13 thorpej Exp $
# $NetBSD: files,v 1.540 2002/07/02 20:27:45 yamt Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -139,6 +139,7 @@ defparam opt_kgdb.h KGDB_DEV KGDB_DEVNAME
KGDB_DEVADDR KGDB_DEVRATE KGDB_DEVMODE
defflag LOCKDEBUG
defflag SYSCALL_DEBUG
defflag opt_kstack.h KSTACK_CHECK_MAGIC
# memory (ram) disk options
#

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_proc.c,v 1.47 2002/04/12 17:02:33 christos Exp $ */
/* $NetBSD: kern_proc.c,v 1.48 2002/07/02 20:27:46 yamt Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -73,7 +73,9 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.47 2002/04/12 17:02:33 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.48 2002/07/02 20:27:46 yamt Exp $");
#include "opt_kstack.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -571,3 +573,78 @@ pgrpdump()
}
}
#endif /* DEBUG */
#ifdef KSTACK_CHECK_MAGIC
#include <sys/user.h>
#define KSTACK_MAGIC 0xdeadbeaf
/* XXX should be per process basis? */
int kstackleftmin = KSTACK_SIZE;
int kstackleftthres = KSTACK_SIZE / 8; /* warn if remaining stack is less than this */
void
kstack_setup_magic(const struct proc *p)
{
u_int32_t *ip;
u_int32_t const *end;
KASSERT(p != 0);
KASSERT(p != &proc0);
/*
* fill all the stack with magic number
* so that later modification on it can be detected.
*/
ip = (u_int32_t *)KSTACK_LOWEST_ADDR(p);
end = (u_int32_t *)((caddr_t)KSTACK_LOWEST_ADDR(p) + KSTACK_SIZE);
for (; ip < end; ip++) {
*ip = KSTACK_MAGIC;
}
}
void
kstack_check_magic(const struct proc *p)
{
u_int32_t const *ip, *end;
int stackleft;
KASSERT(p != 0);
/* don't check proc0 */ /*XXX*/
if (p == &proc0)
return;
#ifdef __MACHINE_STACK_GROWS_UP
/* stack grows upwards (eg. hppa) */
ip = (u_int32_t *)((caddr_t)KSTACK_LOWEST_ADDR(p) + KSTACK_SIZE);
end = (u_int32_t *)KSTACK_LOWEST_ADDR(p);
for (ip--; ip >= end; ip--)
if (*ip != KSTACK_MAGIC)
break;
stackleft = (caddr_t)KSTACK_LOWEST_ADDR(p) + KSTACK_SIZE - (caddr_t)ip;
#else /* __MACHINE_STACK_GROWS_UP */
/* stack grows downwards (eg. i386) */
ip = (u_int32_t *)KSTACK_LOWEST_ADDR(p);
end = (u_int32_t *)((caddr_t)KSTACK_LOWEST_ADDR(p) + KSTACK_SIZE);
for (; ip < end; ip++)
if (*ip != KSTACK_MAGIC)
break;
stackleft = (caddr_t)ip - KSTACK_LOWEST_ADDR(p);
#endif /* __MACHINE_STACK_GROWS_UP */
if (kstackleftmin > stackleft) {
kstackleftmin = stackleft;
if (stackleft < kstackleftthres)
printf("warning: kernel stack left %d bytes(pid %u)\n",
stackleft, p->p_pid);
}
if (stackleft <= 0) {
panic("magic on the top of kernel stack changed for pid %u: "
"maybe kernel stack overflow\n", p->p_pid);
}
}
#endif /*KSTACK_CHECK_MAGIC*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_synch.c,v 1.108 2002/05/21 01:38:27 thorpej Exp $ */
/* $NetBSD: kern_synch.c,v 1.109 2002/07/02 20:27:46 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@ -78,10 +78,11 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.108 2002/05/21 01:38:27 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.109 2002/07/02 20:27:46 yamt Exp $");
#include "opt_ddb.h"
#include "opt_ktrace.h"
#include "opt_kstack.h"
#include "opt_lockdebug.h"
#include "opt_multiprocessor.h"
@ -848,6 +849,10 @@ mi_switch(struct proc *p)
*/
spc->spc_flags &= ~SPCF_SWITCHCLEAR;
#ifdef KSTACK_CHECK_MAGIC
kstack_check_magic(p);
#endif
/*
* Pick a new current process and switch to it. When we
* run again, we'll return back here.

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.138 2002/06/17 16:23:58 christos Exp $ */
/* $NetBSD: proc.h,v 1.139 2002/07/02 20:27:47 yamt Exp $ */
/*-
* Copyright (c) 1986, 1989, 1991, 1993
@ -45,6 +45,7 @@
#if defined(_KERNEL_OPT)
#include "opt_multiprocessor.h"
#include "opt_kstack.h"
#endif
#if defined(_KERNEL)
@ -474,5 +475,23 @@ void p_sugid(struct proc*);
void proc_trampoline_mp(void); /* XXX */
#endif
#ifdef KSTACK_CHECK_MAGIC
void kstack_setup_magic(const struct proc *);
void kstack_check_magic(const struct proc *);
#endif
/*
* kernel stack paramaters
* XXX require sizeof(struct user)
*/
/* the lowest address of kernel stack */
#ifndef KSTACK_LOWEST_ADDR
#define KSTACK_LOWEST_ADDR(p) ((caddr_t)ALIGN((p)->p_addr + 1))
#endif
/* size of kernel stack */
#ifndef KSTACK_SIZE
#define KSTACK_SIZE (USPACE - ALIGN(sizeof(struct user)))
#endif
#endif /* _KERNEL */
#endif /* !_SYS_PROC_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_glue.c,v 1.58 2002/05/15 06:57:49 matt Exp $ */
/* $NetBSD: uvm_glue.c,v 1.59 2002/07/02 20:27:48 yamt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -67,9 +67,10 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.58 2002/05/15 06:57:49 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.59 2002/07/02 20:27:48 yamt Exp $");
#include "opt_kgdb.h"
#include "opt_kstack.h"
#include "opt_sysv.h"
#include "opt_uvmhist.h"
@ -295,6 +296,13 @@ uvm_fork(p1, p2, shared, stack, stacksize, func, arg)
if (error)
panic("uvm_fork: uvm_fault_wire failed: %d", error);
#ifdef KSTACK_CHECK_MAGIC
/*
* fill stack with magic number
*/
kstack_setup_magic(p2);
#endif
/*
* p_stats currently points at a field in the user struct. Copy
* parts of p_stats, and zero out the rest.