summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>1998-05-19 00:00:14 +0000
committertegge <tegge@FreeBSD.org>1998-05-19 00:00:14 +0000
commit9fdbafa2fe06cfff465241ce76c5395269982396 (patch)
tree3b482820bffff64041452ded3ad80246ff105eb3 /sys
parent34f4d24e56af87f75658e327d3046622ea4bc85d (diff)
downloadFreeBSD-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.c28
-rw-r--r--sys/amd64/amd64/vm_machdep.c27
-rw-r--r--sys/amd64/include/ptrace.h6
-rw-r--r--sys/fs/procfs/procfs.h5
-rw-r--r--sys/fs/procfs/procfs_mem.c39
-rw-r--r--sys/fs/procfs/procfs_vnops.c4
-rw-r--r--sys/i386/i386/machdep.c28
-rw-r--r--sys/i386/i386/vm_machdep.c27
-rw-r--r--sys/i386/include/ptrace.h6
-rw-r--r--sys/kern/sys_process.c7
-rw-r--r--sys/miscfs/procfs/procfs.h5
-rw-r--r--sys/miscfs/procfs/procfs_mem.c39
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c4
-rw-r--r--sys/powerpc/include/ptrace.h6
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
OpenPOWER on IntegriCloud