Annotation of src/usr.bin/ktrace/ktrace.c, Revision 1.38
1.38 ! deraadt 1: /* $OpenBSD: ktrace.c,v 1.37 2020/07/16 17:47:41 tedu Exp $ */
1.1 deraadt 2: /* $NetBSD: ktrace.c,v 1.4 1995/08/31 23:01:44 jtc Exp $ */
3:
4: /*-
5: * Copyright (c) 1988, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
1.16 millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
1.31 deraadt 33: #include <sys/param.h> /* MAXCOMLEN */
1.38 ! deraadt 34: #include <sys/types.h>
1.31 deraadt 35: #include <sys/signal.h>
1.1 deraadt 36: #include <sys/stat.h>
37: #include <sys/time.h>
38: #include <sys/uio.h>
39: #include <sys/ktrace.h>
40:
41: #include <err.h>
1.19 millert 42: #include <errno.h>
1.8 millert 43: #include <fcntl.h>
1.10 deraadt 44: #include <stdlib.h>
1.38 ! deraadt 45: #include <limits.h>
1.1 deraadt 46: #include <stdio.h>
1.14 deraadt 47: #include <string.h>
1.1 deraadt 48: #include <unistd.h>
49:
50: #include "ktrace.h"
1.11 espie 51: #include "extern.h"
1.1 deraadt 52:
1.25 miod 53: extern char *__progname;
54:
1.13 millert 55: static int rpid(const char *);
56: static void no_ktrace(int);
57: static void usage(void);
1.1 deraadt 58:
1.25 miod 59: int is_ltrace;
60:
1.10 deraadt 61: int
1.17 deraadt 62: main(int argc, char *argv[])
1.1 deraadt 63: {
64: enum { NOTSET, CLEAR, CLEARALL } clear;
1.10 deraadt 65: int append, ch, fd, inherit, ops, pidset, trpoints;
66: pid_t pid;
1.25 miod 67: char *tracefile, *tracespec;
1.3 deraadt 68: mode_t omask;
1.6 angelos 69: struct stat sb;
1.1 deraadt 70:
1.25 miod 71: is_ltrace = strcmp(__progname, "ltrace") == 0;
72:
1.1 deraadt 73: clear = NOTSET;
1.21 tedu 74: append = ops = pidset = inherit = pid = 0;
1.25 miod 75: trpoints = is_ltrace ? KTRFAC_USER : DEF_POINTS;
1.1 deraadt 76: tracefile = DEF_TRACEFILE;
1.25 miod 77: tracespec = NULL;
78:
79: if (is_ltrace) {
1.28 miod 80: while ((ch = getopt(argc, argv, "af:it:u:")) != -1)
1.25 miod 81: switch ((char)ch) {
82: case 'a':
83: append = 1;
84: break;
85: case 'f':
86: tracefile = optarg;
87: break;
88: case 'i':
89: inherit = 1;
1.28 miod 90: break;
91: case 't':
1.33 guenther 92: trpoints = getpoints(optarg, KTRFAC_USER);
1.28 miod 93: if (trpoints < 0) {
94: warnx("unknown facility in %s", optarg);
95: usage();
96: }
1.25 miod 97: break;
98: case 'u':
99: tracespec = optarg;
100: break;
101: default:
102: usage();
103: }
104: } else {
1.37 tedu 105: while ((ch = getopt(argc, argv, "aBCcdf:g:ip:t:T")) != -1)
1.25 miod 106: switch ((char)ch) {
107: case 'a':
108: append = 1;
109: break;
110: case 'B':
111: putenv("LD_BIND_NOW=");
112: break;
113: case 'C':
114: clear = CLEARALL;
1.35 tedu 115: tracefile = NULL;
1.25 miod 116: pidset = 1;
117: break;
118: case 'c':
119: clear = CLEAR;
120: break;
121: case 'd':
122: ops |= KTRFLAG_DESCEND;
123: break;
124: case 'f':
125: tracefile = optarg;
126: break;
127: case 'g':
128: pid = -rpid(optarg);
129: pidset = 1;
130: break;
131: case 'i':
132: inherit = 1;
133: break;
134: case 'p':
135: pid = rpid(optarg);
136: pidset = 1;
137: break;
138: case 't':
1.33 guenther 139: trpoints = getpoints(optarg, DEF_POINTS);
1.25 miod 140: if (trpoints < 0) {
141: warnx("unknown facility in %s", optarg);
142: usage();
143: }
144: break;
1.37 tedu 145: case 'T':
146: putenv("LIBC_NOUSERTC=");
147: break;
1.25 miod 148: default:
1.1 deraadt 149: usage();
150: }
1.25 miod 151: }
152:
1.1 deraadt 153: argv += optind;
154: argc -= optind;
155:
1.15 deraadt 156: if ((pidset && *argv) || (!pidset && !*argv && clear != CLEAR))
1.1 deraadt 157: usage();
1.25 miod 158:
1.1 deraadt 159: if (inherit)
160: trpoints |= KTRFAC_INHERIT;
161:
162: (void)signal(SIGSYS, no_ktrace);
163: if (clear != NOTSET) {
164: if (clear == CLEARALL) {
165: ops = KTROP_CLEAR | KTRFLAG_DESCEND;
166: trpoints = ALL_POINTS;
167: pid = 1;
168: } else
169: ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
170:
1.36 deraadt 171: if (ktrace(tracefile, ops, trpoints, pid) == -1) {
1.30 deraadt 172: if (errno == ESRCH)
173: err(1, "%d", pid);
1.9 millert 174: err(1, "%s", tracefile);
1.30 deraadt 175: }
1.1 deraadt 176: exit(0);
177: }
178:
1.3 deraadt 179: omask = umask(S_IRWXG|S_IRWXO);
1.5 deraadt 180: if (append) {
1.36 deraadt 181: if ((fd = open(tracefile, O_CREAT | O_WRONLY, DEFFILEMODE)) == -1)
1.9 millert 182: err(1, "%s", tracefile);
1.5 deraadt 183: if (fstat(fd, &sb) != 0 || sb.st_uid != getuid())
184: errx(1, "Refuse to append to %s: not owned by you.",
185: tracefile);
186: } else {
187: if (unlink(tracefile) == -1 && errno != ENOENT)
188: err(1, "unlink %s", tracefile);
189: if ((fd = open(tracefile, O_CREAT | O_EXCL | O_WRONLY,
1.36 deraadt 190: DEFFILEMODE)) == -1)
1.9 millert 191: err(1, "%s", tracefile);
1.5 deraadt 192: }
1.3 deraadt 193: (void)umask(omask);
1.1 deraadt 194: (void)close(fd);
195:
196: if (*argv) {
1.25 miod 197: if (is_ltrace) {
198: if (setenv("LD_TRACE_PLT", inherit ? "i" : "", 1) < 0)
199: err(1, "setenv(LD_TRACE_PLT)");
200: if (tracespec &&
201: setenv("LD_TRACE_PLTSPEC", tracespec, 1) < 0)
202: err(1, "setenv(LD_TRACE_PLTSPEC)");
203: }
1.36 deraadt 204: if (ktrace(tracefile, ops, trpoints, getpid()) == -1)
1.9 millert 205: err(1, "%s", tracefile);
1.1 deraadt 206: execvp(argv[0], &argv[0]);
207: err(1, "exec of '%s' failed", argv[0]);
208: }
1.36 deraadt 209: else if (ktrace(tracefile, ops, trpoints, pid) == -1) {
1.30 deraadt 210: if (errno == ESRCH)
211: err(1, "%d", pid);
1.9 millert 212: err(1, "%s", tracefile);
1.30 deraadt 213: }
1.1 deraadt 214: exit(0);
215: }
216:
1.11 espie 217: static int
1.17 deraadt 218: rpid(const char *p)
1.1 deraadt 219: {
1.32 deraadt 220: const char *errstr;
1.1 deraadt 221: static int first;
1.32 deraadt 222: pid_t pid;
1.1 deraadt 223:
224: if (first++) {
225: warnx("only one -g or -p flag is permitted.");
226: usage();
227: }
228: if (!*p) {
229: warnx("illegal process id.");
230: usage();
231: }
1.32 deraadt 232: pid = strtonum(p, 1, INT_MAX, &errstr);
233: if (errstr) {
234: warnx("illegal process id: %s", errstr);
235: usage();
236: }
237: return pid;
1.1 deraadt 238: }
239:
1.11 espie 240: static void
1.17 deraadt 241: usage(void)
1.1 deraadt 242: {
1.25 miod 243: if (is_ltrace)
1.29 jmc 244: fprintf(stderr, "usage: %s [-ai] [-f trfile] [-t trstr]"
245: " [-u trspec] command\n",
1.25 miod 246: __progname);
247: else
1.37 tedu 248: fprintf(stderr, "usage: %s [-aCcdi] [-f trfile] [-g pgid]"
1.25 miod 249: " [-p pid] [-t trstr]\n"
1.37 tedu 250: " %s [-aBdiT] [-f trfile] [-t trstr] command\n",
1.25 miod 251: __progname, __progname);
1.1 deraadt 252: exit(1);
253: }
254:
1.18 deraadt 255: /* ARGSUSED */
1.11 espie 256: static void
1.17 deraadt 257: no_ktrace(int signo)
1.1 deraadt 258: {
1.34 awolk 259: dprintf(STDERR_FILENO,
1.15 deraadt 260: "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'option KTRACE'\n");
1.12 deraadt 261: _exit(1);
1.1 deraadt 262: }