1*8d741a5dSApple OSS Distributions /* quick and dirty hack to grab credential backtrace info from kernel via sysctl.
2*8d741a5dSApple OSS Distributions * sysctl is only defined if xnu is built with DEBUG_CRED defined.
3*8d741a5dSApple OSS Distributions * The current version of this is used to target a specific credential and gather
4*8d741a5dSApple OSS Distributions * backtrace info on all references and unreferences.
5*8d741a5dSApple OSS Distributions */
6*8d741a5dSApple OSS Distributions
7*8d741a5dSApple OSS Distributions #include <stdio.h>
8*8d741a5dSApple OSS Distributions #include <stdlib.h>
9*8d741a5dSApple OSS Distributions #include <fcntl.h>
10*8d741a5dSApple OSS Distributions #include <limits.h>
11*8d741a5dSApple OSS Distributions #include <string.h>
12*8d741a5dSApple OSS Distributions #include <errno.h>
13*8d741a5dSApple OSS Distributions #include <unistd.h>
14*8d741a5dSApple OSS Distributions #include <sys/stat.h>
15*8d741a5dSApple OSS Distributions #include <sys/types.h>
16*8d741a5dSApple OSS Distributions #include <sys/sysctl.h>
17*8d741a5dSApple OSS Distributions #include <bsm/audit.h>
18*8d741a5dSApple OSS Distributions
19*8d741a5dSApple OSS Distributions /* bad! this is replicated in kern_credential.c. make sure they stay in sync!
20*8d741a5dSApple OSS Distributions * Or better yet have commone header file?
21*8d741a5dSApple OSS Distributions */
22*8d741a5dSApple OSS Distributions #define MAX_STACK_DEPTH 8
23*8d741a5dSApple OSS Distributions struct cred_backtrace {
24*8d741a5dSApple OSS Distributions int depth;
25*8d741a5dSApple OSS Distributions uint32_t stack[MAX_STACK_DEPTH];
26*8d741a5dSApple OSS Distributions };
27*8d741a5dSApple OSS Distributions typedef struct cred_backtrace cred_backtrace;
28*8d741a5dSApple OSS Distributions
29*8d741a5dSApple OSS Distributions struct cred_debug_buffer {
30*8d741a5dSApple OSS Distributions int next_slot;
31*8d741a5dSApple OSS Distributions cred_backtrace stack_buffer[1];
32*8d741a5dSApple OSS Distributions };
33*8d741a5dSApple OSS Distributions typedef struct cred_debug_buffer cred_debug_buffer;
34*8d741a5dSApple OSS Distributions
35*8d741a5dSApple OSS Distributions
main(int argc,char * argv[])36*8d741a5dSApple OSS Distributions main( int argc, char *argv[] )
37*8d741a5dSApple OSS Distributions {
38*8d741a5dSApple OSS Distributions int err, i, j;
39*8d741a5dSApple OSS Distributions size_t len;
40*8d741a5dSApple OSS Distributions char *my_bufferp = NULL;
41*8d741a5dSApple OSS Distributions cred_debug_buffer *bt_buffp;
42*8d741a5dSApple OSS Distributions cred_backtrace *btp;
43*8d741a5dSApple OSS Distributions
44*8d741a5dSApple OSS Distributions /* get size of buffer we will need */
45*8d741a5dSApple OSS Distributions len = 0;
46*8d741a5dSApple OSS Distributions err = sysctlbyname( "kern.cred_bt", NULL, &len, NULL, 0 );
47*8d741a5dSApple OSS Distributions if (err != 0) {
48*8d741a5dSApple OSS Distributions printf( "sysctl failed \n" );
49*8d741a5dSApple OSS Distributions printf( "\terrno %d - \"%s\" \n", errno, strerror( errno ));
50*8d741a5dSApple OSS Distributions return;
51*8d741a5dSApple OSS Distributions }
52*8d741a5dSApple OSS Distributions
53*8d741a5dSApple OSS Distributions /* get a buffer for our back traces */
54*8d741a5dSApple OSS Distributions my_bufferp = malloc( len );
55*8d741a5dSApple OSS Distributions if (my_bufferp == NULL) {
56*8d741a5dSApple OSS Distributions printf( "malloc error %d - \"%s\" \n", errno, strerror( errno ));
57*8d741a5dSApple OSS Distributions return;
58*8d741a5dSApple OSS Distributions }
59*8d741a5dSApple OSS Distributions err = sysctlbyname( "kern.cred_bt", my_bufferp, &len, NULL, 0 );
60*8d741a5dSApple OSS Distributions if (err != 0) {
61*8d741a5dSApple OSS Distributions printf( "sysctl 2 failed \n" );
62*8d741a5dSApple OSS Distributions printf( "\terrno %d - \"%s\" \n", errno, strerror( errno ));
63*8d741a5dSApple OSS Distributions return;
64*8d741a5dSApple OSS Distributions }
65*8d741a5dSApple OSS Distributions
66*8d741a5dSApple OSS Distributions bt_buffp = (cred_debug_buffer *) my_bufferp;
67*8d741a5dSApple OSS Distributions btp = &bt_buffp->stack_buffer[0];
68*8d741a5dSApple OSS Distributions
69*8d741a5dSApple OSS Distributions printf("number of traces %d \n", bt_buffp->next_slot);
70*8d741a5dSApple OSS Distributions for (i = 0; i < bt_buffp->next_slot; i++, btp++) {
71*8d741a5dSApple OSS Distributions printf("[%d] ", i);
72*8d741a5dSApple OSS Distributions for (j = 0; j < btp->depth; j++) {
73*8d741a5dSApple OSS Distributions printf("%p ", btp->stack[j]);
74*8d741a5dSApple OSS Distributions }
75*8d741a5dSApple OSS Distributions printf("\n");
76*8d741a5dSApple OSS Distributions }
77*8d741a5dSApple OSS Distributions
78*8d741a5dSApple OSS Distributions return;
79*8d741a5dSApple OSS Distributions }
80