1#import <stdint.h> 2#import <bsm/libbsm.h> 3#import <System/sys/codesign.h> 4#import <sys/errno.h> 5 6#import <err.h> 7#import <stdio.h> 8#import <unistd.h> 9 10int 11get_blob(pid_t pid, int op) 12{ 13 uint8_t header[8]; 14 unsigned int cnt; 15 int rcent; 16 17 for (cnt = 0; cnt < sizeof(header); cnt++) { 18 rcent = csops(pid, op, header, 1); 19 if (rcent != -1 && errno != ERANGE) 20 err(1, "errno != ERANGE for short header"); 21 } 22 23 rcent = csops(pid, op, header, sizeof(header)); 24 if (rcent == -1 && errno == ERANGE) { 25 uint32_t len, bufferlen, bufferlen2; 26 27 memcpy(&len, &header[4], 4); 28 bufferlen = ntohl(len); 29 if (bufferlen > 1024 * 1024) 30 errx(1, "invalid length on blob from kernel"); 31 else if (bufferlen == 0) 32 errx(1, "bufferlen == 0"); 33 else if (bufferlen < 8) 34 errx(1, "bufferlen <8 0"); 35 36 uint8_t buffer[bufferlen + 1]; 37 38 rcent = csops(pid, op, buffer, bufferlen - 1); 39 if (rcent != -1 && errno != ERANGE) 40 errx(1, "csops with full buffer - 1 failed"); 41 42 rcent = csops(pid, op, buffer, bufferlen); 43 if (rcent != 0) 44 errx(1, "csops with full buffer failed"); 45 46 memcpy(&len, &buffer[4], 4); 47 bufferlen2 = ntohl(len); 48 49 if (op == CS_OPS_BLOB) { 50 if (bufferlen2 > bufferlen) 51 errx(1, "buffer larger on second try"); 52 if (bufferlen2 != bufferlen) 53 warnx("buffer shrunk since codesign can't tell the right size to codesign_allocate"); 54 } else { 55 if (bufferlen2 != bufferlen) 56 errx(1, "buffer sizes different"); 57 } 58 59 rcent = csops(pid, op, buffer, bufferlen + 1); 60 if (rcent != 0) 61 errx(1, "csops with full buffer + 1 didn't pass"); 62 63 return 0; 64 65 } else if (rcent == 0) { 66 return 0; 67 } else { 68 return 1; 69 } 70} 71 72int 73main(int argc, const char * argv[]) 74{ 75 uint32_t status; 76 int rcent; 77 pid_t pid; 78 79 pid = getpid(); 80 81 if (get_blob(pid, CS_OPS_ENTITLEMENTS_BLOB)) 82 errx(1, "failed to get entitlements"); 83 84 if (get_blob(0, CS_OPS_ENTITLEMENTS_BLOB)) 85 errx(1, "failed to get entitlements"); 86 87 if (get_blob(pid, CS_OPS_BLOB)) 88 errx(1, "failed to get blob"); 89 90 if (get_blob(0, CS_OPS_BLOB)) 91 errx(1, "failed to get blob"); 92 93 if (get_blob(pid, CS_OPS_IDENTITY)) 94 errx(1, "failed to get identity"); 95 96 if (get_blob(0, CS_OPS_IDENTITY)) 97 errx(1, "failed to get identity"); 98 99 rcent = csops(pid, CS_OPS_SET_STATUS, &status, sizeof(status) - 1); 100 if (rcent == 0) 101 err(1, "passed when passed in too short status buffer"); 102 103 status = htonl(CS_RESTRICT); 104 rcent = csops(pid, CS_OPS_SET_STATUS, &status, sizeof(status)); 105 if (rcent != 0) 106 errx(1, "failed to mark proc RESTRICTED"); 107 108 rcent = csops(pid, CS_OPS_MARKINVALID, NULL, 0); 109 if (rcent != 0) 110 errx(1, "failed to mark proc invalid"); 111 112 status = htonl(CS_VALID); 113 rcent = csops(pid, CS_OPS_SET_STATUS, &status, sizeof(status)); 114 if (rcent == 0) 115 errx(1, "managed set flags on an INVALID proc"); 116 117 if (!get_blob(pid, CS_OPS_ENTITLEMENTS_BLOB)) 118 errx(1, "got entitlements while invalid"); 119 120 if (!get_blob(pid, CS_OPS_IDENTITY)) 121 errx(1, "got identity"); 122 123 if (!get_blob(0, CS_OPS_IDENTITY)) 124 errx(1, "got identity"); 125 126 if (!get_blob(pid, CS_OPS_BLOB)) 127 errx(1, "got blob"); 128 129 return 0; 130} 131