BSD 4_3_Reno release
[unix-history] / usr / src / sys / kern / kern_ktrace.c
index 773fb62..0c39240 100644 (file)
@@ -2,19 +2,22 @@
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution is only permitted until one year after the first shipment
+ * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
+ * binary forms are permitted provided that: (1) source distributions retain
+ * this entire copyright notice and comment, and (2) distributions including
+ * binaries display the following acknowledgement:  This product includes
+ * software developed by the University of California, Berkeley and its
+ * contributors'' in the documentation or other materials provided with the
+ * distribution and in all advertising materials mentioning features or use
+ * of this software.  Neither the name of the University nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  *
- *     @(#)kern_ktrace.c       7.3 (Berkeley) %G%
+ *     @(#)kern_ktrace.c       7.9 (Berkeley) 6/28/90
  */
 
 #ifdef KTRACE
  */
 
 #ifdef KTRACE
@@ -32,7 +35,7 @@
 extern int nsysent;
 extern char *syscallnames[];
 
 extern int nsysent;
 extern char *syscallnames[];
 
-int ktrace_nocheck = 1;
+int ktrace_nocheck = 0;        /* set to 1 when security checks in place */
 
 struct ktr_header *
 ktrgetheader(type)
 
 struct ktr_header *
 ktrgetheader(type)
@@ -48,8 +51,9 @@ ktrgetheader(type)
        return (kth);
 }
 
        return (kth);
 }
 
-ktrsyscall(vp, code, narg)
+ktrsyscall(vp, code, narg, args)
        struct vnode *vp;
        struct vnode *vp;
+       int code, narg, args[];
 {
        struct  ktr_header *kth = ktrgetheader(KTR_SYSCALL);
        struct  ktr_syscall *ktp;
 {
        struct  ktr_header *kth = ktrgetheader(KTR_SYSCALL);
        struct  ktr_syscall *ktp;
@@ -63,7 +67,7 @@ ktrsyscall(vp, code, narg)
        ktp->ktr_narg = narg;
        argp = (int *)((char *)ktp + sizeof(struct ktr_syscall));
        for (i = 0; i < narg; i++)
        ktp->ktr_narg = narg;
        argp = (int *)((char *)ktp + sizeof(struct ktr_syscall));
        for (i = 0; i < narg; i++)
-               *argp++ = u.u_arg[i];
+               *argp++ = args[i];
        kth->ktr_buf = (caddr_t)ktp;
        kth->ktr_len = len;
        ktrwrite(vp, kth);
        kth->ktr_buf = (caddr_t)ktp;
        kth->ktr_len = len;
        ktrwrite(vp, kth);
@@ -71,8 +75,9 @@ ktrsyscall(vp, code, narg)
        FREE(kth, M_TEMP);
 }
 
        FREE(kth, M_TEMP);
 }
 
-ktrsysret(vp, code)
+ktrsysret(vp, code, error, retval)
        struct vnode *vp;
        struct vnode *vp;
+       int code, error, retval;
 {
        struct ktr_header *kth = ktrgetheader(KTR_SYSRET);
        struct ktr_sysret ktp;
 {
        struct ktr_header *kth = ktrgetheader(KTR_SYSRET);
        struct ktr_sysret ktp;
@@ -80,9 +85,8 @@ ktrsysret(vp, code)
        if (kth == NULL)
                return;
        ktp.ktr_code = code;
        if (kth == NULL)
                return;
        ktp.ktr_code = code;
-       ktp.ktr_eosys = u.u_eosys;
-       ktp.ktr_error = u.u_error;
-       ktp.ktr_retval = u.u_r.r_val1;          /* what about val2 ? */
+       ktp.ktr_error = error;
+       ktp.ktr_retval = retval;                /* what about val2 ? */
 
        kth->ktr_buf = (caddr_t)&ktp;
        kth->ktr_len = sizeof(struct ktr_sysret);
 
        kth->ktr_buf = (caddr_t)&ktp;
        kth->ktr_len = sizeof(struct ktr_sysret);
@@ -106,8 +110,9 @@ ktrnamei(vp, path)
        FREE(kth, M_TEMP);
 }
 
        FREE(kth, M_TEMP);
 }
 
-ktrgenio(vp, fd, rw, iov, len)
+ktrgenio(vp, fd, rw, iov, len, error)
        struct vnode *vp;
        struct vnode *vp;
+       int fd;
        enum uio_rw rw;
        register struct iovec *iov;
 {
        enum uio_rw rw;
        register struct iovec *iov;
 {
@@ -116,7 +121,7 @@ ktrgenio(vp, fd, rw, iov, len)
        register caddr_t cp;
        register int resid = len, cnt;
        
        register caddr_t cp;
        register int resid = len, cnt;
        
-       if (kth == NULL || u.u_error)
+       if (kth == NULL || error)
                return;
        MALLOC(ktp, struct ktr_genio *, sizeof(struct ktr_genio) + len,
                M_TEMP, M_WAITOK);
                return;
        MALLOC(ktp, struct ktr_genio *, sizeof(struct ktr_genio) + len,
                M_TEMP, M_WAITOK);
@@ -126,7 +131,7 @@ ktrgenio(vp, fd, rw, iov, len)
        while (resid > 0) {
                if ((cnt = iov->iov_len) > resid)
                        cnt = resid;
        while (resid > 0) {
                if ((cnt = iov->iov_len) > resid)
                        cnt = resid;
-               if (copyin(iov->iov_base, cp, cnt))
+               if (copyin(iov->iov_base, cp, (unsigned)cnt))
                        goto done;
                cp += cnt;
                resid -= cnt;
                        goto done;
                cp += cnt;
                resid -= cnt;
@@ -166,14 +171,17 @@ ktrpsig(vp, sig, action, mask, code)
 /*
  * ktrace system call
  */
 /*
  * ktrace system call
  */
-ktrace()
-{
-       register struct a {
+/* ARGSUSED */
+ktrace(curp, uap, retval)
+       struct proc *curp;
+       register struct args {
                char    *fname;
                int     ops;
                int     facs;
                int     pid;
                char    *fname;
                int     ops;
                int     facs;
                int     pid;
-       } *uap = (struct a *)u.u_ap;
+       } *uap;
+       int *retval;
+{
        register struct vnode *vp = NULL;
        register struct nameidata *ndp = &u.u_nd;
        register struct proc *p;
        register struct vnode *vp = NULL;
        register struct nameidata *ndp = &u.u_nd;
        register struct proc *p;
@@ -181,26 +189,26 @@ ktrace()
        struct pgrp *pg;
        register int facs = uap->facs;
        register int ret = 0;
        struct pgrp *pg;
        register int facs = uap->facs;
        register int ret = 0;
+       int error = 0;
 
        /*
         * Until security implications are thought through,
         * limit tracing to root (unless ktrace_nocheck is set).
         */
 
        /*
         * Until security implications are thought through,
         * limit tracing to root (unless ktrace_nocheck is set).
         */
-       if (!ktrace_nocheck && (u.u_error = suser(u.u_cred, &u.u_acflag)))
-               return;
+       if (!ktrace_nocheck && (error = suser(u.u_cred, &u.u_acflag)))
+               return (error);
        if (ops != KTROP_CLEAR) {
                /*
                 * an operation which requires a file argument.
                 */
                ndp->ni_segflg = UIO_USERSPACE;
                ndp->ni_dirp = uap->fname;
        if (ops != KTROP_CLEAR) {
                /*
                 * an operation which requires a file argument.
                 */
                ndp->ni_segflg = UIO_USERSPACE;
                ndp->ni_dirp = uap->fname;
-               if (u.u_error = vn_open(ndp, FREAD|FWRITE, 0))
-                       return;
+               if (error = vn_open(ndp, FREAD|FWRITE, 0))
+                       return (error);
                vp = ndp->ni_vp;
                if (vp->v_type != VREG) {
                vp = ndp->ni_vp;
                if (vp->v_type != VREG) {
-                       u.u_error = EACCES;
                        vrele(vp);
                        vrele(vp);
-                       return;
+                       return (EACCES);
                }
        }
        /*
                }
        }
        /*
@@ -220,7 +228,7 @@ ktrace()
         * need something to (un)trace
         */
        if (!facs) {
         * need something to (un)trace
         */
        if (!facs) {
-               u.u_error = EINVAL;
+               error = EINVAL;
                goto done;
        }
        /* 
                goto done;
        }
        /* 
@@ -229,7 +237,7 @@ ktrace()
        if (uap->pid < 0) {
                pg = pgfind(-uap->pid);
                if (pg == NULL) {
        if (uap->pid < 0) {
                pg = pgfind(-uap->pid);
                if (pg == NULL) {
-                       u.u_error = ESRCH;
+                       error = ESRCH;
                        goto done;
                }
                for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt)
                        goto done;
                }
                for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt)
@@ -241,7 +249,7 @@ ktrace()
        } else {
                p = pfind(uap->pid);
                if (p == NULL) {
        } else {
                p = pfind(uap->pid);
                if (p == NULL) {
-                       u.u_error = ESRCH;
+                       error = ESRCH;
                        goto done;
                }
                if (ops&KTRFLAG_DESCEND)
                        goto done;
                }
                if (ops&KTRFLAG_DESCEND)
@@ -250,10 +258,11 @@ ktrace()
                        ret |= ktrops(p, ops, facs, vp);
        }
        if (!ret)
                        ret |= ktrops(p, ops, facs, vp);
        }
        if (!ret)
-               u.u_error = EPERM;
+               error = EPERM;
 done:
        if (vp != NULL)
                vrele(vp);
 done:
        if (vp != NULL)
                vrele(vp);
+       return (error);
 }
 
 ktrops(p, ops, facs, vp)
 }
 
 ktrops(p, ops, facs, vp)
@@ -262,7 +271,7 @@ ktrops(p, ops, facs, vp)
 {
 
        if (u.u_uid && u.u_uid != p->p_uid)
 {
 
        if (u.u_uid && u.u_uid != p->p_uid)
-               return 0;
+               return (0);
        if (ops == KTROP_SET) {
                if (p->p_tracep != vp) { 
                        /*
        if (ops == KTROP_SET) {
                if (p->p_tracep != vp) { 
                        /*
@@ -294,7 +303,6 @@ ktrsetchildren(top, ops, facs, vp)
        struct vnode *vp;
 {
        register struct proc *p;
        struct vnode *vp;
 {
        register struct proc *p;
-       register int ndx;
        register int ret = 0;
 
        p = top;
        register int ret = 0;
 
        p = top;
@@ -330,6 +338,7 @@ ktrwrite(vp, kth)
 {
        struct uio auio;
        struct iovec aiov[2];
 {
        struct uio auio;
        struct iovec aiov[2];
+       struct proc *p;
        int error;
 
        if (vp == NULL)
        int error;
 
        if (vp == NULL)
@@ -351,5 +360,18 @@ ktrwrite(vp, kth)
        VOP_LOCK(vp);
        error = VOP_WRITE(vp, &auio, IO_UNIT|IO_APPEND, u.u_cred);
        VOP_UNLOCK(vp);
        VOP_LOCK(vp);
        error = VOP_WRITE(vp, &auio, IO_UNIT|IO_APPEND, u.u_cred);
        VOP_UNLOCK(vp);
+       if (!error)
+               return;
+       /*
+        * If error encountered, give up tracing on this vnode.
+        */
+       uprintf("\ntrace write failed with errno %d, tracing stopped\n", error);
+       for (p = allproc; p != NULL; p = p->p_nxt) {
+               if (p->p_tracep == vp) {
+                       p->p_tracep = NULL;
+                       p->p_traceflag = 0;
+                       vrele(vp);
+               }
+       }
 }
 #endif
 }
 #endif