Subject: kern/25741: ras(9) sequence is not protected against ptrace(2)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <itohy@netbsd.org>
List: netbsd-bugs
Date: 05/29/2004 11:16:15
>Number:         25741
>Category:       kern
>Synopsis:       ras(9) sequence is not protected against ptrace(2)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 29 02:17:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     ITOH Yasufumi
>Release:        NetBSD 2.0F (May 26, 2004)
>Organization:
>Environment:
System: NetBSD pino.my.domain 1.6L NetBSD 1.6L (PINO) #380: Mon Jun 9 20:33:32 JST 2003 itohy@pino.my.domain:/remote/fmv.w/src/sys/arch/i386/compile/PINO i386
Architecture: i386
Machine: i386

>Description:
	ras(9) code sequence can be modified by ptrace(2).

	ptrace(2) checks for RAS in PT_WRITE_I and PT_WRITE_D cases,
	but doesn't in PT_IO case.
	See the code potion below.

sys/kern/sys_process.c:
int
sys_ptrace(l, v, retval)
	:
{
	:
	switch (SCARG(uap, req)) {
	:
	case  PT_WRITE_I:		/* XXX no separate I and D spaces */
	case  PT_WRITE_D:
#if defined(__HAVE_RAS)
		/*
		 * Can't write to a RAS
		 */
		if (!LIST_EMPTY(&t->p_raslist) &&
		    (ras_lookup(t, SCARG(uap, addr)) != (caddr_t)-1)) {
			return (EACCES);
		}
#endif
		write = 1;
		tmp = SCARG(uap, data);
	case  PT_READ_I:		/* XXX no separate I and D spaces */
	case  PT_READ_D:
		:
		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
		uio.uio_procp = p;
		error = process_domem(p, t, &uio);
		if (!write)
			*retval = tmp;
		return (error);
	:
	case  PT_IO:
		error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
		:
		uio.uio_procp = p;
		switch (piod.piod_op) {
		case PIOD_READ_D:
		case PIOD_READ_I:
			uio.uio_rw = UIO_READ;
			break;
		case PIOD_WRITE_D:
		case PIOD_WRITE_I:
			uio.uio_rw = UIO_WRITE;
			break;
		default:
			return (EINVAL);
		}
		error = process_domem(p, t, &uio);
		piod.piod_len -= uio.uio_resid;
		(void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
		return (error);
	:

>How-To-Repeat:
	code inspection

>Fix:
	Move the RAS check to process_domem()?

>Release-Note:
>Audit-Trail:
>Unformatted: