1{
2 lib,
3 stdenv,
4 fetchFromSavannah,
5 flex,
6 bison,
7 python3,
8 autoconf,
9 automake,
10 libtool,
11 bash,
12 gettext,
13 ncurses,
14 libusb-compat-0_1,
15 freetype,
16 qemu,
17 lvm2,
18 unifont,
19 pkg-config,
20 help2man,
21 fetchzip,
22 fetchpatch,
23 buildPackages,
24 nixosTests,
25 fuse, # only needed for grub-mount
26 runtimeShell,
27 zfs ? null,
28 efiSupport ? false,
29 zfsSupport ? false,
30 xenSupport ? false,
31 kbdcompSupport ? false,
32 ckbcomp,
33}:
34
35let
36 pcSystems = {
37 i686-linux.target = "i386";
38 x86_64-linux.target = "i386";
39 };
40
41 efiSystemsBuild = {
42 i686-linux.target = "i386";
43 x86_64-linux.target = "x86_64";
44 armv7l-linux.target = "arm";
45 aarch64-linux.target = "aarch64";
46 loongarch64-linux.target = "loongarch64";
47 riscv32-linux.target = "riscv32";
48 riscv64-linux.target = "riscv64";
49 };
50
51 # For aarch64, we need to use '--target=aarch64-efi' when building,
52 # but '--target=arm64-efi' when installing. Insanity!
53 efiSystemsInstall = {
54 i686-linux.target = "i386";
55 x86_64-linux.target = "x86_64";
56 armv7l-linux.target = "arm";
57 aarch64-linux.target = "arm64";
58 loongarch64-linux.target = "loongarch64";
59 riscv32-linux.target = "riscv32";
60 riscv64-linux.target = "riscv64";
61 };
62
63 canEfi = lib.any (system: stdenv.hostPlatform.system == system) (
64 lib.mapAttrsToList (name: _: name) efiSystemsBuild
65 );
66 inPCSystems = lib.any (system: stdenv.hostPlatform.system == system) (
67 lib.mapAttrsToList (name: _: name) pcSystems
68 );
69
70 gnulib = fetchFromSavannah {
71 repo = "gnulib";
72 # NOTE: keep in sync with bootstrap.conf!
73 rev = "9f48fb992a3d7e96610c4ce8be969cff2d61a01b";
74 hash = "sha256-mzbF66SNqcSlI+xmjpKpNMwzi13yEWoc1Fl7p4snTto=";
75 };
76
77 src = fetchFromSavannah {
78 repo = "grub";
79 rev = "grub-2.12";
80 hash = "sha256-lathsBb2f7urh8R86ihpTdwo3h1hAHnRiHd5gCLVpBc=";
81 };
82
83 # The locales are fetched from translationproject.org at build time,
84 # but those translations are not versioned/stable. For that reason
85 # we take them from the nearest release tarball instead:
86 locales = fetchzip {
87 url = "https://ftp.gnu.org/gnu/grub/grub-2.12.tar.gz";
88 hash = "sha256-IoRiJHNQ58y0UhCAD0CrpFiI8Mz1upzAtyh5K4Njh/w=";
89 };
90in
91stdenv.mkDerivation rec {
92 pname = "grub";
93 version = "2.12";
94 inherit src;
95
96 patches = [
97 ./fix-bash-completion.patch
98 ./add-hidden-menu-entries.patch
99
100 # https://lists.gnu.org/archive/html/grub-devel/2025-02/msg00024.html
101 (fetchpatch {
102 name = "01_implement_grub_strlcpy.patch";
103 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=ea703528a8581a2ea7e0bad424a70fdf0aec7d8f";
104 hash = "sha256-MSMgu1vMG83HRImUUsTyA1YQaIhgEreGGPd+ZDWSI2I=";
105 })
106 (fetchpatch {
107 name = "02_CVE-2024-45781.patch";
108 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=c1a291b01f4f1dcd6a22b61f1c81a45a966d16ba";
109 hash = "sha256-q8ErK+cQzaqwSuhLRFL3AfYBkpgJq1IQmadnlmlz2yw=";
110 })
111 (fetchpatch {
112 name = "03_CVE-2024-45782_CVE-2024-56737.patch";
113 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=417547c10410b714e43f08f74137c24015f8f4c3";
114 hash = "sha256-mRinw27WZ2d1grzyzFGO18yXx72UVBM6Lf5cR8XJfs8=";
115 })
116 (fetchpatch {
117 name = "04_fs_tar_initialize_name_in_grub_cpio_find_file.patch";
118 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=2c8ac08c99466c0697f704242363fc687f492a0d";
119 hash = "sha256-EMGF0B+Fw6tSmllWUJAp1ynzWk+w2C/XM1LmXSReHWg=";
120 })
121 (fetchpatch {
122 name = "05_CVE-2024-45780.patch";
123 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=0087bc6902182fe5cedce2d034c75a79cf6dd4f3";
124 hash = "sha256-IlW5i4EJVoUYPu9/lb0LeytTpzltQuu5fpkFPQNIhls=";
125 })
126 (fetchpatch {
127 name = "06_fs_f2fs_grub_errno_mount_fails.patch";
128 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=563436258cde64da6b974880abff1bf0959f4da3";
129 hash = "sha256-Iu0RPyB+pAnqMT+MTX+TrJbYJsvYPn7jbMgE1jcLh/Q=";
130 })
131 (fetchpatch {
132 name = "07_CVE-2024-45783.patch";
133 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=f7c070a2e28dfab7137db0739fb8db1dc02d8898";
134 hash = "sha256-V1wh2dPeTazmad61jFtOjhq2MdoD+txPWY/AfwwyTZM=";
135 })
136 (fetchpatch {
137 name = "08_fs_iso9660_grub_errno_mount_fails.patch";
138 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=965db5970811d18069b34f28f5f31ddadde90a97";
139 hash = "sha256-6eN1AvZwXkJOQVcjgymy/E7QiAxzL/d0W3KlAZRqUzI=";
140 })
141 (fetchpatch {
142 name = "09_fs_iso9660_fix_invalid_free.patch";
143 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=1443833a9535a5873f7de3798cf4d8389f366611";
144 hash = "sha256-Gt5yMy5Vg9zrDggj3o/TLNt2vT9/6IuHg4Se2p8e8pI=";
145 })
146 (fetchpatch {
147 name = "10_fs_jfs_fix_oob_read_jfs_getent.patch";
148 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=66175696f3a385b14bdf1ebcda7755834bd2d5fb";
149 hash = "sha256-ETbzbc5gvf55sTLjmJOXXC9VH3qcP1Gv5seR/U9NRiY=";
150 })
151 (fetchpatch {
152 name = "11_fs_jfs_fix_oob_read_caused_by_invalid_dir_slot_index.patch";
153 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=ab09fd0531f3523ac0ef833404526c98c08248f7";
154 hash = "sha256-wE6niiIx4BdN800/Eegb6IbBRoMFpXq9kPvatwhWNXY=";
155 })
156 (fetchpatch {
157 name = "12_fs_jfs_use_full_40_bits_offset_and_address_for_data_extent.patch";
158 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=bd999310fe67f35a66de3bfa2836da91589d04ef";
159 hash = "sha256-fbC4oTEIoGWJASzJI5RXfoanrMLTfjFOI51LCUU7Ctg=";
160 })
161 (fetchpatch {
162 name = "13_fs_jfs_inconsistent_signed_unsigned_types_usage.patch";
163 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=edd995a26ec98654d907a9436a296c2d82bc4b28";
164 hash = "sha256-aa1G1vi4bPZejfKEqZokAZTzY9Ea2lyxTrP4drDV9tk=";
165 })
166 (fetchpatch {
167 name = "14_fs_ext2_fix_out-of-bounds_read_for_inline_extent.patch";
168 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=7e2f750f0a795c4d64ec7dc7591edac8da2e978c";
169 hash = "sha256-PtPqZHMU2fy7btRRaaswLyHizplxnygCzDfcg5ievOQ=";
170 })
171 (fetchpatch {
172 name = "15_fs_ntfs_fix_out-of-bounds_read.patch";
173 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=aff26318783a135562b904ff09e2359893885732";
174 hash = "sha256-znN6lkAB9aAhTGKR1038DzOz5nzuTp+7ylHVqRM7HeI=";
175 })
176 (fetchpatch {
177 name = "16_fs_ntfs_track_the_end_of_the_MFT_attribute_buffer.patch";
178 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=237a71184a32d1ef7732f5f49ed6a89c5fe1c99a";
179 hash = "sha256-0I/g0qHkWY6PArPn1UaYRhCrrh9bHknADh34v5eSjjM=";
180 })
181 (fetchpatch {
182 name = "17_fs_ntfs_use_a_helper_function_to_access_attributes.patch";
183 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=048777bc29043403d077d41a81d0183767b8bc71";
184 hash = "sha256-Mm49MSLqCq143r8ruLJm1QoyCoLtOlCBfqoAPwPlv8E=";
185 })
186 # Patch 18 (067b6d225d482280abad03944f04e30abcbdafa1) has been removed because it causes regressions
187 # https://lists.gnu.org/archive/html/grub-devel/2025-03/msg00067.html
188 (fetchpatch {
189 name = "19_fs_xfs_fix_out-of-bounds_read.patch";
190 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=6ccc77b59d16578b10eaf8a4fe85c20b229f0d8a";
191 hash = "sha256-FvTzFvfEi3oyxPC/dUHreyzzeVCskaUlYUjpKY/l0DE=";
192 })
193 (fetchpatch {
194 name = "20_fs_xfs_ensuring_failing_to_mount_sets_a_grub_errno.patch";
195 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d1d6b7ea58aa5a80a4c4d0666b49460056c8ef0a";
196 hash = "sha256-SLdXMmYHq/gRmWrjRrOu5ZYFod84EllUL6hk+gnr3kg=";
197 })
198 (fetchpatch {
199 name = "21_kern_file_ensure_file_data_is_set.patch";
200 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=a7910687294b29288ac649e71b47493c93294f17";
201 hash = "sha256-DabZK9eSToEmSA9dEwtEN+URiVyS9qf6e2Y2UiMuy8Q=";
202 })
203 (fetchpatch {
204 name = "22_kern_file_implement_filesystem_reference_counting.patch";
205 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=16f196874fbe360a1b3c66064ec15adadf94c57b";
206 excludes = [ "grub-core/fs/erofs.c" ]; # Does not exist on 2.12
207 hash = "sha256-yGU//1tPaxi+xFKZrsbUAnvgFpwtrIMG+8cPbSud4+U=";
208 })
209 (fetchpatch {
210 name = "23_prerequisite_1_key_protector_add_key_protectors_framework.patch";
211 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=5d260302da672258444b01239803c8f4d753e3f3";
212 hash = "sha256-9WnFN6xMiv+1XMhNHgVEegkhwzp9KpRZI6MIZY/Ih3Q=";
213 })
214 (fetchpatch {
215 name = "23_prerequisite_2_disk_cryptodisk_allow_user_to_retry_failed_passphrase.patch";
216 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=386b59ddb42fa3f86ddfe557113b25c8fa16f88c";
217 hash = "sha256-e1kGQB7wGWvEb2bY3xIpZxE1uzTt9JOKi05jXyUm+bI=";
218 })
219 (fetchpatch {
220 name = "23_prerequisite_3_cryptodisk_support_key_protectors.patch";
221 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=ad0c52784a375cecaa8715d7deadcf5d65baf173";
222 hash = "sha256-+YIvUYA3fLiOFFsXDrQjqjWFluzLa7N1tv0lwq8BqCs=";
223 })
224 (fetchpatch {
225 name = "23_prerequisite_4_cryptodisk_fallback_to_passphrase.patch";
226 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=6abf8af3c54abc04c4ec71c75d10fcfbc190e181";
227 hash = "sha256-eMu9rW4iJucDAsTQMJD1XE6dDIcUmn02cGqIaqBbO3o=";
228 })
229 (fetchpatch {
230 name = "23_prerequisite_5_cryptodisk_wipe_out_the_cached_keys_from_protectors.patch";
231 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=b35480b48e6f9506d8b7ad8a3b5206d29c24ea95";
232 hash = "sha256-5L6Rr+X5Z+Ip91z8cpLcatDW1vyEoZa1icL2oMXPXuI=";
233 })
234 (fetchpatch {
235 name = "23_prerequisite_6_cli_lock_add_build_option_to_block_command_line_interface.patch";
236 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=bb65d81fe320e4b20d0a9b32232a7546eb275ecc";
237 hash = "sha256-HxXgtvEhtaIjXbOcxJHNpD9/NVOv3uXPnue7cagEMu8=";
238 })
239 (fetchpatch {
240 name = "23_CVE-2024-49504.patch";
241 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=13febd78db3cd85dcba67d8ad03ad4d42815f11e";
242 hash = "sha256-U7lNUb4iVAyQ1yEg5ECHCQGE51tKvY13T9Ji09Q1W9Y=";
243 })
244 (fetchpatch {
245 name = "24_disk_loopback_reference_tracking_for_the_loopback.patch";
246 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=67f70f70a36b6e87a65f928fe1e840a12eafb7ae";
247 hash = "sha256-sWBnSF3rAuY1A/IIK1Pc+BqTvyK3j7+lLEhvImtBQMA=";
248 })
249 (fetchpatch {
250 name = "25_kern_disk_limit_recursion_depth.patch";
251 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=18212f0648b6de7d71d4c8f41eb4d8b78b3a299b";
252 hash = "sha256-HiVzXUNs45Fxh4DSqO8wAxSBM7CaYU/bix0PVBcIHGw=";
253 })
254 (fetchpatch {
255 name = "26_kern_partition_limit_recursion_in_part_iterate.patch";
256 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=8a7103fddfd6664f41081f3bb88eebbf2871da2a";
257 hash = "sha256-Nw1VFRVww1VSDSBkRrnTGeaA2PKCitugM12XH6X/2YI=";
258 })
259 (fetchpatch {
260 name = "27_script_execute_limit_the_recursion_depth.patch";
261 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d8a937ccae5c6d86dc4375698afca5cefdcd01e1";
262 hash = "sha256-YOAdPMZ2iBNMzIwAXFkkyTMKh4ptZUQ0J3v9EjnRlbo=";
263 })
264 (fetchpatch {
265 name = "28_net_unregister_net_default_ip_and_net_default_mac_variables_hooks_on_unload.patch";
266 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=a1dd8e59da26f1a9608381d3a1a6c0f465282b1d";
267 hash = "sha256-7fqdkhFqLECzhz1OLavkHrE9ktDAEmx9ZxZayNr/Eo4=";
268 })
269 (fetchpatch {
270 name = "29_net_remove_variables_hooks_when_interface_is_unregisted.patch";
271 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=aa8b4d7facef7b75a2703274b1b9d4e0e734c401";
272 hash = "sha256-m3VLDbJlwchV5meEpU4LJrDxBtA80qvYcVMJinHLnac=";
273 })
274 (fetchpatch {
275 name = "30_CVE-2025-0624.patch";
276 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=5eef88152833062a3f7e017535372d64ac8ef7e1";
277 hash = "sha256-DvhzHnenAmO9SZpi4kU+0GhyKZB4q4xQYuNJgEhJmn0=";
278 })
279 (fetchpatch {
280 name = "31_net_tftp_fix_stack_buffer_overflow_in_tftp_open.patch";
281 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=0707accab1b9be5d3645d4700dde3f99209f9367";
282 hash = "sha256-16NrpWFSE4jFT2uxmJg16jChw8HiGRTol25XQXNQ5l4=";
283 })
284 (fetchpatch {
285 name = "32_CVE-2024-45774.patch";
286 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=2c34af908ebf4856051ed29e46d88abd2b20387f";
287 hash = "sha256-OWmF+fp2TmetQjV4EWMcESW8u52Okkb5C5IPLfczyv4=";
288 })
289 (fetchpatch {
290 name = "33_kern_dl_fix_for_an_integer_overflow_in_grub_dl_ref.patch";
291 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=500e5fdd82ca40412b0b73f5e5dda38e4a3af96d";
292 hash = "sha256-FNqOWo+oZ4/1sCbTi2uaeKchUxwAKXtbzhScezm0yxk=";
293 })
294 # Patch 34 (https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d72208423dcabf9eb4a3bcb17b6b31888396bd49)
295 # is skipped, grub_dl_set_mem_attrs() does not exist on 2.12
296 (fetchpatch {
297 name = "35_kern_dl_check_for_the_SHF_INFO_LINK_flag_in_grub_dl_relocate_symbols.patch";
298 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=98ad84328dcabfa603dcf5bd217570aa6b4bdd99";
299 hash = "sha256-Zi4Pj2NbodL0VhhO5MWhvErb8xmA7Li0ur0MxpgQjzg=";
300 })
301 (fetchpatch {
302 name = "36_CVE-2024-45775.patch";
303 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=05be856a8c3aae41f5df90cab7796ab7ee34b872";
304 hash = "sha256-T6DO8iuImQTP7hPaCAHMtFnheQoCkZ6w+kfNolLPmrY=";
305 })
306 (fetchpatch {
307 name = "37_commands_ls_fix_NULL_dereference.patch";
308 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=0bf56bce47489c059e50e61a3db7f682d8c44b56";
309 hash = "sha256-h5okwqv4ZFahP3ANUbsk1fiSV4pwEnxUExeBgQ4tiTI=";
310 })
311 (fetchpatch {
312 name = "38_CVE-2025-0622.patch";
313 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=2123c5bca7e21fbeb0263df4597ddd7054700726";
314 hash = "sha256-tFE7VgImGZWDICyvHbrI1hqW6/XohgdTmk21MzljMGw=";
315 })
316 (fetchpatch {
317 name = "39_CVE-2025-0622.patch";
318 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=9c16197734ada8d0838407eebe081117799bfe67";
319 hash = "sha256-tTeuEvadKbXVuY0m0dKtTr11Lpb3yQi4zk0bpwrMOeA=";
320 })
321 (fetchpatch {
322 name = "40_CVE-2025-0622.patch";
323 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=7580addfc8c94cedb0cdfd7a1fd65b539215e637";
324 hash = "sha256-khRLpWqE7hzzoqssVkGFMjAv09T+uHn13Q9pCpogMms=";
325 })
326 (fetchpatch {
327 name = "41_CVE-2024-45776.patch";
328 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=09bd6eb58b0f71ec273916070fa1e2de16897a91";
329 hash = "sha256-yrl/6XUdKQg/MLe8KFuFoRRbQSyOhDmyvnWBV+sr3EY=";
330 })
331 (fetchpatch {
332 name = "42_CVE-2024-45777.patch";
333 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=b970a5ed967816bbca8225994cd0ee2557bad515";
334 hash = "sha256-Vl5Emw3O3Ba2hD1GCWune4PGduDDPO0gM5u+zx/OwKo=";
335 })
336 (fetchpatch {
337 name = "43_CVE-2025-0690.patch";
338 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=dad8f502974ed9ad0a70ae6820d17b4b142558fc";
339 hash = "sha256-DeWOncndX2VM8w1lb5fd5wHAZrI+ChB5Pj9XbUIfDWY=";
340 })
341 (fetchpatch {
342 name = "44_commands_test_stack_overflow_due_to_unlimited_recursion_depth.patch";
343 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=c68b7d23628a19da67ebe2e06f84165ee04961af";
344 hash = "sha256-aputM9KqkB/cK8hBiU9VXbu0LpLNlNCMVIeE9h2pMgY=";
345 })
346 (fetchpatch {
347 name = "45_CVE-2025-1118.patch";
348 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=34824806ac6302f91e8cabaa41308eaced25725f";
349 hash = "sha256-PKQs+fCwj4a9p4hbMqAT3tFNoAOw4xnbKmCwjPUgEOc=";
350 })
351 (fetchpatch {
352 name = "46_commands_memrw_disable_memory_reading_in_lockdown_mode.patch";
353 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=340e4d058f584534f4b90b7dbea2b64a9f8c418c";
354 hash = "sha256-NiMIUnfRreDBw+k4yxUzoRNMFL8pkJhVtkINVgmv5XA=";
355 })
356 (fetchpatch {
357 name = "47_commands_hexdump_disable_memory_reading_in_lockdown_mode.patch";
358 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=5f31164aed51f498957cdd6ed733ec71a8592c99";
359 hash = "sha256-NA7QjxZ9FP+WwiOveqLkbZqsF7hULIyaVS3gNaSUXJE=";
360 })
361 (fetchpatch {
362 name = "48_CVE-2024-45778_CVE-2024-45779.patch";
363 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=26db6605036bd9e5b16d9068a8cc75be63b8b630";
364 hash = "sha256-1+ImwkF/qsejWs2lpyO6xbcqVo2NJGv32gjrP8mEPnI=";
365 })
366 (fetchpatch {
367 name = "49_CVE-2025-0677_CVE-2025-0684_CVE-2025-0685_CVE-2025-0686_CVE-2025-0689.patch";
368 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=c4bc55da28543d2522a939ba4ee0acde45f2fa74";
369 hash = "sha256-qrlErSImMX8eXJHkXjOe5GZ6lWOya5SVpNoiqyEM1lE=";
370 })
371 (fetchpatch {
372 name = "50_disk_use_safe_math_macros_to_prevent_overflows.patch";
373 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=c407724dad6c3e2fc1571e57adbda71cc03f82aa";
374 hash = "sha256-kkAjxXvCdzwqh+oWtEF3qSPiUX9cGWO6eSFVeo7WJzQ=";
375 })
376 (fetchpatch {
377 name = "51_disk_prevent_overflows_when_allocating_memory_for_arrays.patch";
378 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d8151f98331ee4d15fcca59edffa59246d8fc15f";
379 hash = "sha256-2U+gMLigOCCg3P1GB615xQ0B9PDA6j92tt1ba3Tqg+E=";
380 })
381 (fetchpatch {
382 name = "52_disk_check_if_returned_pointer_for_allocated_memory_is_NULL.patch";
383 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=33bd6b5ac5c77b346769ab5284262f94e695e464";
384 hash = "sha256-+BaJRskWP/YVEdvIxMvEydjQx2LpLlGphRtZjiOUxJ0=";
385 })
386 (fetchpatch {
387 name = "53_disk_ieee1275_ofdisk_call_grub_ieee1275_close_when_grub_malloc_fails.patch";
388 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=fbaddcca541805c333f0fc792b82772594e73753";
389 hash = "sha256-9sGA41HlB/8rtT/fMfkDo4ZJMXBSr+EyN92l/0gDfl4=";
390 })
391 (fetchpatch {
392 name = "54_fs_use_safe_math_macros_to_prevent_overflows.patch";
393 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=6608163b08a7a8be4b0ab2a5cd4593bba07fe2b7";
394 excludes = [ "grub-core/fs/erofs.c" ]; # Does not exist on 2.12
395 hash = "sha256-mW4MH5VH5pDxCaFhNh/4mEcYloga56p8vCi7X4kSaek=";
396 })
397 (fetchpatch {
398 name = "55_CVE-2025-0678_CVE-2025-1125.patch";
399 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=84bc0a9a68835952ae69165c11709811dae7634e";
400 hash = "sha256-rCliqM2+k7rTGNpdHFkg3pHvuISjoG0MQr6/8lIvwK4=";
401 })
402 (fetchpatch {
403 name = "56_fs_prevent_overflows_when_assigning_returned_values_from_read_number.patch";
404 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=cde9f7f338f8f5771777f0e7dfc423ddf952ad31";
405 hash = "sha256-dN3HJXNIYtaUZL0LhLabC4VKK6CVC8km9UTw/ln/6ys=";
406 })
407 (fetchpatch {
408 name = "57_fs_zfs_use_safe_math_macros_to_prevent_overflows.patch";
409 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=88e491a0f744c6b19b6d4caa300a576ba56db7c9";
410 hash = "sha256-taSuKyCf9+TiQZcF26yMWpDDQqCfTdRuZTqB9aEz3aA=";
411 })
412 (fetchpatch {
413 name = "58_fs_zfs_prevent_overflows_when_allocating_memory_for_arrays.patch";
414 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=7f38e32c7ebeaebb79e2c71e3c7d5ea367d3a39c";
415 hash = "sha256-E5VmP7I4TAEXxTz3j7mi/uIr9kOSzMoPHAYAbyu56Xk=";
416 })
417 (fetchpatch {
418 name = "59_fs_zfs_check_if_returned_pointer_for_allocated_memory_is_NULL.patch";
419 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=13065f69dae0eeb60813809026de5bd021051892";
420 hash = "sha256-1W//rHUspDS+utdNc069J8lX1ONfoBKiJYnUt46C/D0=";
421 })
422 (fetchpatch {
423 name = "60_fs_zfs_add_missing_NULL_check_after_grub_strdup_call.patch";
424 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=dd6a4c8d10e02ca5056681e75795041a343636e4";
425 hash = "sha256-iFLEkz5G6aQ8FXGuY7/wgN4d4o0+sUxWMKYIFcQ/H+o=";
426 })
427 (fetchpatch {
428 name = "61_net_use_safe_math_macros_to_prevent_overflows.patch";
429 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=4beeff8a31c4fb4071d2225533cfa316b5a58391";
430 hash = "sha256-/gs5ZhplQ1h7PWw0p+b5+0OxmRcvDRKWHj39ezhivcg=";
431 })
432 (fetchpatch {
433 name = "62_net_prevent_overflows_when_allocating_memory_for_arrays.patch";
434 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=dee2c14fd66bc497cdc74c69fde8c9b84637c8eb";
435 hash = "sha256-cO02tCGEeQhQF0TmgtNOgUwRLnNgmxhEefo1gtSlFOk=";
436 })
437 (fetchpatch {
438 name = "63_net_check_if_returned_pointer_for_allocated_memory_is_NULL.patch";
439 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=1c06ec900591d1fab6fbacf80dc010541d0a5ec8";
440 hash = "sha256-oSRhWWVraitoVDqGlFOVzdCkaNqFGOHLjJu75CSc388=";
441 })
442 (fetchpatch {
443 name = "64_fs_sfs_check_if_allocated_memory_is_NULL.patch";
444 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=e3c578a56f9294e286b6028ca7c1def997a17b15";
445 hash = "sha256-7tvFbmjWmWmmRykQjMvZV6IYlhSS8oNR7YfaO5XXAfU=";
446 })
447 (fetchpatch {
448 name = "65_script_execute_fix_potential_underflow_and_NULL.patch";
449 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d13b6e8ebd10b4eb16698a002aa40258cf6e6f0e";
450 hash = "sha256-paMWaAIImzxtufUrVF5v4T4KnlDAJIPhdaHznu5CyZ8=";
451 })
452 (fetchpatch {
453 name = "66_osdep_unix_getroot_fix_potential_underflow.patch";
454 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=66733f7c7dae889861ea3ef3ec0710811486019e";
455 hash = "sha256-/14HC1kcW7Sy9WfJQFfC+YnvS/GNTMP+Uy6Dxd3zkwc=";
456 })
457 (fetchpatch {
458 name = "67_misc_ensure_consistent_overflow_error_messages.patch";
459 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=f8795cde217e21539c2f236bcbb1a4bf521086b3";
460 hash = "sha256-4X7wr1Tg16xDE9FO6NTlgkfLV5zFKmajeaOspIqcCuI=";
461 })
462 (fetchpatch {
463 name = "68_bus_usb_ehci_define_GRUB_EHCI_TOGGLE_as_grub_uint32_t.patch";
464 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=9907d9c2723304b42cf6da74f1cc6c4601391956";
465 hash = "sha256-D8xaI8g7ffGGmZqqeS8wxWIFLUWUBfmHwMVOHkYTc2I=";
466 })
467 (fetchpatch {
468 name = "69_normal_menu_use_safe_math_to_avoid_an_integer_overflow.patch";
469 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=5b36a5210e21bee2624f8acc36aefd8f10266adb";
470 hash = "sha256-UourmM0Zlaj4o+SnYi5AtjfNujDOt+2ez2XH/uWyiaM=";
471 })
472 (fetchpatch {
473 name = "70_kern_partition_add_sanity_check_after_grub_strtoul_call.patch";
474 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=8e6e87e7923ca2ae880021cb42a35cc9bb4c8fe2";
475 hash = "sha256-4keMUu6ZDKmuSQlFnldV15dDGUibsnSvoEWhLsqWieI=";
476 })
477 (fetchpatch {
478 name = "71_kern_misc_add_sanity_check_after_grub_strtoul_call.patch";
479 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=a8d6b06331a75d75b46f3dd6cc6fcd40dcf604b7";
480 hash = "sha256-2Mpe1sqyuoUPyMAKGZTNzG/ig3G3K8w0gia7lc508Rg=";
481 })
482 (fetchpatch {
483 name = "72_loader_i386_linux_cast_left_shift_to_grub_uint32_t.patch";
484 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=490a6ab71cebd96fae7a1ceb9067484f5ccbec2a";
485 hash = "sha256-e49OC1EBaX0/nWTTXT5xE5apTJPQV0myP5Ohxn9Wwa8=";
486 })
487 (fetchpatch {
488 name = "73_loader_i386_bsd_use_safe_math_to_avoid_underflow.patch";
489 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=4dc6166571645780c459dde2cdc1b001a5ec844c";
490 hash = "sha256-e8X+oBvejcFNOY1Tp/f6QqCDwrgK7f9u1F8SdO/dhy4=";
491 })
492 (fetchpatch {
493 # Fixes 7e2f750f0a (security patch 14/73)
494 name = "fs_ext2_rework_out-of-bounds_read_for_inline_and_external_extents.patch";
495 url = "https://git.savannah.gnu.org/cgit/grub.git/patch/?id=348cd416a3574348f4255bf2b04ec95938990997";
496 hash = "sha256-WBLYQxv8si2tvdPAvbm0/4NNqYWBMJpFV4GC0HhN/kE=";
497 })
498 ];
499
500 postPatch =
501 if kbdcompSupport then
502 ''
503 sed -i util/grub-kbdcomp.in -e 's@\bckbcomp\b@${ckbcomp}/bin/ckbcomp@'
504 ''
505 else
506 ''
507 echo '#! ${runtimeShell}' > util/grub-kbdcomp.in
508 echo 'echo "Compile grub2 with { kbdcompSupport = true; } to enable support for this command."' >> util/grub-kbdcomp.in
509 '';
510
511 depsBuildBuild = [ buildPackages.stdenv.cc ];
512 nativeBuildInputs = [
513 bison
514 flex
515 python3
516 pkg-config
517 gettext
518 freetype
519 autoconf
520 automake
521 help2man
522 ];
523 buildInputs = [
524 ncurses
525 libusb-compat-0_1
526 freetype
527 lvm2
528 fuse
529 libtool
530 bash
531 ]
532 ++ lib.optional doCheck qemu
533 ++ lib.optional zfsSupport zfs;
534
535 strictDeps = true;
536
537 hardeningDisable = [ "all" ];
538
539 separateDebugInfo = !xenSupport;
540
541 preConfigure = ''
542 for i in "tests/util/"*.in
543 do
544 sed -i "$i" -e's|/bin/bash|${stdenv.shell}|g'
545 done
546
547 # Apparently, the QEMU executable is no longer called
548 # `qemu-system-i386', even on i386.
549 #
550 # In addition, use `-nodefaults' to avoid errors like:
551 #
552 # chardev: opening backend "stdio" failed
553 # qemu: could not open serial device 'stdio': Invalid argument
554 #
555 # See <http://www.mail-archive.com/qemu-devel@nongnu.org/msg22775.html>.
556 sed -i "tests/util/grub-shell.in" \
557 -e's/qemu-system-i386/qemu-system-x86_64 -nodefaults/g'
558
559 unset CPP # setting CPP intereferes with dependency calculation
560
561 patchShebangs .
562
563 GNULIB_REVISION=$(. bootstrap.conf; echo $GNULIB_REVISION)
564 if [ "$GNULIB_REVISION" != ${gnulib.rev} ]; then
565 echo "This version of GRUB requires a different gnulib revision!"
566 echo "We have: ${gnulib.rev}"
567 echo "GRUB needs: $GNULIB_REVISION"
568 exit 1
569 fi
570
571 cp -f --no-preserve=mode ${locales}/po/LINGUAS ${locales}/po/*.po po
572
573 ./bootstrap --no-git --gnulib-srcdir=${gnulib}
574
575 substituteInPlace ./configure --replace '/usr/share/fonts/unifont' '${unifont}/share/fonts'
576 '';
577
578 postConfigure = ''
579 # make sure .po files are up to date to workaround
580 # parallel `msgmerge --update` on autogenerated .po files:
581 # https://github.com/NixOS/nixpkgs/pull/248747#issuecomment-1676301670
582 make dist
583 '';
584
585 configureFlags = [
586 "--enable-grub-mount" # dep of os-prober
587 ]
588 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
589 # grub doesn't do cross-compilation as usual and tries to use unprefixed
590 # tools to target the host. Provide toolchain information explicitly for
591 # cross builds.
592 #
593 # Ref: # https://github.com/buildroot/buildroot/blob/master/boot/grub2/grub2.mk#L108
594 "TARGET_CC=${stdenv.cc.targetPrefix}cc"
595 "TARGET_NM=${stdenv.cc.targetPrefix}nm"
596 "TARGET_OBJCOPY=${stdenv.cc.targetPrefix}objcopy"
597 "TARGET_RANLIB=${stdenv.cc.targetPrefix}ranlib"
598 "TARGET_STRIP=${stdenv.cc.targetPrefix}strip"
599 ]
600 ++ lib.optional zfsSupport "--enable-libzfs"
601 ++ lib.optionals efiSupport [
602 "--with-platform=efi"
603 "--target=${efiSystemsBuild.${stdenv.hostPlatform.system}.target}"
604 "--program-prefix="
605 ]
606 ++ lib.optionals xenSupport [
607 "--with-platform=xen"
608 "--target=${efiSystemsBuild.${stdenv.hostPlatform.system}.target}"
609 ];
610
611 # save target that grub is compiled for
612 grubTarget =
613 if efiSupport then
614 "${efiSystemsInstall.${stdenv.hostPlatform.system}.target}-efi"
615 else
616 lib.optionalString inPCSystems "${pcSystems.${stdenv.hostPlatform.system}.target}-pc";
617
618 doCheck = false;
619 enableParallelBuilding = true;
620
621 postInstall = ''
622 # Avoid a runtime reference to gcc
623 sed -i $out/lib/grub/*/modinfo.sh -e "/grub_target_cppflags=/ s|'.*'|' '|"
624 # just adding bash to buildInputs wasn't enough to fix the shebang
625 substituteInPlace $out/lib/grub/*/modinfo.sh \
626 --replace ${buildPackages.bash} "/usr/bin/bash"
627 '';
628
629 passthru.tests = {
630 nixos-grub = nixosTests.grub;
631 nixos-install-simple = nixosTests.installer.simple;
632 nixos-install-grub-uefi = nixosTests.installer.simpleUefiGrub;
633 nixos-install-grub-uefi-spec = nixosTests.installer.simpleUefiGrubSpecialisation;
634 };
635
636 meta = with lib; {
637 description = "GNU GRUB, the Grand Unified Boot Loader";
638
639 longDescription = ''
640 GNU GRUB is a Multiboot boot loader. It was derived from GRUB, GRand
641 Unified Bootloader, which was originally designed and implemented by
642 Erich Stefan Boleyn.
643
644 Briefly, the boot loader is the first software program that runs when a
645 computer starts. It is responsible for loading and transferring
646 control to the operating system kernel software (such as the Hurd or
647 the Linux). The kernel, in turn, initializes the rest of the
648 operating system (e.g., GNU).
649 '';
650
651 homepage = "https://www.gnu.org/software/grub/";
652
653 license = licenses.gpl3Plus;
654
655 platforms =
656 if xenSupport then
657 [
658 "x86_64-linux"
659 "i686-linux"
660 ]
661 else
662 platforms.gnu ++ platforms.linux;
663
664 maintainers = [ ];
665
666 broken = !(efiSupport -> canEfi) || !(zfsSupport -> zfs != null) || (efiSupport && xenSupport);
667 };
668}