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 23struct cred_backtrace { 24 int depth; 25 uint32_t stack[ MAX_STACK_DEPTH ]; 26}; 27typedef struct cred_backtrace cred_backtrace; 28 29struct cred_debug_buffer { 30 int next_slot; 31 cred_backtrace stack_buffer[ 1 ]; 32}; 33typedef struct cred_debug_buffer cred_debug_buffer; 34 35 36main( 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 81