1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved. 4 */ 5 6 #include <stdlib.h> 7 #include <stddef.h> 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <errno.h> 11 12 static void usage(const char *const name) 13 { 14 printf("Usage: %s OutputFile (PolicyFile)\n", name); 15 exit(EINVAL); 16 } 17 18 static int policy_to_buffer(const char *pathname, char **buffer, size_t *size) 19 { 20 size_t fsize; 21 size_t read; 22 char *lbuf; 23 int rc = 0; 24 FILE *fd; 25 26 fd = fopen(pathname, "r"); 27 if (!fd) { 28 rc = errno; 29 goto out; 30 } 31 32 fseek(fd, 0, SEEK_END); 33 fsize = ftell(fd); 34 rewind(fd); 35 36 lbuf = malloc(fsize); 37 if (!lbuf) { 38 rc = ENOMEM; 39 goto out_close; 40 } 41 42 read = fread((void *)lbuf, sizeof(*lbuf), fsize, fd); 43 if (read != fsize) { 44 rc = -1; 45 goto out_free; 46 } 47 48 *buffer = lbuf; 49 *size = fsize; 50 fclose(fd); 51 52 return rc; 53 54 out_free: 55 free(lbuf); 56 out_close: 57 fclose(fd); 58 out: 59 return rc; 60 } 61 62 static int write_boot_policy(const char *pathname, const char *buf, size_t size) 63 { 64 int rc = 0; 65 FILE *fd; 66 size_t i; 67 68 fd = fopen(pathname, "w"); 69 if (!fd) { 70 rc = errno; 71 goto err; 72 } 73 74 fprintf(fd, "/* This file is automatically generated."); 75 fprintf(fd, " Do not edit. */\n"); 76 fprintf(fd, "#include <linux/stddef.h>\n"); 77 fprintf(fd, "\nextern const char *const ipe_boot_policy;\n\n"); 78 fprintf(fd, "const char *const ipe_boot_policy =\n"); 79 80 if (!buf || size == 0) { 81 fprintf(fd, "\tNULL;\n"); 82 fclose(fd); 83 return 0; 84 } 85 86 fprintf(fd, "\t\""); 87 88 for (i = 0; i < size; ++i) { 89 switch (buf[i]) { 90 case '"': 91 fprintf(fd, "\\\""); 92 break; 93 case '\'': 94 fprintf(fd, "'"); 95 break; 96 case '\n': 97 fprintf(fd, "\\n\"\n\t\""); 98 break; 99 case '\\': 100 fprintf(fd, "\\\\"); 101 break; 102 case '\t': 103 fprintf(fd, "\\t"); 104 break; 105 case '\?': 106 fprintf(fd, "\\?"); 107 break; 108 default: 109 fprintf(fd, "%c", buf[i]); 110 } 111 } 112 fprintf(fd, "\";\n"); 113 fclose(fd); 114 115 return 0; 116 117 err: 118 if (fd) 119 fclose(fd); 120 return rc; 121 } 122 123 int main(int argc, const char *const argv[]) 124 { 125 char *policy = NULL; 126 size_t len = 0; 127 int rc = 0; 128 129 if (argc < 2) 130 usage(argv[0]); 131 132 if (argc > 2) { 133 rc = policy_to_buffer(argv[2], &policy, &len); 134 if (rc != 0) 135 goto cleanup; 136 } 137 138 rc = write_boot_policy(argv[1], policy, len); 139 cleanup: 140 if (policy) 141 free(policy); 142 if (rc != 0) 143 perror("An error occurred during policy conversion: "); 144 return rc; 145 } 146