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