]> git.proxmox.com Git - grub2.git/blame - util/grub-mkimage.c
fs/ntfs: Fix various OOB reads and writes (CVE-2023-4692, CVE-2023-4693)
[grub2.git] / util / grub-mkimage.c
CommitLineData
4b13b216 1/* grub-mkimage.c - make a bootable image */
6a161fa9 2/*
4b13b216 3 * GRUB -- GRand Unified Bootloader
2f1a3acf 4 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6a161fa9 5 *
5a79f472 6 * GRUB is free software: you can redistribute it and/or modify
6a161fa9 7 * it under the terms of the GNU General Public License as published by
5a79f472 8 * the Free Software Foundation, either version 3 of the License, or
6a161fa9 9 * (at your option) any later version.
10 *
5a79f472 11 * GRUB is distributed in the hope that it will be useful,
6a161fa9 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
5a79f472 17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
6a161fa9 18 */
19
20#include <config.h>
4b13b216 21#include <grub/types.h>
5855d253 22#include <grub/elf.h>
a49217cf 23#include <grub/aout.h>
9a90f817 24#include <grub/i18n.h>
4b13b216 25#include <grub/kernel.h>
26#include <grub/disk.h>
692d7c28 27#include <grub/emu/misc.h>
4b13b216 28#include <grub/util/misc.h>
29#include <grub/util/resolve.h>
55a581dc 30#include <grub/misc.h>
614be3f1 31#include <grub/offsets.h>
04360337 32#include <grub/crypto.h>
5452733f 33#include <grub/dl.h>
e310b81f 34#include <time.h>
70ffcc93 35#include <multiboot.h>
6a161fa9 36
37#include <stdio.h>
38#include <unistd.h>
39#include <string.h>
40#include <stdlib.h>
3a73dcb6 41#include <assert.h>
d31bc996 42#include <grub/efi/pe32.h>
bc1cf01c
VS
43#include <grub/uboot/image.h>
44#include <grub/arm/reloc.h>
d5e2a158 45#include <grub/ia64/reloc.h>
71c1d67a 46#include <grub/osdep/hostfile.h>
ec16e026 47#include <grub/util/install.h>
cd46aa6c 48#include <grub/emu/config.h>
6a161fa9 49
50#define _GNU_SOURCE 1
ca3e2088
VS
51
52#pragma GCC diagnostic ignored "-Wmissing-prototypes"
53#pragma GCC diagnostic ignored "-Wmissing-declarations"
c76899a0 54#include <argp.h>
ca3e2088
VS
55#pragma GCC diagnostic error "-Wmissing-prototypes"
56#pragma GCC diagnostic error "-Wmissing-declarations"
57
6a161fa9 58
548643e5
RM
59#include "progname.h"
60
6a161fa9 61\f
62
c76899a0 63static struct argp_option options[] = {
67093bc0
VS
64 {"directory", 'd', N_("DIR"), 0,
65 /* TRANSLATORS: platform here isn't identifier. It can be translated. */
66 N_("use images and modules under DIR [default=%s/<platform>]"), 0},
1440b7eb 67 {"prefix", 'p', N_("DIR"), 0, N_("set prefix directory"), 0},
67093bc0 68 {"memdisk", 'm', N_("FILE"), 0,
ef292a87
VS
69 /* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated.
70 "embed" is a verb (command description). "*/
8573d302 71 N_("embed FILE as a memdisk image\n"
bfdfeb25
VS
72 "Implies `-p (memdisk)/boot/grub' and overrides any prefix supplied previously,"
73 " but the prefix itself can be overridden by later options"), 0},
fcbb723d 74 {"dtb", 'D', N_("FILE"), 0, N_("embed FILE as a device tree (DTB)\n"), 0},
ef292a87 75 /* TRANSLATORS: "embed" is a verb (command description). "*/
9c4b5c13 76 {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
5e3b8dcb
VS
77 /* TRANSLATORS: "embed" is a verb (command description). "*/
78 {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
9c4b5c13
VS
79 /* TRANSLATORS: NOTE is a name of segment. */
80 {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
c76899a0 81 {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
0ae70393 82 {"format", 'O', N_("FORMAT"), 0, 0, 0},
79451522 83 {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
b1154713 84 {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
968de8c2 85 {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
0ae70393 86 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
c76899a0
VS
87 { 0, 0, 0, 0, 0, 0 }
88};
6a161fa9 89
ae558c2c
VS
90#pragma GCC diagnostic ignored "-Wformat-nonliteral"
91
c76899a0
VS
92static char *
93help_filter (int key, const char *text, void *input __attribute__ ((unused)))
6a161fa9 94{
c76899a0 95 switch (key)
614be3f1 96 {
c76899a0 97 case 'd':
cd46aa6c 98 return xasprintf (text, grub_util_get_pkglibdir ());
c76899a0
VS
99 case 'O':
100 {
ec16e026 101 char *formats = grub_install_get_image_targets_string (), *ret;
b2b149cb 102 ret = xasprintf ("%s\n%s %s", _("generate an image in FORMAT"),
0ae70393 103 _("available formats:"), formats);
c76899a0
VS
104 free (formats);
105 return ret;
106 }
107 default:
108 return (char *) text;
614be3f1 109 }
6a161fa9 110}
111
ae558c2c
VS
112#pragma GCC diagnostic error "-Wformat-nonliteral"
113
c76899a0 114struct arguments
6a161fa9 115{
c76899a0
VS
116 size_t nmodules;
117 size_t modules_max;
118 char **modules;
119 char *output;
120 char *dir;
121 char *prefix;
122 char *memdisk;
fcbb723d 123 char *dtb;
5e3b8dcb
VS
124 char **pubkeys;
125 size_t npubkeys;
c76899a0
VS
126 char *font;
127 char *config;
b1154713 128 char *sbat;
c76899a0 129 int note;
968de8c2 130 int disable_shim_lock;
ec16e026 131 const struct grub_install_image_target_desc *image_target;
c76899a0
VS
132 grub_compression_t comp;
133};
6a161fa9 134
c76899a0
VS
135static error_t
136argp_parser (int key, char *arg, struct argp_state *state)
137{
138 /* Get the input argument from argp_parse, which we
139 know is a pointer to our arguments structure. */
140 struct arguments *arguments = state->input;
bdca2607 141
c76899a0 142 switch (key)
6a161fa9 143 {
c76899a0
VS
144 case 'o':
145 if (arguments->output)
146 free (arguments->output);
6a161fa9 147
c76899a0
VS
148 arguments->output = xstrdup (arg);
149 break;
150
151 case 'O':
152 {
ec16e026 153 arguments->image_target = grub_install_get_image_target (arg);
c76899a0 154 if (!arguments->image_target)
6a161fa9 155 {
c76899a0
VS
156 printf (_("unknown target format %s\n"), arg);
157 argp_usage (state);
158 exit (1);
159 }
160 break;
161 }
162 case 'd':
163 if (arguments->dir)
164 free (arguments->dir);
6a161fa9 165
c76899a0
VS
166 arguments->dir = xstrdup (arg);
167 break;
6a161fa9 168
c76899a0
VS
169 case 'n':
170 arguments->note = 1;
171 break;
2296410f 172
c76899a0
VS
173 case 'm':
174 if (arguments->memdisk)
175 free (arguments->memdisk);
55a581dc 176
c76899a0 177 arguments->memdisk = xstrdup (arg);
b39f9d20 178
c76899a0
VS
179 if (arguments->prefix)
180 free (arguments->prefix);
a9207284 181
c76899a0
VS
182 arguments->prefix = xstrdup ("(memdisk)/boot/grub");
183 break;
55a581dc 184
fcbb723d
VS
185 case 'D':
186 if (arguments->dtb)
187 free (arguments->dtb);
188
189 arguments->dtb = xstrdup (arg);
190 break;
191
5e3b8dcb
VS
192 case 'k':
193 arguments->pubkeys = xrealloc (arguments->pubkeys,
194 sizeof (arguments->pubkeys[0])
195 * (arguments->npubkeys + 1));
196 arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg);
197 break;
198
c76899a0
VS
199 case 'c':
200 if (arguments->config)
201 free (arguments->config);
5e898c9d 202
c76899a0
VS
203 arguments->config = xstrdup (arg);
204 break;
5e898c9d 205
c76899a0
VS
206 case 'C':
207 if (grub_strcmp (arg, "xz") == 0)
208 {
2c44e493 209#ifdef HAVE_LIBLZMA
ec16e026 210 arguments->comp = GRUB_COMPRESSION_XZ;
2c44e493 211#else
495fc8c1
VS
212 grub_util_error ("%s",
213 _("grub-mkimage is compiled without XZ support"));
2c44e493 214#endif
c76899a0
VS
215 }
216 else if (grub_strcmp (arg, "none") == 0)
ec16e026 217 arguments->comp = GRUB_COMPRESSION_NONE;
a9d96eeb 218 else if (grub_strcmp (arg, "auto") == 0)
ec16e026 219 arguments->comp = GRUB_COMPRESSION_AUTO;
c76899a0
VS
220 else
221 grub_util_error (_("Unknown compression format %s"), arg);
222 break;
223
224 case 'p':
225 if (arguments->prefix)
226 free (arguments->prefix);
227
228 arguments->prefix = xstrdup (arg);
229 break;
230
b1154713
PJ
231 case 's':
232 if (arguments->sbat)
233 free (arguments->sbat);
234
235 arguments->sbat = xstrdup (arg);
236 break;
237
968de8c2
DJL
238 case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
239 arguments->disable_shim_lock = 1;
240 break;
241
c76899a0
VS
242 case 'v':
243 verbosity++;
244 break;
245 case ARGP_KEY_ARG:
246 assert (arguments->nmodules < arguments->modules_max);
247 arguments->modules[arguments->nmodules++] = xstrdup(arg);
248 break;
758194b0 249
c76899a0
VS
250 default:
251 return ARGP_ERR_UNKNOWN;
252 }
253 return 0;
254}
6a161fa9 255
c76899a0
VS
256static struct argp argp = {
257 options, argp_parser, N_("[OPTION]... [MODULES]"),
258 N_("Make a bootable image of GRUB."),
259 NULL, help_filter, NULL
260};
261
262int
263main (int argc, char *argv[])
264{
265 FILE *fp = stdout;
266 struct arguments arguments;
377c1211 267 unsigned i;
bf697e28 268
ae5540d3 269 grub_util_host_init (&argc, &argv);
6a161fa9 270
c76899a0 271 memset (&arguments, 0, sizeof (struct arguments));
ec16e026 272 arguments.comp = GRUB_COMPRESSION_AUTO;
c76899a0
VS
273 arguments.modules_max = argc + 1;
274 arguments.modules = xmalloc ((arguments.modules_max + 1)
275 * sizeof (arguments.modules[0]));
276 memset (arguments.modules, 0, (arguments.modules_max + 1)
277 * sizeof (arguments.modules[0]));
6a161fa9 278
c76899a0
VS
279 if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
280 {
281 fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
282 exit(1);
6a161fa9 283 }
284
c76899a0 285 if (!arguments.image_target)
614be3f1 286 {
c76899a0 287 char *program = xstrdup(program_name);
0ae70393 288 printf ("%s\n", _("Target format not specified (use the -O option)."));
c76899a0
VS
289 argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
290 free (program);
291 exit(1);
614be3f1
VS
292 }
293
1440b7eb
AB
294 if (!arguments.prefix)
295 {
296 char *program = xstrdup(program_name);
297 printf ("%s\n", _("Prefix not specified (use the -p option)."));
298 argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
299 free (program);
300 exit(1);
301 }
302
c76899a0 303 if (arguments.output)
6a161fa9 304 {
bb338aaf 305 fp = grub_util_fopen (arguments.output, "wb");
6a161fa9 306 if (! fp)
0ae70393
VS
307 grub_util_error (_("cannot open `%s': %s"), arguments.output,
308 strerror (errno));
6a161fa9 309 }
310
c76899a0 311 if (!arguments.dir)
94ac7906 312 {
ec16e026 313 const char *dn = grub_util_get_target_dirname (arguments.image_target);
cd46aa6c
VS
314 const char *pkglibdir = grub_util_get_pkglibdir ();
315 char *ptr;
316 arguments.dir = xmalloc (grub_strlen (pkglibdir) + grub_strlen (dn) + 2);
317 ptr = grub_stpcpy (arguments.dir, pkglibdir);
318 *ptr++ = '/';
319 strcpy (ptr, dn);
94ac7906
VS
320 }
321
1440b7eb 322 grub_install_generate_image (arguments.dir, arguments.prefix, fp,
ec16e026
VS
323 arguments.output, arguments.modules,
324 arguments.memdisk, arguments.pubkeys,
325 arguments.npubkeys, arguments.config,
326 arguments.image_target, arguments.note,
b1154713 327 arguments.comp, arguments.dtb,
968de8c2 328 arguments.sbat, arguments.disable_shim_lock);
6a161fa9 329
62daa270
CW
330 if (grub_util_file_sync (fp) < 0)
331 grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
332 strerror (errno));
333 if (fclose (fp) == EOF)
334 grub_util_error (_("cannot close `%s': %s"), arguments.output ? : "stdout",
335 strerror (errno));
6a161fa9 336
377c1211
VS
337 for (i = 0; i < arguments.nmodules; i++)
338 free (arguments.modules[i]);
339
962b69d9 340 free (arguments.dir);
377c1211
VS
341 free (arguments.prefix);
342 free (arguments.modules);
6a161fa9 343
c821711f
LL
344 if (arguments.output)
345 free (arguments.output);
346
b1154713
PJ
347 if (arguments.sbat)
348 free (arguments.sbat);
349
6a161fa9 350 return 0;
351}