Change ptrace(2) to allow MD specific requests [PATCH]

Marcel Moolenaar marcel at xcllnt.net
Tue Aug 12 13:37:32 PDT 2003


Gang,

There's a need on ia64 to have machine-specific ptrace(2) requests.
To allow for this, we need to change the ptrace(2) entry point to
allow requests that it does not understand so that they can be
passed to a machine specific handler. Please review the attached
patch for any vulnerabilies.

Some background follows:

When machine-specific ptrace(2) requests exist, <machine/ptrace.h>
defines __HAVE_PTRACE_MACHDEP (taken from NetBSD). Based on this
we call cpu_ptrace() for any request larger or equal to PT_FIRSTMACH
If __HAVE_PTRACE_MACHDEP is not defined, then any request larger
or equal to PT_FIRSTMACH is invalid by definition.

The implication is that we cannot short-circuit requests we don't
know about in MI code. Instead we check privileges and fall through
to where we actually handle the request.

This changes the behaviour of the interface when an unknown and
unprivileged request is made. Previously we would return EINVAL
(due to the unknown request). With this patch, we will return
EPERM or EBUSY (due to the lack of permissions).

The question before you: is this patch acceptable?

Thanks,

-- 
 Marcel Moolenaar	  USPA: A-39004		 marcel at xcllnt.net
-------------- next part --------------
Index: sys_process.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sys_process.c,v
retrieving revision 1.113
diff -u -r1.113 sys_process.c
--- sys_process.c	10 Aug 2003 23:04:55 -0000	1.113
+++ sys_process.c	11 Aug 2003 21:26:17 -0000
@@ -336,6 +336,7 @@
 		break;
 	default:
 		addr = uap->addr;
+		break;
 	}
 	if (error)
 		return (error);
@@ -449,21 +450,7 @@
 		/* OK */
 		break;
 
-	case PT_READ_I:
-	case PT_READ_D:
-	case PT_WRITE_I:
-	case PT_WRITE_D:
-	case PT_IO:
-	case PT_CONTINUE:
-	case PT_KILL:
-	case PT_STEP:
-	case PT_DETACH:
-	case PT_GETREGS:
-	case PT_SETREGS:
-	case PT_GETFPREGS:
-	case PT_SETFPREGS:
-	case PT_GETDBREGS:
-	case PT_SETDBREGS:
+	default:
 		/* not being traced... */
 		if ((p->p_flag & P_TRACED) == 0) {
 			error = EPERM;
@@ -484,10 +471,6 @@
 
 		/* OK */
 		break;
-
-	default:
-		error = EINVAL;
-		goto fail;
 	}
 
 	td2 = FIRST_THREAD_IN_PROC(p);
@@ -701,13 +684,21 @@
 		PROC_UNLOCK(p);
 		return (error);
 
+#ifdef __HAVE_PTRACE_MACHDEP
 	default:
-		KASSERT(0, ("unreachable code\n"));
+		if (req >= PT_FIRSTMACH) {
+			_PHOLD(p);
+			error = cpu_ptrace(td2, req, addr, data);
+			_PRELE(p);
+			PROC_UNLOCK(p);
+			return (error);
+		}
 		break;
+#endif
 	}
 
-	KASSERT(0, ("unreachable code\n"));
-	return (0);
+	/* Unknown request. */
+	error = EINVAL;
 
 fail:
 	PROC_UNLOCK(p);


More information about the freebsd-audit mailing list