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 FILE *fd; 65 size_t i; 66 67 fd = fopen(pathname, "w"); 68 if (!fd) 69 return errno; 70 71 fprintf(fd, "/* This file is automatically generated."); 72 fprintf(fd, " Do not edit. */\n"); 73 fprintf(fd, "#include <linux/stddef.h>\n"); 74 fprintf(fd, "\nextern const char *const ipe_boot_policy;\n\n"); 75 fprintf(fd, "const char *const ipe_boot_policy =\n"); 76 77 if (!buf || size == 0) { 78 fprintf(fd, "\tNULL;\n"); 79 fclose(fd); 80 return 0; 81 } 82 83 fprintf(fd, "\t\""); 84 85 for (i = 0; i < size; ++i) { 86 switch (buf[i]) { 87 case '"': 88 fprintf(fd, "\\\""); 89 break; 90 case '\'': 91 fprintf(fd, "'"); 92 break; 93 case '\n': 94 fprintf(fd, "\\n\"\n\t\""); 95 break; 96 case '\\': 97 fprintf(fd, "\\\\"); 98 break; 99 case '\t': 100 fprintf(fd, "\\t"); 101 break; 102 case '\?': 103 fprintf(fd, "\\?"); 104 break; 105 default: 106 fprintf(fd, "%c", buf[i]); 107 } 108 } 109 fprintf(fd, "\";\n"); 110 fclose(fd); 111 112 return 0; 113 } 114 115 int main(int argc, const char *const argv[]) 116 { 117 char *policy = NULL; 118 size_t len = 0; 119 int rc = 0; 120 121 if (argc < 2) 122 usage(argv[0]); 123 124 if (argc > 2) { 125 rc = policy_to_buffer(argv[2], &policy, &len); 126 if (rc != 0) 127 goto cleanup; 128 } 129 130 rc = write_boot_policy(argv[1], policy, len); 131 cleanup: 132 if (policy) 133 free(policy); 134 if (rc != 0) 135 perror("An error occurred during policy conversion: "); 136 return rc; 137 } 138