4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <sys/varargs.h>
45 fprintf(stderr, "%s: ", "baddof");
46 vfprintf(stderr, fmt, ap);
48 if (fmt[strlen(fmt) - 1] != '\n')
49 fprintf(stderr, ": %s\n", strerror(errno));
54 #define LEAP_DISTANCE 20
57 corrupt(int fd, unsigned char *buf, int len)
59 static int ttl, valid;
62 int val[LEAP_DISTANCE], pos[LEAP_DISTANCE];
66 printf("valid DOF #%d\n", valid++);
69 * We are going iterate through, flipping one bit and attempting
72 for (bit = 0; bit < len * 8; bit++) {
74 buf[bit / 8] ^= (1 << (bit % 8));
79 if ((rv = ioctl(fd, DTRACEIOC_ENABLE, buf)) == -1) {
81 * That failed -- restore the bit and drive on.
88 * That worked -- and it may have enabled probes. To keep
89 * enabled probes down to a reasonable level, we'll close
90 * and reopen pseudodevice if we have more than 10,000
100 printf("enabled %d probes; resetting device.\n", ttl);
103 new = open("/devices/pseudo/dtrace@0:dtrace", O_RDWR);
106 fatal("couldn't open DTrace pseudo device");
114 buf[bit / 8] = saved;
119 * Now we want to get as many bits away as possible. We flip
120 * bits randomly -- getting as far away as we can until we don't
121 * seem to be making any progress.
123 for (i = 0; i < LEAP_DISTANCE; i++) {
125 * Pick a random bit and corrupt it.
127 bit = lrand48() % (len * 8);
129 val[i] = buf[bit / 8];
131 buf[bit / 8] ^= (1 << (bit % 8));
135 * Let's see if that managed to get us valid DOF...
137 if ((rv = ioctl(fd, DTRACEIOC_ENABLE, buf)) > 0) {
139 * Success! This will be our new base for valid DOF.
146 * No luck -- we'll restore those bits and try flipping a
147 * different set. Note that this must be done in reverse
150 for (i = LEAP_DISTANCE - 1; i >= 0; i--)
151 buf[pos[i]] = val[i];
156 main(int argc, char **argv)
158 char *filename = argv[1];
163 unsigned char *dof, *copy;
166 fatal("expected D script as argument\n");
168 if ((fp = fopen(filename, "r")) == NULL)
169 fatal("couldn't open %s", filename);
172 * First, we need to compile our provided D into DOF.
174 if ((dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) {
175 fatal("cannot open dtrace library: %s\n",
176 dtrace_errmsg(NULL, err));
179 pgp = dtrace_program_fcompile(dtp, fp, 0, 0, NULL);
183 fatal("failed to compile script %s: %s\n", filename,
184 dtrace_errmsg(dtp, dtrace_errno(dtp)));
187 dof = dtrace_dof_create(dtp, pgp, 0);
188 len = ((dof_hdr_t *)dof)->dofh_loadsz;
190 if ((copy = malloc(len)) == NULL)
191 fatal("could not allocate copy of %d bytes", len);
194 bcopy(dof, copy, len);
196 * Open another instance of the dtrace device.
198 fd = open("/devices/pseudo/dtrace@0:dtrace", O_RDWR);
201 fatal("couldn't open DTrace pseudo device");
203 corrupt(fd, copy, len);