xref: /linux/scripts/ipe/polgen/polgen.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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