root/sys/sys/ktrace.h
/*-
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 1988, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. 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 BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _SYS_KTRACE_H_
#define _SYS_KTRACE_H_

#include <sys/param.h>
#include <sys/caprights.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/_uexterror.h>
#include <sys/_uio.h>

/*
 * operations to ktrace system call  (KTROP(op))
 */
#define KTROP_SET               0       /* set trace points */
#define KTROP_CLEAR             1       /* clear trace points */
#define KTROP_CLEARFILE         2       /* stop all tracing to file */
#define KTROP(o)                ((o)&3) /* macro to extract operation */
/*
 * flags (ORed in with operation)
 */
#define KTRFLAG_DESCEND         4       /* perform op on all children too */

/*
 * ktrace record header
 */
struct ktr_header_v0 {
        int     ktr_len;                /* length of buf */
        short   ktr_type;               /* trace record type */
        pid_t   ktr_pid;                /* process id */
        char    ktr_comm[MAXCOMLEN + 1];/* command name */
        struct  timeval ktr_time;       /* timestamp */
        long    ktr_tid;                /* thread id */
};

struct ktr_header {
        int     ktr_len;                /* length of buf */
        short   ktr_type;               /* trace record type */
        short   ktr_version;            /* ktr_header version */
        pid_t   ktr_pid;                /* process id */
        char    ktr_comm[MAXCOMLEN + 1];/* command name */
        struct  timespec ktr_time;      /* timestamp */
        /* XXX: make ktr_tid an lwpid_t on next ABI break */
        long    ktr_tid;                /* thread id */
        int     ktr_cpu;                /* cpu id */
};

#define KTR_VERSION0    0
#define KTR_VERSION1    1
#define KTR_OFFSET_V0   sizeof(struct ktr_header_v0) - \
                            sizeof(struct ktr_header)
/*
 * Test for kernel trace point (MP SAFE).
 *
 * KTRCHECK() just checks that the type is enabled and is only for
 * internal use in the ktrace subsystem.  KTRPOINT() checks against
 * ktrace recursion as well as checking that the type is enabled and
 * is the public interface.
 */
#define KTRCHECK(td, type)      ((td)->td_proc->p_traceflag & (1 << type))
#define KTRPOINT(td, type)      (__predict_false(KTRCHECK((td), (type))))
#define KTRUSERRET(td) do {                                             \
        if (__predict_false(!STAILQ_EMPTY_ATOMIC(&(td)->td_proc->p_ktr))) \
                ktruserret(td);                                         \
} while (0)

/*
 * ktrace record types
 */

/*
 * KTR_SYSCALL - system call record
 */
#define KTR_SYSCALL     1
struct ktr_syscall {
        short   ktr_code;               /* syscall number */
        short   ktr_narg;               /* number of arguments */
        /*
         * followed by ktr_narg register_t
         */
        register_t      ktr_args[1];
};

/*
 * KTR_SYSRET - return from system call record
 */
#define KTR_SYSRET      2
struct ktr_sysret {
        short   ktr_code;
        short   ktr_eosys;
        int     ktr_error;
        register_t      ktr_retval;
};

/*
 * KTR_NAMEI - namei record
 */
#define KTR_NAMEI       3
        /* record contains pathname */

/*
 * KTR_GENIO - trace generic process i/o
 */
#define KTR_GENIO       4
struct ktr_genio {
        int     ktr_fd;
        enum    uio_rw ktr_rw;
        /*
         * followed by data successfully read/written
         */
};

/*
 * KTR_PSIG - trace processed signal
 */
#define KTR_PSIG        5
struct ktr_psig {
        int     signo;
        sig_t   action;
        int     code;
        sigset_t mask;
};

/*
 * KTR_CSW - trace context switches
 */
#define KTR_CSW         6
struct ktr_csw_old {
        int     out;    /* 1 if switch out, 0 if switch in */
        int     user;   /* 1 if usermode (ivcsw), 0 if kernel (vcsw) */
};

struct ktr_csw {
        int     out;    /* 1 if switch out, 0 if switch in */
        int     user;   /* 1 if usermode (ivcsw), 0 if kernel (vcsw) */
        char    wmesg[8];
};

/*
 * KTR_USER - data coming from userland
 */
#define KTR_USER_MAXLEN 2048    /* maximum length of passed data */
#define KTR_USER        7

/*
 * KTR_STRUCT - misc. structs
 */
#define KTR_STRUCT      8
        /*
         * record contains null-terminated struct name followed by
         * struct contents
         */
struct sockaddr;
struct stat;
struct sysentvec;

/*
 * KTR_SYSCTL - name of a sysctl MIB
 */
#define KTR_SYSCTL      9
        /* record contains null-terminated MIB name */

/*
 * KTR_PROCCTOR - trace process creation (multiple ABI support)
 */
#define KTR_PROCCTOR    10
struct ktr_proc_ctor {
        u_int   sv_flags;       /* struct sysentvec sv_flags copy */
};

/*
 * KTR_PROCDTOR - trace process destruction (multiple ABI support)
 */
#define KTR_PROCDTOR    11

/*
 * KTR_CAPFAIL - trace capability check failures
 */
#define KTR_CAPFAIL     12
enum ktr_cap_violation {
        CAPFAIL_NOTCAPABLE,     /* insufficient capabilities in cap_check() */
        CAPFAIL_INCREASE,       /* attempt to increase rights on a capability */
        CAPFAIL_SYSCALL,        /* disallowed system call */
        CAPFAIL_SIGNAL,         /* sent signal to process other than self */
        CAPFAIL_PROTO,          /* disallowed protocol */
        CAPFAIL_SOCKADDR,       /* restricted address lookup */
        CAPFAIL_NAMEI,          /* restricted namei lookup */
        CAPFAIL_CPUSET,         /* restricted CPU set modification */
};

union ktr_cap_data {
        cap_rights_t    cap_rights[2];
#define cap_needed      cap_rights[0]
#define cap_held        cap_rights[1]
        int             cap_int;
        struct sockaddr cap_sockaddr;
        char            cap_path[MAXPATHLEN];
};

struct ktr_cap_fail {
        enum ktr_cap_violation cap_type;
        short   cap_code;
        u_int   cap_svflags;
        union ktr_cap_data cap_data;
};

/*
 * KTR_FAULT - page fault record
 */
#define KTR_FAULT       13
struct ktr_fault {
        vm_offset_t vaddr;
        int type;
};

/*
 * KTR_FAULTEND - end of page fault record
 */
#define KTR_FAULTEND    14
struct ktr_faultend {
        int result;
};

/*
 * KTR_STRUCT_ARRAY - array of misc. structs
 */
#define KTR_STRUCT_ARRAY 15
struct ktr_struct_array {
        size_t struct_size;
        /*
         * Followed by null-terminated structure name and then payload
         * contents.
         */
};

/*
 * KTR_ARGS - arguments of execve()
 */
#define KTR_ARGS 16

/*
 * KTR_ENVS - environment variables of execve()
 */
#define KTR_ENVS 17

/*
 * KTR_EXTERR - extended error reported
 */
#define KTR_EXTERR 18
struct ktr_exterr {
        struct uexterror ue;
};

/*
 * KTR_DROP - If this bit is set in ktr_type, then at least one event
 * between the previous record and this record was dropped.
 */
#define KTR_DROP        0x8000
/*
 * KTR_VERSIONED - If this bit is set in ktr_type, then the kernel
 * exposes the new struct ktr_header (versioned), otherwise the old
 * struct ktr_header_v0 is exposed.
 */
#define KTR_VERSIONED   0x4000
#define KTR_TYPE        (KTR_DROP | KTR_VERSIONED)

/*
 * kernel trace points (in p_traceflag)
 */
#define KTRFAC_MASK     0x00ffffff
#define KTRFAC_SYSCALL  (1<<KTR_SYSCALL)
#define KTRFAC_SYSRET   (1<<KTR_SYSRET)
#define KTRFAC_NAMEI    (1<<KTR_NAMEI)
#define KTRFAC_GENIO    (1<<KTR_GENIO)
#define KTRFAC_PSIG     (1<<KTR_PSIG)
#define KTRFAC_CSW      (1<<KTR_CSW)
#define KTRFAC_USER     (1<<KTR_USER)
#define KTRFAC_STRUCT   (1<<KTR_STRUCT)
#define KTRFAC_SYSCTL   (1<<KTR_SYSCTL)
#define KTRFAC_PROCCTOR (1<<KTR_PROCCTOR)
#define KTRFAC_PROCDTOR (1<<KTR_PROCDTOR)
#define KTRFAC_CAPFAIL  (1<<KTR_CAPFAIL)
#define KTRFAC_FAULT    (1<<KTR_FAULT)
#define KTRFAC_FAULTEND (1<<KTR_FAULTEND)
#define KTRFAC_STRUCT_ARRAY (1<<KTR_STRUCT_ARRAY)
#define KTRFAC_ARGS     (1<<KTR_ARGS)
#define KTRFAC_ENVS     (1<<KTR_ENVS)
#define KTRFAC_EXTERR   (1<<KTR_EXTERR)

/*
 * trace flags (also in p_traceflags)
 */
#define KTRFAC_ROOT     0x80000000      /* root set this trace */
#define KTRFAC_INHERIT  0x40000000      /* pass trace flags to children */
#define KTRFAC_DROP     0x20000000      /* last event was dropped */

#ifdef  _KERNEL
struct ktr_io_params;

#ifdef  KTRACE
struct vnode *ktr_get_tracevp(struct proc *, bool);
#else
static inline struct vnode *
ktr_get_tracevp(struct proc *p, bool ref)
{

        return (NULL);
}
#endif
void    ktr_io_params_free(struct ktr_io_params *);
void    ktrnamei(const char *);
void    ktrcsw(int, int, const char *);
void    ktrcsw_out(const struct timespec *, const char *);
void    ktrpsig(int, sig_t, sigset_t *, int);
void    ktrfault(vm_offset_t, int);
void    ktrfaultend(int);
void    ktrgenio(int, enum uio_rw, struct uio *, int);
void    ktrsyscall(int, int narg, syscallarg_t args[]);
void    ktrsysctl(int *name, u_int namelen);
void    ktrsysret(int, int, register_t);
void    ktrprocctor(struct proc *);
struct ktr_io_params *ktrprocexec(struct proc *);
void    ktrprocexit(struct thread *);
void    ktrprocfork(struct proc *, struct proc *);
void    ktruserret(struct thread *);
void    ktrstruct(const char *, const void *, size_t);
void    ktrstruct_error(const char *, const void *, size_t, int);
void    ktrstructarray(const char *, enum uio_seg, const void *, int, size_t);
void    ktrcapfail(enum ktr_cap_violation, const void *);
void    ktrdata(int, const void *, size_t);
#define ktrcaprights(s) \
        ktrstruct("caprights", (s), sizeof(cap_rights_t))
#define ktritimerval(s) \
        ktrstruct("itimerval", (s), sizeof(struct itimerval))
#define ktrsockaddr(s) \
        ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len)
#define ktrstat(s) \
        ktrstruct("stat", (s), sizeof(struct stat))
#define ktrstat_error(s, error) \
        ktrstruct_error("stat", (s), sizeof(struct stat), error)
#define ktrcpuset(s, l) \
        ktrstruct("cpuset_t", (s), l)
#define ktrsplice(s) \
        ktrstruct("splice", (s), sizeof(struct splice))
#define ktrthrparam(s) \
        ktrstruct("thrparam", (s), sizeof(struct thr_param))
extern u_int ktr_geniosize;
#ifdef  KTRACE
extern int ktr_filesize_limit_signal;
#define __ktrace_used
#else
#define ktr_filesize_limit_signal 0
#define __ktrace_used   __unused
#endif
#else

#include <sys/cdefs.h>

__BEGIN_DECLS
int     ktrace(const char *, int, int, pid_t);
int     utrace(const void *, size_t);
__END_DECLS

#endif

#endif