ptrace broken on latest CURRENT ?

Craig Rodrigues rodrigc at crodrigues.org
Sat Nov 27 22:52:43 PST 2004


On Sat, Nov 27, 2004 at 09:04:11PM -0500, Craig Rodrigues wrote:
> On Sat, Nov 27, 2004 at 07:30:36PM -0500, Craig Rodrigues wrote:
> > --- sys_generic.c.orig	Sat Nov 27 19:14:39 2004
> > +++ sys_generic.c	Sat Nov 27 19:17:09 2004
> > @@ -503,7 +503,7 @@
> >          if ((size > IOCPARM_MAX) ||
> >              ((com & (IOC_VOID  | IOC_IN | IOC_OUT)) == 0) ||
> >              ((com & IOC_VOID) && size > 0) ||
> > -            ((com & (IOC_IN | IOC_OUT)) && size == 0)) {
> > +            ((com & IOC_OUT) && size == 0)) {
> >                  fdrop(fp, td);
> >                  return (ENOTTY);
> >          }
> 
> 
> Hi,
> 
> If we leave the define of PIOCBIS as: 
> # define       PIOCBIS _IOC(IOC_IN, 'p', 1, 0)
> 
> then the length of this ioctl is going to be 0 (from IOCPARM_LEN).
> I'm not sure if that is a good thing.   This is what tripped
> up the original ioctl() code in sys_generic.c.
> 
> If we don't change sys_generic.c, then the other approach
> to this problem is to fix the ioctl() calls in the procfs.
> Any comments on this?

Hi,

If PIOCBIS is redefined according to the patch which I submitted, then
strace needs to be patched as well.   I'm not sure of the best way
to do this other than bumping __FreeBSD_version__ and checking it.

Here are my patches to procfs and strace.  
Comments?

--
Craig Rodrigues        
http://crodrigues.org
rodrigc at crodrigues.org

-------------- next part --------------
Index: sys/fs/procfs/procfs_ioctl.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_ioctl.c,v
retrieving revision 1.10
diff -u -r1.10 procfs_ioctl.c
--- sys/fs/procfs/procfs_ioctl.c	7 Dec 2003 17:40:00 -0000	1.10
+++ sys/fs/procfs/procfs_ioctl.c	28 Nov 2004 06:48:03 -0000
@@ -46,8 +46,8 @@
 procfs_ioctl(PFS_IOCTL_ARGS)
 {
 	struct procfs_status *ps;
-	int error, flags, sig;
-
+	int error;
+	unsigned int flags, sig;
 	PROC_LOCK(p);
 	error = 0;
 	switch (cmd) {
Index: sys/sys/param.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/param.h,v
retrieving revision 1.218
diff -u -r1.218 param.h
--- sys/sys/param.h	4 Nov 2004 08:38:34 -0000	1.218
+++ sys/sys/param.h	28 Nov 2004 06:48:05 -0000
@@ -57,7 +57,7 @@
  *		is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 600006	/* Master, propagated to newvers */
+#define __FreeBSD_version 600007	/* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>
Index: sys/sys/pioctl.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/pioctl.h,v
retrieving revision 1.12
diff -u -r1.12 pioctl.h
--- sys/sys/pioctl.h	4 Aug 2002 01:06:58 -0000	1.12
+++ sys/sys/pioctl.h	28 Nov 2004 06:48:05 -0000
@@ -49,12 +49,12 @@
 	unsigned long	val;	/* Any extra data */
 };
 
-# define	PIOCBIS	_IOC(IOC_IN, 'p', 1, 0)	/* Set event flag */
-# define	PIOCBIC	_IOC(IOC_IN, 'p', 2, 0)	/* Clear event flag */
-# define	PIOCSFL	_IOC(IOC_IN, 'p', 3, 0)	/* Set flags */
+# define	PIOCBIS	_IOW('p', 1, unsigned int)	/* Set event flag */
+# define	PIOCBIC	_IOW('p', 2, unsigned int)	/* Clear event flag */
+# define	PIOCSFL	_IOW('p', 3, unsigned int)	/* Set flags */
 			/* wait for proc to stop */
 # define	PIOCWAIT	_IOR('p', 4, struct procfs_status)
-# define	PIOCCONT	_IOC(IOC_IN, 'p', 5, 0)	/* Continue a process */
+# define	PIOCCONT	_IOW('p', 5, unsigned int)	/* Continue a process */
 			/* Get proc status */
 # define	PIOCSTATUS	_IOR('p', 6, struct procfs_status)
 # define	PIOCGFL	_IOR('p', 7, unsigned int)	/* Get flags */
Index: usr.bin/truss/extern.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/truss/extern.h,v
retrieving revision 1.9
diff -u -r1.9 extern.h
--- usr.bin/truss/extern.h	17 Jul 2004 19:19:36 -0000	1.9
+++ usr.bin/truss/extern.h	28 Nov 2004 06:48:06 -0000
@@ -32,7 +32,7 @@
  */
 
 extern int setup_and_wait(char **);
-extern int start_tracing(int, int, int);
+extern int start_tracing(int, unsigned int, int);
 extern void restore_proc(int);
 extern const char *ioctlname(register_t val);
 extern char *strsig(int sig);
Index: usr.bin/truss/main.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/truss/main.c,v
retrieving revision 1.38
diff -u -r1.38 main.c
--- usr.bin/truss/main.c	17 Jul 2004 19:19:36 -0000	1.38
+++ usr.bin/truss/main.c	28 Nov 2004 06:48:07 -0000
@@ -322,7 +322,7 @@
 	break;
       }
     }
-    if (ioctl(Procfd, PIOCCONT, val) == -1) {
+    if (ioctl(Procfd, PIOCCONT, &val) == -1) {
       if (kill(trussinfo->pid, 0) == -1 && errno == ESRCH)
 	break;
       else
Index: usr.bin/truss/setup.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/truss/setup.c,v
retrieving revision 1.19
diff -u -r1.19 setup.c
--- usr.bin/truss/setup.c	7 Jan 2004 14:29:45 -0000	1.19
+++ usr.bin/truss/setup.c	28 Nov 2004 06:48:08 -0000
@@ -54,7 +54,7 @@
 #include "truss.h"
 #include "extern.h"
 
-static int evflags = 0;
+static unsigned int evflags = 0;
 
 /*
  * setup_and_wait() is called to start a process.  All it really does
@@ -69,19 +69,19 @@
   char buf[32];
   int fd;
   int pid;
-  int flags;
+  unsigned int flags;
 
   pid = fork();
   if (pid == -1) {
     err(1, "fork failed");
   }
   if (pid == 0) {	/* Child */
-    int mask = S_EXEC | S_EXIT;
+    unsigned int mask = S_EXEC | S_EXIT;
     fd = open("/proc/curproc/mem", O_WRONLY);
     if (fd == -1)
       err(2, "cannot open /proc/curproc/mem");
     fcntl(fd, F_SETFD, 1);
-    if (ioctl(fd, PIOCBIS, mask) == -1)
+    if (ioctl(fd, PIOCBIS, &mask) == -1)
       err(3, "PIOCBIS");
     flags = PF_LINGER;
     /*
@@ -89,11 +89,11 @@
      * process on last close; normally, this is the behaviour
      * we want.
      */
-    if (ioctl(fd, PIOCSFL, flags) == -1)
+    if (ioctl(fd, PIOCSFL, &flags) == -1)
       warn("cannot set PF_LINGER");
     execvp(command[0], command);
     mask = ~0;
-    ioctl(fd, PIOCBIC, ~0);
+    ioctl(fd, PIOCBIC, &mask);
     err(4, "execvp %s", command[0]);
   }
   /* Only in the parent here */
@@ -128,7 +128,7 @@
  */
 
 int
-start_tracing(int pid, int eventflags, int flags) {
+start_tracing(int pid, unsigned int eventflags, int flags) {
   int fd;
   char buf[32];
   struct procfs_status tmp;
@@ -151,7 +151,7 @@
   }
   evflags = tmp.events;
 
-  if (ioctl(fd, PIOCBIS, eventflags) == -1)
+  if (ioctl(fd, PIOCBIS, &eventflags) == -1)
     err(9, "cannot set procfs event bit mask");
 
   /*
@@ -160,7 +160,7 @@
    * needs to be woken up via procctl.
    */
 
-  if (ioctl(fd, PIOCSFL, flags) == -1)
+  if (ioctl(fd, PIOCSFL, &flags) == -1)
     warn("cannot clear PF_LINGER");
 
   return fd;
@@ -174,9 +174,9 @@
  */
 void
 restore_proc(int signo __unused) {
-
-  ioctl(Procfd, PIOCBIC, ~0);
+  unsigned int flags = ~0;
+  ioctl(Procfd, PIOCBIC, &flags);
   if (evflags)
-    ioctl(Procfd, PIOCBIS, evflags);
+    ioctl(Procfd, PIOCBIS, &evflags);
   exit(0);
 }
-------------- next part --------------
--- strace.c.orig	Tue Nov 11 16:24:23 2003
+++ strace.c	Sun Nov 28 01:33:18 2004
@@ -798,7 +798,11 @@
 	        return -1;
 	}
 	arg &= ~PF_LINGER;
+#if __FreeBSD_version >= 600007
+	if (ioctl(tcp->pfd, PIOCSFL, &arg) < 0) {
+#else
 	if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) {
+#endif /* __FreeBSD_version */
 	        perror("PIOCSFL");
 	        return -1;
 	}
@@ -859,7 +863,11 @@
 #else /* FREEBSD */
 	/* set events flags. */
 	arg = S_SIG | S_SCE | S_SCX ;
+#if __FreeBSD_version >= 600007
+	if(ioctl(tcp->pfd, PIOCBIS, &arg) < 0) {
+#else
 	if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) {
+#endif
 		perror("PIOCBIS");
 		return -1;
 	}
@@ -898,7 +906,7 @@
 					break;
 			}
 			/* Set it running: maybe execve will be next. */
-#ifndef FREEBSD
+#if !defined(FREEBSD) || ((defined FREEBSD) && (__FreeBSD_version >= 600007))
 			arg = 0;
 			if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
 #else /* FREEBSD */
@@ -1796,7 +1804,7 @@
 			break;
 		}
 		arg = 0;
-#ifndef FREEBSD
+#if !defined(FREEBSD) || ((defined FREEBSD) && (__FreeBSD_version >= 600007))
 		if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
 #else
 		if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) {


More information about the freebsd-current mailing list