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
usage(const char * const name)12 static void usage(const char *const name)
13 {
14 printf("Usage: %s OutputFile (PolicyFile)\n", name);
15 exit(EINVAL);
16 }
17
policy_to_buffer(const char * pathname,char ** buffer,size_t * size)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
write_boot_policy(const char * pathname,const char * buf,size_t size)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
main(int argc,const char * const argv[])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