]> git.proxmox.com Git - grub2.git/blame - util/grub-setup.c
fs/ntfs: Fix various OOB reads and writes (CVE-2023-4692, CVE-2023-4693)
[grub2.git] / util / grub-setup.c
CommitLineData
4b13b216 1/* grub-setup.c - make GRUB usable */
1cc73a62 2/*
4b13b216 3 * GRUB -- GRand Unified Bootloader
a98f4a08 4 * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc.
1cc73a62 5 *
5a79f472 6 * GRUB is free software: you can redistribute it and/or modify
1cc73a62 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
1cc73a62 9 * (at your option) any later version.
10 *
5a79f472 11 * GRUB is distributed in the hope that it will be useful,
1cc73a62 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/>.
1cc73a62 18 */
19
20#include <config.h>
c06c7520
VS
21
22#define _GNU_SOURCE 1
23
24#include <string.h>
25
4b13b216 26#include <grub/types.h>
8c411768 27#include <grub/emu/misc.h>
4b13b216 28#include <grub/util/misc.h>
29#include <grub/device.h>
30#include <grub/disk.h>
31#include <grub/file.h>
32#include <grub/fs.h>
3f1578fe 33#include <grub/partition.h>
5f968e1e 34#include <grub/env.h>
8c411768 35#include <grub/emu/hostdisk.h>
9cacaa17 36#include <grub/term.h>
f577f7a0 37#include <grub/i18n.h>
c06c7520 38#include <grub/crypto.h>
d2ea4551 39#include <grub/emu/getroot.h>
c06c7520 40#include <grub/util/install.h>
e1e49678 41
ca3e2088
VS
42#pragma GCC diagnostic ignored "-Wmissing-prototypes"
43#pragma GCC diagnostic ignored "-Wmissing-declarations"
c5930ec8 44#include <argp.h>
ca3e2088
VS
45#pragma GCC diagnostic error "-Wmissing-prototypes"
46#pragma GCC diagnostic error "-Wmissing-declarations"
1cc73a62 47
d2ea4551
VS
48/* On SPARC this program fills in various fields inside of the 'boot' and 'core'
49 * image files.
50 *
51 * The 'boot' image needs to know the OBP path name of the root
52 * device. It also needs to know the initial block number of
53 * 'core' (which is 'diskboot' concatenated with 'kernel' and
54 * all the modules, this is created by grub-mkimage). This resulting
55 * 'boot' image is 512 bytes in size and is placed in the second block
56 * of a partition.
57 *
58 * The initial 'diskboot' block acts as a loader for the actual GRUB
59 * kernel. It contains the loading code and then a block list.
60 *
61 * The block list of 'core' starts at the end of the 'diskboot' image
62 * and works it's way backwards towards the end of the code of 'diskboot'.
63 *
64 * We patch up the images with the necessary values and write out the
65 * result.
66 */
67
1cc73a62 68#define DEFAULT_BOOT_FILE "boot.img"
69#define DEFAULT_CORE_FILE "core.img"
70
dd73313c 71/* Non-printable "keys" for arguments with no short form.
35b90906 72 * See grub-core/lib/gnulib/argp.h for details. */
dd73313c
JM
73enum {
74 NO_RS_CODES_KEY = 0x100,
75};
76
c5930ec8
YB
77static struct argp_option options[] = {
78 {"boot-image", 'b', N_("FILE"), 0,
6a656b0e 79 N_("use FILE as the boot image [default=%s]"), 0},
c5930ec8 80 {"core-image", 'c', N_("FILE"), 0,
6a656b0e 81 N_("use FILE as the core image [default=%s]"), 0},
c5930ec8 82 {"directory", 'd', N_("DIR"), 0,
6a656b0e 83 N_("use GRUB files in the directory DIR [default=%s]"), 0},
c5930ec8 84 {"device-map", 'm', N_("FILE"), 0,
9c4b5c13 85 N_("use FILE as the device map [default=%s]"), 0},
c5930ec8 86 {"force", 'f', 0, 0,
9c4b5c13 87 N_("install even if problems are detected"), 0},
c5930ec8 88 {"skip-fs-probe",'s',0, 0,
6a656b0e 89 N_("do not probe for filesystems in DEVICE"), 0},
b525fd83 90 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
fdf2ec9c 91 {"allow-floppy", 'a', 0, 0,
ef292a87
VS
92 /* TRANSLATORS: The potential breakage isn't limited to floppies but it's
93 likely to make the install unbootable from HDD. */
6a656b0e 94 N_("make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0},
dd73313c
JM
95 {"no-rs-codes", NO_RS_CODES_KEY, 0, 0,
96 N_("Do not apply any reed-solomon codes when embedding core.img. "
97 "This option is only available on x86 BIOS targets."), 0},
c5930ec8
YB
98 { 0, 0, 0, 0, 0, 0 }
99};
100
ae558c2c
VS
101#pragma GCC diagnostic ignored "-Wformat-nonliteral"
102
c5930ec8
YB
103static char *
104help_filter (int key, const char *text, void *input __attribute__ ((unused)))
105{
106 switch (key)
107 {
108 case 'b':
109 return xasprintf (text, DEFAULT_BOOT_FILE);
110
111 case 'c':
112 return xasprintf (text, DEFAULT_CORE_FILE);
113
114 case 'd':
115 return xasprintf (text, DEFAULT_DIRECTORY);
116
117 case 'm':
118 return xasprintf (text, DEFAULT_DEVICE_MAP);
1cc73a62 119
c5930ec8
YB
120 default:
121 return (char *) text;
122 }
123}
124
ae558c2c
VS
125#pragma GCC diagnostic error "-Wformat-nonliteral"
126
c5930ec8
YB
127struct arguments
128{
129 char *boot_file;
130 char *core_file;
131 char *dir;
132 char *dev_map;
c5930ec8
YB
133 int force;
134 int fs_probe;
fdf2ec9c 135 int allow_floppy;
c5930ec8 136 char *device;
dd73313c 137 int add_rs_codes;
c5930ec8
YB
138};
139
c5930ec8
YB
140static error_t
141argp_parser (int key, char *arg, struct argp_state *state)
142{
143 /* Get the input argument from argp_parse, which we
144 know is a pointer to our arguments structure. */
145 struct arguments *arguments = state->input;
146
c5930ec8
YB
147 switch (key)
148 {
fdf2ec9c
VS
149 case 'a':
150 arguments->allow_floppy = 1;
151 break;
152
c5930ec8
YB
153 case 'b':
154 if (arguments->boot_file)
155 free (arguments->boot_file);
156
157 arguments->boot_file = xstrdup (arg);
158 break;
159
160 case 'c':
161 if (arguments->core_file)
162 free (arguments->core_file);
163
164 arguments->core_file = xstrdup (arg);
165 break;
166
167 case 'd':
168 if (arguments->dir)
169 free (arguments->dir);
170
171 arguments->dir = xstrdup (arg);
172 break;
173
174 case 'm':
175 if (arguments->dev_map)
176 free (arguments->dev_map);
177
178 arguments->dev_map = xstrdup (arg);
179 break;
180
c5930ec8
YB
181 case 'f':
182 arguments->force = 1;
183 break;
184
185 case 's':
186 arguments->fs_probe = 0;
187 break;
188
189 case 'v':
190 verbosity++;
191 break;
192
dd73313c
JM
193 case NO_RS_CODES_KEY:
194 arguments->add_rs_codes = 0;
195 break;
196
c5930ec8
YB
197 case ARGP_KEY_ARG:
198 if (state->arg_num == 0)
199 arguments->device = xstrdup(arg);
200 else
201 {
202 /* Too many arguments. */
67093bc0
VS
203 fprintf (stderr, _("Unknown extra argument `%s'."), arg);
204 fprintf (stderr, "\n");
c5930ec8
YB
205 argp_usage (state);
206 }
207 break;
208
209 case ARGP_KEY_NO_ARGS:
dfe3b247 210 fprintf (stderr, "%s", _("No device is specified.\n"));
c5930ec8 211 argp_usage (state);
c76899a0 212 exit (1);
c5930ec8
YB
213 break;
214
215 default:
216 return ARGP_ERR_UNKNOWN;
217 }
218
219 return 0;
1cc73a62 220}
221
c5930ec8
YB
222static struct argp argp = {
223 options, argp_parser, N_("DEVICE"),
934d7e44 224 "\n"N_("\
c5930ec8
YB
225Set up images to boot from DEVICE.\n\
226\n\
934d7e44
YB
227You should not normally run this program directly. Use grub-install instead.")
228"\v"N_("\
26c53dc6 229DEVICE must be an OS device (e.g. /dev/sda)."),
c5930ec8
YB
230 NULL, help_filter, NULL
231};
232
f585c905
AB
233static char *
234get_device_name (char *dev)
235{
236 size_t len = strlen (dev);
237
238 if (dev[0] != '(' || dev[len - 1] != ')')
239 return 0;
240
241 dev[len - 1] = '\0';
242 return dev + 1;
243}
244
1cc73a62 245int
246main (int argc, char *argv[])
247{
f585c905
AB
248 char *root_dev = NULL;
249 char *dest_dev = NULL;
c5930ec8 250 struct arguments arguments;
b39f9d20 251
ae5540d3 252 grub_util_host_init (&argc, &argv);
1cc73a62 253
c5930ec8
YB
254 /* Default option values. */
255 memset (&arguments, 0, sizeof (struct arguments));
256 arguments.fs_probe = 1;
dd73313c 257 arguments.add_rs_codes = 1;
1cc73a62 258
c5930ec8
YB
259 /* Parse our arguments */
260 if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
261 {
dfe3b247 262 fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
c5930ec8 263 exit(1);
1cc73a62 264 }
265
c36e5cd1 266#ifdef GRUB_SETUP_SPARC64
17821956
VS
267 arguments.force = 1;
268#endif
269
91a4bf68 270 if (verbosity > 1)
271 grub_env_set ("debug", "all");
272
075a1650 273 /* Initialize the emulated biosdisk driver. */
c5930ec8 274 grub_util_biosdisk_init (arguments.dev_map ? : DEFAULT_DEVICE_MAP);
1cc73a62 275
daf0f0ba 276 /* Initialize all modules. */
277 grub_init_all ();
5c144cc8 278 grub_gcry_init_all ();
b39f9d20 279
88b87c93 280 grub_lvm_fini ();
1e8d555b
VS
281 grub_mdraid09_fini ();
282 grub_mdraid1x_fini ();
076e7c0f
VS
283 grub_diskfilter_fini ();
284 grub_diskfilter_init ();
1e8d555b
VS
285 grub_mdraid09_init ();
286 grub_mdraid1x_init ();
88b87c93
VS
287 grub_lvm_init ();
288
f585c905
AB
289 dest_dev = get_device_name (arguments.device);
290 if (! dest_dev)
291 {
292 /* Possibly, the user specified an OS device file. */
293 dest_dev = grub_util_get_grub_dev (arguments.device);
294 if (! dest_dev)
295 {
296 char *program = xstrdup(program_name);
297 fprintf (stderr, _("Invalid device `%s'.\n"), arguments.device);
298 argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
299 free(program);
300 exit(1);
301 }
302 grub_util_info ("transformed OS device `%s' into GRUB device `%s'",
303 arguments.device, dest_dev);
304 }
305 else
306 {
307 /* For simplicity. */
308 dest_dev = xstrdup (dest_dev);
309 grub_util_info ("Using `%s' as GRUB device", dest_dev);
310 }
311
076e7c0f 312 /* Do the real work. */
c06c7520
VS
313 GRUB_SETUP_FUNC (arguments.dir ? : DEFAULT_DIRECTORY,
314 arguments.boot_file ? : DEFAULT_BOOT_FILE,
315 arguments.core_file ? : DEFAULT_CORE_FILE,
f585c905 316 dest_dev, arguments.force,
dd73313c 317 arguments.fs_probe, arguments.allow_floppy,
5fd18f77 318 arguments.add_rs_codes, 0);
1cc73a62 319
320 /* Free resources. */
daf0f0ba 321 grub_fini_all ();
4b13b216 322 grub_util_biosdisk_fini ();
b39f9d20 323
c5930ec8
YB
324 free (arguments.boot_file);
325 free (arguments.core_file);
326 free (arguments.dir);
c5930ec8
YB
327 free (arguments.dev_map);
328 free (arguments.device);
f585c905
AB
329 free (root_dev);
330 free (dest_dev);
b39f9d20 331
1cc73a62 332 return 0;
333}