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 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
main(int argc,const char * const argv[])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