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