Disallow reading the current kernel stack. Only the user structure and

the current registers should be accessible.
Reviewed by:	David Greenman <dg@root.com>
This commit is contained in:
Tor Egge 1998-05-19 00:00:14 +00:00
parent 0a11c79d42
commit afc6ea238f
14 changed files with 187 additions and 40 deletions

View File

@ -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;

View File

@ -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;
{
int error;
caddr_t tempuser;
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));
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

View File

@ -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

View File

@ -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 *));

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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;
{
int error;
caddr_t tempuser;
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));
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

View File

@ -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

View File

@ -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) {

View File

@ -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 *));

View File

@ -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;
}

View File

@ -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)

View File

@ -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