Annotation of src/usr.bin/ktrace/ktrace.c, Revision 1.29
1.29 ! jmc 1: /* $OpenBSD: ktrace.c,v 1.28 2014/04/04 21:34:47 miod 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:
33: #include <sys/param.h>
34: #include <sys/stat.h>
35: #include <sys/time.h>
36: #include <sys/uio.h>
37: #include <sys/ktrace.h>
38:
39: #include <err.h>
1.19 millert 40: #include <errno.h>
1.8 millert 41: #include <fcntl.h>
1.10 deraadt 42: #include <stdlib.h>
1.1 deraadt 43: #include <stdio.h>
1.14 deraadt 44: #include <string.h>
1.1 deraadt 45: #include <unistd.h>
46:
47: #include "ktrace.h"
1.11 espie 48: #include "extern.h"
1.1 deraadt 49:
1.25 miod 50: extern char *__progname;
51:
1.13 millert 52: static int rpid(const char *);
53: static void no_ktrace(int);
54: static void usage(void);
1.1 deraadt 55:
1.25 miod 56: int is_ltrace;
57:
1.10 deraadt 58: int
1.17 deraadt 59: main(int argc, char *argv[])
1.1 deraadt 60: {
61: enum { NOTSET, CLEAR, CLEARALL } clear;
1.10 deraadt 62: int append, ch, fd, inherit, ops, pidset, trpoints;
63: pid_t pid;
1.25 miod 64: char *tracefile, *tracespec;
1.3 deraadt 65: mode_t omask;
1.6 angelos 66: struct stat sb;
1.1 deraadt 67:
1.25 miod 68: is_ltrace = strcmp(__progname, "ltrace") == 0;
69:
1.1 deraadt 70: clear = NOTSET;
1.21 tedu 71: append = ops = pidset = inherit = pid = 0;
1.25 miod 72: trpoints = is_ltrace ? KTRFAC_USER : DEF_POINTS;
1.1 deraadt 73: tracefile = DEF_TRACEFILE;
1.25 miod 74: tracespec = NULL;
75:
76: if (is_ltrace) {
1.28 miod 77: while ((ch = getopt(argc, argv, "af:it:u:")) != -1)
1.25 miod 78: switch ((char)ch) {
79: case 'a':
80: append = 1;
81: break;
82: case 'f':
83: tracefile = optarg;
84: break;
85: case 'i':
86: inherit = 1;
1.28 miod 87: break;
88: case 't':
89: trpoints = getpoints(optarg);
90: if (trpoints < 0) {
91: warnx("unknown facility in %s", optarg);
92: usage();
93: }
1.25 miod 94: break;
95: case 'u':
96: tracespec = optarg;
97: break;
98: default:
99: usage();
100: }
101: } else {
102: while ((ch = getopt(argc, argv, "aBCcdf:g:ip:t:")) != -1)
103: switch ((char)ch) {
104: case 'a':
105: append = 1;
106: break;
107: case 'B':
108: putenv("LD_BIND_NOW=");
109: break;
110: case 'C':
111: clear = CLEARALL;
112: pidset = 1;
113: break;
114: case 'c':
115: clear = CLEAR;
116: break;
117: case 'd':
118: ops |= KTRFLAG_DESCEND;
119: break;
120: case 'f':
121: tracefile = optarg;
122: break;
123: case 'g':
124: pid = -rpid(optarg);
125: pidset = 1;
126: break;
127: case 'i':
128: inherit = 1;
129: break;
130: case 'p':
131: pid = rpid(optarg);
132: pidset = 1;
133: break;
134: case 't':
135: trpoints = getpoints(optarg);
136: if (trpoints < 0) {
137: warnx("unknown facility in %s", optarg);
138: usage();
139: }
140: break;
141: default:
1.1 deraadt 142: usage();
143: }
1.25 miod 144: }
145:
1.1 deraadt 146: argv += optind;
147: argc -= optind;
148:
1.15 deraadt 149: if ((pidset && *argv) || (!pidset && !*argv && clear != CLEAR))
1.1 deraadt 150: usage();
1.25 miod 151:
1.1 deraadt 152: if (inherit)
153: trpoints |= KTRFAC_INHERIT;
154:
155: (void)signal(SIGSYS, no_ktrace);
156: if (clear != NOTSET) {
157: if (clear == CLEARALL) {
158: ops = KTROP_CLEAR | KTRFLAG_DESCEND;
159: trpoints = ALL_POINTS;
160: pid = 1;
161: } else
162: ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
163:
164: if (ktrace(tracefile, ops, trpoints, pid) < 0)
1.9 millert 165: err(1, "%s", tracefile);
1.1 deraadt 166: exit(0);
167: }
168:
1.3 deraadt 169: omask = umask(S_IRWXG|S_IRWXO);
1.5 deraadt 170: if (append) {
171: if ((fd = open(tracefile, O_CREAT | O_WRONLY, DEFFILEMODE)) < 0)
1.9 millert 172: err(1, "%s", tracefile);
1.5 deraadt 173: if (fstat(fd, &sb) != 0 || sb.st_uid != getuid())
174: errx(1, "Refuse to append to %s: not owned by you.",
175: tracefile);
176: } else {
177: if (unlink(tracefile) == -1 && errno != ENOENT)
178: err(1, "unlink %s", tracefile);
179: if ((fd = open(tracefile, O_CREAT | O_EXCL | O_WRONLY,
180: DEFFILEMODE)) < 0)
1.9 millert 181: err(1, "%s", tracefile);
1.5 deraadt 182: }
1.3 deraadt 183: (void)umask(omask);
1.1 deraadt 184: (void)close(fd);
185:
186: if (*argv) {
1.25 miod 187: if (is_ltrace) {
188: if (setenv("LD_TRACE_PLT", inherit ? "i" : "", 1) < 0)
189: err(1, "setenv(LD_TRACE_PLT)");
190: if (tracespec &&
191: setenv("LD_TRACE_PLTSPEC", tracespec, 1) < 0)
192: err(1, "setenv(LD_TRACE_PLTSPEC)");
193: }
1.1 deraadt 194: if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
1.9 millert 195: err(1, "%s", tracefile);
1.1 deraadt 196: execvp(argv[0], &argv[0]);
197: err(1, "exec of '%s' failed", argv[0]);
198: }
199: else if (ktrace(tracefile, ops, trpoints, pid) < 0)
1.9 millert 200: err(1, "%s", tracefile);
1.1 deraadt 201: exit(0);
202: }
203:
1.11 espie 204: static int
1.17 deraadt 205: rpid(const char *p)
1.1 deraadt 206: {
207: static int first;
208:
209: if (first++) {
210: warnx("only one -g or -p flag is permitted.");
211: usage();
212: }
213: if (!*p) {
214: warnx("illegal process id.");
215: usage();
216: }
217: return(atoi(p));
218: }
219:
1.11 espie 220: static void
1.17 deraadt 221: usage(void)
1.1 deraadt 222: {
1.25 miod 223: if (is_ltrace)
1.29 ! jmc 224: fprintf(stderr, "usage: %s [-ai] [-f trfile] [-t trstr]"
! 225: " [-u trspec] command\n",
1.25 miod 226: __progname);
227: else
228: fprintf(stderr, "usage: %s [-aBCcdi] [-f trfile] [-g pgid]"
229: " [-p pid] [-t trstr]\n"
230: " %s [-adi] [-f trfile] [-t trstr] command\n",
231: __progname, __progname);
1.1 deraadt 232: exit(1);
233: }
234:
1.18 deraadt 235: /* ARGSUSED */
1.11 espie 236: static void
1.17 deraadt 237: no_ktrace(int signo)
1.1 deraadt 238: {
1.12 deraadt 239: char buf[8192];
240:
241: snprintf(buf, sizeof(buf),
1.15 deraadt 242: "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'option KTRACE'\n");
1.12 deraadt 243: write(STDERR_FILENO, buf, strlen(buf));
244: _exit(1);
1.1 deraadt 245: }