diff options
author | tegge <tegge@FreeBSD.org> | 1998-05-19 00:00:14 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 1998-05-19 00:00:14 +0000 |
commit | 9fdbafa2fe06cfff465241ce76c5395269982396 (patch) | |
tree | 3b482820bffff64041452ded3ad80246ff105eb3 /sys | |
parent | 34f4d24e56af87f75658e327d3046622ea4bc85d (diff) | |
download | FreeBSD-src-9fdbafa2fe06cfff465241ce76c5395269982396.zip FreeBSD-src-9fdbafa2fe06cfff465241ce76c5395269982396.tar.gz |
Disallow reading the current kernel stack. Only the user structure and
the current registers should be accessible.
Reviewed by: David Greenman <dg@root.com>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/machdep.c | 28 | ||||
-rw-r--r-- | sys/amd64/amd64/vm_machdep.c | 27 | ||||
-rw-r--r-- | sys/amd64/include/ptrace.h | 6 | ||||
-rw-r--r-- | sys/fs/procfs/procfs.h | 5 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_mem.c | 39 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_vnops.c | 4 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 28 | ||||
-rw-r--r-- | sys/i386/i386/vm_machdep.c | 27 | ||||
-rw-r--r-- | sys/i386/include/ptrace.h | 6 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 7 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs.h | 5 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_mem.c | 39 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 4 | ||||
-rw-r--r-- | sys/powerpc/include/ptrace.h | 6 |
14 files changed, 189 insertions, 42 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index faa4bf9..fa851fa 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.293 1998/03/23 19:52:32 jlemon Exp $ + * $Id: machdep.c,v 1.294 1998/04/06 15:46:17 peter Exp $ */ #include "apm.h" @@ -121,11 +121,9 @@ #include <i386/isa/intr_machdep.h> #include <i386/isa/rtc.h> #include <machine/random.h> +#include <sys/ptrace.h> extern void init386 __P((int first)); -extern int ptrace_set_pc __P((struct proc *p, unsigned int addr)); -extern int ptrace_single_step __P((struct proc *p)); -extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data)); extern void dblfault_handler __P((void)); extern void printcpuinfo(void); /* XXX header file */ @@ -1610,6 +1608,28 @@ ptrace_single_step(p) return (0); } +int ptrace_read_u_check(p, addr, len) + struct proc *p; + vm_offset_t addr; + size_t len; +{ + vm_offset_t gap; + + if ((vm_offset_t) (addr + len) < addr) + return EPERM; + if ((vm_offset_t) (addr + len) <= sizeof(struct user)) + return 0; + + gap = (char *) p->p_md.md_regs - (char *) p->p_addr; + + if ((vm_offset_t) addr < gap) + return EPERM; + if ((vm_offset_t) (addr + len) <= + (vm_offset_t) (gap + sizeof(struct trapframe))) + return 0; + return EPERM; +} + int ptrace_write_u(p, off, data) struct proc *p; vm_offset_t off; diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 7e3b32a..9c8b1f5 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -38,7 +38,7 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.106 1998/05/16 14:44:11 kato Exp $ + * $Id: vm_machdep.c,v 1.107 1998/05/17 22:12:11 tegge Exp $ */ #include "npx.h" @@ -742,10 +742,27 @@ cpu_coredump(p, vp, cred) struct vnode *vp; struct ucred *cred; { - - return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES), - (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, - p)); + int error; + caddr_t tempuser; + + tempuser = malloc(ctob(UPAGES), M_TEMP, M_WAITOK); + if (!tempuser) + return EINVAL; + + bzero(tempuser, ctob(UPAGES)); + bcopy(p->p_addr, tempuser, sizeof(struct user)); + bcopy(p->p_md.md_regs, + tempuser + ((caddr_t) p->p_md.md_regs - (caddr_t) p->p_addr), + sizeof(struct trapframe)); + + error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser, + ctob(UPAGES), + (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, + cred, (int *)NULL, p); + + free(tempuser, M_TEMP); + + return error; } #ifdef notyet diff --git a/sys/amd64/include/ptrace.h b/sys/amd64/include/ptrace.h index a8f7e71..ec3d5aa 100644 --- a/sys/amd64/include/ptrace.h +++ b/sys/amd64/include/ptrace.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ptrace.h 8.1 (Berkeley) 6/11/93 - * $Id$ + * $Id: ptrace.h,v 1.5 1997/02/22 09:35:03 peter Exp $ */ #ifndef _MACHINE_PTRACE_H_ @@ -45,5 +45,9 @@ #define PT_GETFPREGS (PT_FIRSTMACH + 3) #define PT_SETFPREGS (PT_FIRSTMACH + 4) +#ifdef KERNEL +int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len)); +#endif /* !KERNEL */ + #endif diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h index ada5ef3..9adee8a 100644 --- a/sys/fs/procfs/procfs.h +++ b/sys/fs/procfs/procfs.h @@ -37,7 +37,7 @@ * @(#)procfs.h 8.9 (Berkeley) 5/14/95 * * From: - * $Id: procfs.h,v 1.17 1997/09/07 05:26:16 bde Exp $ + * $Id: procfs.h,v 1.18 1997/12/30 08:46:41 bde Exp $ */ /* @@ -155,6 +155,9 @@ int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, str int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +/* Return 1 if process has special kernel digging privileges */ +int procfs_kmemaccess __P((struct proc *)); + /* functions to check whether or not files should be displayed */ int procfs_validfile __P((struct proc *)); int procfs_validfpregs __P((struct proc *)); diff --git a/sys/fs/procfs/procfs_mem.c b/sys/fs/procfs/procfs_mem.c index 5184f47..29c883c 100644 --- a/sys/fs/procfs/procfs_mem.c +++ b/sys/fs/procfs/procfs_mem.c @@ -37,7 +37,7 @@ * * @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94 * - * $Id: procfs_mem.c,v 1.30 1998/02/06 12:13:41 eivind Exp $ + * $Id: procfs_mem.c,v 1.31 1998/04/17 22:36:55 des Exp $ */ /* @@ -61,11 +61,14 @@ #include <vm/vm_page.h> #include <vm/vm_extern.h> #include <sys/user.h> +#include <sys/ptrace.h> -static int procfs_rwmem __P((struct proc *p, struct uio *uio)); +static int procfs_rwmem __P((struct proc *curp, + struct proc *p, struct uio *uio)); static int -procfs_rwmem(p, uio) +procfs_rwmem(curp, p, uio) + struct proc *curp; struct proc *p; struct uio *uio; { @@ -130,7 +133,12 @@ procfs_rwmem(p, uio) if (uva >= VM_MAXUSER_ADDRESS) { vm_offset_t tkva; - if (writing || (uva >= (VM_MAXUSER_ADDRESS + UPAGES * PAGE_SIZE))) { + if (writing || + uva >= VM_MAXUSER_ADDRESS + UPAGES * PAGE_SIZE || + (ptrace_read_u_check(p, + uva - (vm_offset_t) VM_MAXUSER_ADDRESS, + (size_t) len) && + !procfs_kmemaccess(curp))) { error = 0; break; } @@ -290,11 +298,11 @@ procfs_domem(curp, p, pfs, uio) */ if (!CHECKIO(curp, p) && - !(curp->p_cred->pc_ucred->cr_gid == KMEM_GROUP && - uio->uio_rw == UIO_READ)) + !(uio->uio_rw == UIO_READ && + procfs_kmemaccess(curp))) return EPERM; - return (procfs_rwmem(p, uio)); + return (procfs_rwmem(curp, p, uio)); } /* @@ -315,3 +323,20 @@ procfs_findtextvp(p) return (p->p_textvp); } + +int procfs_kmemaccess(curp) + struct proc *curp; +{ + int i; + struct ucred *cred; + + cred = curp->p_cred->pc_ucred; + if (suser(cred, &curp->p_acflag)) + return 1; + + for (i = 0; i < cred->cr_ngroups; i++) + if (cred->cr_groups[i] == KMEM_GROUP) + return 1; + + return 0; +} diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index 78b6d92..54893ad 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -36,7 +36,7 @@ * * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * - * $Id: procfs_vnops.c,v 1.55 1998/02/09 06:09:46 eivind Exp $ + * $Id: procfs_vnops.c,v 1.56 1998/03/26 20:52:42 phk Exp $ */ /* @@ -142,7 +142,7 @@ procfs_open(ap) p1 = ap->a_p; if (!CHECKIO(p1, p2) && - (p1->p_cred->pc_ucred->cr_gid != KMEM_GROUP)) + !procfs_kmemaccess(p1)) return (EPERM); if (ap->a_mode & FWRITE) diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index faa4bf9..fa851fa 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 - * $Id: machdep.c,v 1.293 1998/03/23 19:52:32 jlemon Exp $ + * $Id: machdep.c,v 1.294 1998/04/06 15:46:17 peter Exp $ */ #include "apm.h" @@ -121,11 +121,9 @@ #include <i386/isa/intr_machdep.h> #include <i386/isa/rtc.h> #include <machine/random.h> +#include <sys/ptrace.h> extern void init386 __P((int first)); -extern int ptrace_set_pc __P((struct proc *p, unsigned int addr)); -extern int ptrace_single_step __P((struct proc *p)); -extern int ptrace_write_u __P((struct proc *p, vm_offset_t off, int data)); extern void dblfault_handler __P((void)); extern void printcpuinfo(void); /* XXX header file */ @@ -1610,6 +1608,28 @@ ptrace_single_step(p) return (0); } +int ptrace_read_u_check(p, addr, len) + struct proc *p; + vm_offset_t addr; + size_t len; +{ + vm_offset_t gap; + + if ((vm_offset_t) (addr + len) < addr) + return EPERM; + if ((vm_offset_t) (addr + len) <= sizeof(struct user)) + return 0; + + gap = (char *) p->p_md.md_regs - (char *) p->p_addr; + + if ((vm_offset_t) addr < gap) + return EPERM; + if ((vm_offset_t) (addr + len) <= + (vm_offset_t) (gap + sizeof(struct trapframe))) + return 0; + return EPERM; +} + int ptrace_write_u(p, off, data) struct proc *p; vm_offset_t off; diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index 7e3b32a..9c8b1f5 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -38,7 +38,7 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.106 1998/05/16 14:44:11 kato Exp $ + * $Id: vm_machdep.c,v 1.107 1998/05/17 22:12:11 tegge Exp $ */ #include "npx.h" @@ -742,10 +742,27 @@ cpu_coredump(p, vp, cred) struct vnode *vp; struct ucred *cred; { - - return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES), - (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, - p)); + int error; + caddr_t tempuser; + + tempuser = malloc(ctob(UPAGES), M_TEMP, M_WAITOK); + if (!tempuser) + return EINVAL; + + bzero(tempuser, ctob(UPAGES)); + bcopy(p->p_addr, tempuser, sizeof(struct user)); + bcopy(p->p_md.md_regs, + tempuser + ((caddr_t) p->p_md.md_regs - (caddr_t) p->p_addr), + sizeof(struct trapframe)); + + error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser, + ctob(UPAGES), + (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, + cred, (int *)NULL, p); + + free(tempuser, M_TEMP); + + return error; } #ifdef notyet diff --git a/sys/i386/include/ptrace.h b/sys/i386/include/ptrace.h index a8f7e71..ec3d5aa 100644 --- a/sys/i386/include/ptrace.h +++ b/sys/i386/include/ptrace.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ptrace.h 8.1 (Berkeley) 6/11/93 - * $Id$ + * $Id: ptrace.h,v 1.5 1997/02/22 09:35:03 peter Exp $ */ #ifndef _MACHINE_PTRACE_H_ @@ -45,5 +45,9 @@ #define PT_GETFPREGS (PT_FIRSTMACH + 3) #define PT_SETFPREGS (PT_FIRSTMACH + 4) +#ifdef KERNEL +int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len)); +#endif /* !KERNEL */ + #endif diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index fcfbb7c..8231b23 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sys_process.c,v 1.35 1998/02/04 22:32:36 eivind Exp $ + * $Id: sys_process.c,v 1.36 1998/02/06 12:13:27 eivind Exp $ */ #include <sys/param.h> @@ -409,6 +409,11 @@ ptrace(curp, uap) if ((u_int)uap->addr > (UPAGES * PAGE_SIZE - sizeof(int))) { return EFAULT; } + if (ptrace_read_u_check(p,(vm_offset_t) uap->addr, + sizeof(int)) && + !procfs_kmemaccess(curp)) { + return EFAULT; + } error = 0; PHOLD(p); /* user had damn well better be incore! */ if (p->p_flag & P_INMEM) { diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index ada5ef3..9adee8a 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -37,7 +37,7 @@ * @(#)procfs.h 8.9 (Berkeley) 5/14/95 * * From: - * $Id: procfs.h,v 1.17 1997/09/07 05:26:16 bde Exp $ + * $Id: procfs.h,v 1.18 1997/12/30 08:46:41 bde Exp $ */ /* @@ -155,6 +155,9 @@ int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, str int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +/* Return 1 if process has special kernel digging privileges */ +int procfs_kmemaccess __P((struct proc *)); + /* functions to check whether or not files should be displayed */ int procfs_validfile __P((struct proc *)); int procfs_validfpregs __P((struct proc *)); diff --git a/sys/miscfs/procfs/procfs_mem.c b/sys/miscfs/procfs/procfs_mem.c index 5184f47..29c883c 100644 --- a/sys/miscfs/procfs/procfs_mem.c +++ b/sys/miscfs/procfs/procfs_mem.c @@ -37,7 +37,7 @@ * * @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94 * - * $Id: procfs_mem.c,v 1.30 1998/02/06 12:13:41 eivind Exp $ + * $Id: procfs_mem.c,v 1.31 1998/04/17 22:36:55 des Exp $ */ /* @@ -61,11 +61,14 @@ #include <vm/vm_page.h> #include <vm/vm_extern.h> #include <sys/user.h> +#include <sys/ptrace.h> -static int procfs_rwmem __P((struct proc *p, struct uio *uio)); +static int procfs_rwmem __P((struct proc *curp, + struct proc *p, struct uio *uio)); static int -procfs_rwmem(p, uio) +procfs_rwmem(curp, p, uio) + struct proc *curp; struct proc *p; struct uio *uio; { @@ -130,7 +133,12 @@ procfs_rwmem(p, uio) if (uva >= VM_MAXUSER_ADDRESS) { vm_offset_t tkva; - if (writing || (uva >= (VM_MAXUSER_ADDRESS + UPAGES * PAGE_SIZE))) { + if (writing || + uva >= VM_MAXUSER_ADDRESS + UPAGES * PAGE_SIZE || + (ptrace_read_u_check(p, + uva - (vm_offset_t) VM_MAXUSER_ADDRESS, + (size_t) len) && + !procfs_kmemaccess(curp))) { error = 0; break; } @@ -290,11 +298,11 @@ procfs_domem(curp, p, pfs, uio) */ if (!CHECKIO(curp, p) && - !(curp->p_cred->pc_ucred->cr_gid == KMEM_GROUP && - uio->uio_rw == UIO_READ)) + !(uio->uio_rw == UIO_READ && + procfs_kmemaccess(curp))) return EPERM; - return (procfs_rwmem(p, uio)); + return (procfs_rwmem(curp, p, uio)); } /* @@ -315,3 +323,20 @@ procfs_findtextvp(p) return (p->p_textvp); } + +int procfs_kmemaccess(curp) + struct proc *curp; +{ + int i; + struct ucred *cred; + + cred = curp->p_cred->pc_ucred; + if (suser(cred, &curp->p_acflag)) + return 1; + + for (i = 0; i < cred->cr_ngroups; i++) + if (cred->cr_groups[i] == KMEM_GROUP) + return 1; + + return 0; +} diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 78b6d92..54893ad 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -36,7 +36,7 @@ * * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * - * $Id: procfs_vnops.c,v 1.55 1998/02/09 06:09:46 eivind Exp $ + * $Id: procfs_vnops.c,v 1.56 1998/03/26 20:52:42 phk Exp $ */ /* @@ -142,7 +142,7 @@ procfs_open(ap) p1 = ap->a_p; if (!CHECKIO(p1, p2) && - (p1->p_cred->pc_ucred->cr_gid != KMEM_GROUP)) + !procfs_kmemaccess(p1)) return (EPERM); if (ap->a_mode & FWRITE) diff --git a/sys/powerpc/include/ptrace.h b/sys/powerpc/include/ptrace.h index a8f7e71..ec3d5aa 100644 --- a/sys/powerpc/include/ptrace.h +++ b/sys/powerpc/include/ptrace.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ptrace.h 8.1 (Berkeley) 6/11/93 - * $Id$ + * $Id: ptrace.h,v 1.5 1997/02/22 09:35:03 peter Exp $ */ #ifndef _MACHINE_PTRACE_H_ @@ -45,5 +45,9 @@ #define PT_GETFPREGS (PT_FIRSTMACH + 3) #define PT_SETFPREGS (PT_FIRSTMACH + 4) +#ifdef KERNEL +int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len)); +#endif /* !KERNEL */ + #endif |