Compare commits
165 commits
coreos-one
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
2df2912266 | ||
|
ac301e4dd0 | ||
|
c30f378e00 | ||
|
c98a78ae81 | ||
|
84ff10b1c0 | ||
|
8471d8e254 | ||
|
3ec59f14f4 | ||
|
c55480daca | ||
|
ee12785f75 | ||
|
6efd04f314 | ||
|
de094060ac | ||
|
1e81bf6d2d | ||
|
c386331364 | ||
|
30c4e3ca40 | ||
|
8451454889 | ||
|
a6838bbc67 | ||
|
3e9d8c4ce4 | ||
|
e1b0992a8d | ||
|
3b3ac0c982 | ||
|
eb77486141 | ||
|
1066336dc8 | ||
|
b35792dccb | ||
|
74259522d7 | ||
|
a0ba8fae61 | ||
|
e7b8856f8b | ||
|
0dcbf3652b | ||
|
f7bd9986f6 | ||
|
098058752e | ||
|
d2cf823d0e | ||
|
b73cee7f1f | ||
|
879c4a8342 | ||
|
f5703eb062 | ||
|
07e5b79e22 | ||
|
426f57383d | ||
|
1a8d9c9b4a | ||
|
61ff5602fe | ||
|
caea56d1f8 | ||
|
781b3e5efc | ||
|
f8ad7a3dd8 | ||
|
d17770857e | ||
|
61b7ca08d1 | ||
|
16c0dbf4bc | ||
|
dc052e5ac7 | ||
|
6d7a59a2a1 | ||
|
26a8c19307 | ||
|
89f3da1a3d | ||
|
2a1edcf2ed | ||
|
3f05d693d1 | ||
|
f725fa7cb2 | ||
|
64e26162eb | ||
|
68708c4503 | ||
|
a4d3fbdff1 | ||
|
6a34fdb76a | ||
|
a81401ff49 | ||
|
7a9b30143b | ||
|
96be75ecbd | ||
|
cc6bd49a52 | ||
|
15d76540a7 | ||
|
c894713836 | ||
|
c867185b81 | ||
|
f39f1ec5d9 | ||
|
f2d56dea9d | ||
|
4aa9614e0a | ||
|
5ab40eb9f7 | ||
|
0fa9ed41ac | ||
|
0f3600bf1b | ||
|
2f317c8f19 | ||
|
f7dcb6a5c2 | ||
|
2ceae0ae25 | ||
|
641a144085 | ||
|
6cfa746654 | ||
|
c745f02165 | ||
|
26b7d55d82 | ||
|
16923f88ad | ||
|
eb46ee98bc | ||
|
c543d67810 | ||
|
e933feb578 | ||
|
3b81607b55 | ||
|
46d76f8fef | ||
|
12341958d2 | ||
|
2d7c3abd87 | ||
|
ea138d11be | ||
|
8bab36af60 | ||
|
5bcdf67642 | ||
|
30586747f1 | ||
|
b0c7769a41 | ||
|
06fd69a3fd | ||
|
2a6308b954 | ||
|
68006d1732 | ||
|
bdf170d101 | ||
|
6643507ce3 | ||
|
800de4a1d0 | ||
|
5e5a47b8a7 | ||
|
0454b04453 | ||
|
552c9fd081 | ||
|
2c43ab4ef7 | ||
|
20def1a3c3 | ||
|
8ad7c23864 | ||
|
1657e72f5b | ||
|
2bfd3654a6 | ||
|
9b89b1dedb | ||
|
3e8c338bfa | ||
|
c73cda3495 | ||
|
df84d6e94c | ||
|
df5d96de42 | ||
|
e642c95ab6 | ||
|
f0f97576e0 | ||
|
8d88ae92b5 | ||
|
42f4054faf | ||
|
cc93c5a849 | ||
|
ea04f131a4 | ||
|
87049f9716 | ||
|
2e246b6fec | ||
|
ac116bd659 | ||
|
d5a32255de | ||
|
c71be831f1 | ||
|
3137ecd97c | ||
|
9404c41953 | ||
|
d0de8b37f6 | ||
|
0ad07e928a | ||
|
03e72830ab | ||
|
9f03dc5d7b | ||
|
cb2f15c544 | ||
|
febc761e67 | ||
|
e921119857 | ||
|
8c2c35dcc0 | ||
|
aa096037ae | ||
|
3165efcfc2 | ||
|
598de14d93 | ||
|
e96e785580 | ||
|
365e0cc3e7 | ||
|
dd3f49b106 | ||
|
5324c335b1 | ||
|
9fbdec2f6b | ||
|
c6a84545a3 | ||
|
528938d503 | ||
|
0f3f5b7c13 | ||
|
7e28ca82bb | ||
|
b53a2f2c66 | ||
|
495781f5ed | ||
|
e2c09aed97 | ||
|
5e5a15872d | ||
|
42acdd3b40 | ||
|
28a7e597de | ||
|
b78d570a36 | ||
|
33203ca348 | ||
|
ee4bd79ef2 | ||
|
c7cb11b219 | ||
|
ff3e91be9c | ||
|
11268841e2 | ||
|
a57977b5fa | ||
|
f9e28d250a | ||
|
ab2e53c8a1 | ||
|
fc085f7f18 | ||
|
3ea9bc3c06 | ||
|
4e75b2ae31 | ||
|
8f6843ce60 | ||
|
15cfd02b74 | ||
|
688023cd0a | ||
|
261df54f17 | ||
|
dabdfa1c6a | ||
|
2bf40e9e5b | ||
|
2d55ffecbb | ||
|
f2b9083f85 | ||
|
26094f5241 |
249 changed files with 10441 additions and 3733 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
po/exclude.pot binary
|
468
.gitignore
vendored
468
.gitignore
vendored
|
@ -1,237 +1,277 @@
|
||||||
*~
|
#
|
||||||
00_header
|
# Ignore patterns in this directory and all subdirectories.
|
||||||
10_*
|
#
|
||||||
20_linux_xen
|
|
||||||
30_os-prober
|
|
||||||
40_custom
|
|
||||||
41_custom
|
|
||||||
*.1
|
*.1
|
||||||
*.8
|
*.8
|
||||||
ABOUT-NLS
|
*.a
|
||||||
aclocal.m4
|
|
||||||
ahci_test
|
|
||||||
ascii.bitmaps
|
|
||||||
ascii.h
|
|
||||||
autom4te.cache
|
|
||||||
build-aux
|
|
||||||
build-grub-gen-asciih
|
|
||||||
build-grub-gen-widthspec
|
|
||||||
build-grub-mkfont
|
|
||||||
cdboot_test
|
|
||||||
cmp_test
|
|
||||||
config.cache
|
|
||||||
config.guess
|
|
||||||
config.h
|
|
||||||
config-util.h
|
|
||||||
config-util.h.in
|
|
||||||
config.log
|
|
||||||
config.status
|
|
||||||
config.sub
|
|
||||||
configure
|
|
||||||
core_compress_test
|
|
||||||
DISTLIST
|
|
||||||
docs/*.info
|
|
||||||
docs/stamp-vti
|
|
||||||
docs/version.texi
|
|
||||||
ehci_test
|
|
||||||
example_grub_script_test
|
|
||||||
example_scripted_test
|
|
||||||
example_unit_test
|
|
||||||
*.exec
|
*.exec
|
||||||
*.exec.exe
|
*.exec.exe
|
||||||
fddboot_test
|
|
||||||
genkernsyms.sh
|
|
||||||
gensymlist.sh
|
|
||||||
gentrigtables
|
|
||||||
gentrigtables.exe
|
|
||||||
gettext_strings_test
|
|
||||||
/gnulib
|
|
||||||
grub-bin2h
|
|
||||||
/grub-bios-setup
|
|
||||||
/grub-bios-setup.exe
|
|
||||||
grub_cmd_date
|
|
||||||
grub_cmd_echo
|
|
||||||
grub_cmd_regexp
|
|
||||||
grub_cmd_set_date
|
|
||||||
grub_cmd_sleep
|
|
||||||
/grub-editenv
|
|
||||||
/grub-editenv.exe
|
|
||||||
grub-emu
|
|
||||||
grub-emu-lite
|
|
||||||
grub-emu.exe
|
|
||||||
grub-emu-lite.exe
|
|
||||||
grub_emu_init.c
|
|
||||||
grub_emu_init.h
|
|
||||||
/grub-file
|
|
||||||
/grub-file.exe
|
|
||||||
grub-fstest
|
|
||||||
grub-fstest.exe
|
|
||||||
grub_fstest_init.c
|
|
||||||
grub_fstest_init.h
|
|
||||||
grub_func_test
|
|
||||||
grub-install
|
|
||||||
grub-install.exe
|
|
||||||
grub-kbdcomp
|
|
||||||
/grub-macbless
|
|
||||||
/grub-macbless.exe
|
|
||||||
grub-macho2img
|
|
||||||
/grub-menulst2cfg
|
|
||||||
/grub-menulst2cfg.exe
|
|
||||||
/grub-mk*
|
|
||||||
grub-mount
|
|
||||||
/grub-ofpathname
|
|
||||||
/grub-ofpathname.exe
|
|
||||||
grub-core/build-grub-pe2elf.exe
|
|
||||||
/grub-probe
|
|
||||||
/grub-probe.exe
|
|
||||||
grub_probe_init.c
|
|
||||||
grub_probe_init.h
|
|
||||||
/grub-reboot
|
|
||||||
grub_script_blanklines
|
|
||||||
grub_script_blockarg
|
|
||||||
grub_script_break
|
|
||||||
grub-script-check
|
|
||||||
grub-script-check.exe
|
|
||||||
grub_script_check_init.c
|
|
||||||
grub_script_check_init.h
|
|
||||||
grub_script_comments
|
|
||||||
grub_script_continue
|
|
||||||
grub_script_dollar
|
|
||||||
grub_script_echo1
|
|
||||||
grub_script_echo_keywords
|
|
||||||
grub_script_escape_comma
|
|
||||||
grub_script_eval
|
|
||||||
grub_script_expansion
|
|
||||||
grub_script_final_semicolon
|
|
||||||
grub_script_for1
|
|
||||||
grub_script_functions
|
|
||||||
grub_script_gettext
|
|
||||||
grub_script_if
|
|
||||||
grub_script_leading_whitespace
|
|
||||||
grub_script_no_commands
|
|
||||||
grub_script_not
|
|
||||||
grub_script_return
|
|
||||||
grub_script_setparams
|
|
||||||
grub_script_shift
|
|
||||||
grub_script_strcmp
|
|
||||||
grub_script_test
|
|
||||||
grub_script_vars1
|
|
||||||
grub_script_while1
|
|
||||||
grub_script.tab.c
|
|
||||||
grub_script.tab.h
|
|
||||||
grub_script.yy.c
|
|
||||||
grub_script.yy.h
|
|
||||||
grub-set-default
|
|
||||||
grub_setup_init.c
|
|
||||||
grub_setup_init.h
|
|
||||||
grub-shell
|
|
||||||
grub-shell-tester
|
|
||||||
grub-sparc64-setup
|
|
||||||
grub-sparc64-setup.exe
|
|
||||||
/grub-syslinux2cfg
|
|
||||||
/grub-syslinux2cfg.exe
|
|
||||||
gzcompress_test
|
|
||||||
hddboot_test
|
|
||||||
help_test
|
|
||||||
*.img
|
|
||||||
*.image
|
*.image
|
||||||
*.image.exe
|
*.image.exe
|
||||||
include/grub/cpu
|
*.img
|
||||||
include/grub/machine
|
|
||||||
INSTALL.grub
|
|
||||||
install-sh
|
|
||||||
lib/libgcrypt-grub
|
|
||||||
libgrub_a_init.c
|
|
||||||
*.log
|
*.log
|
||||||
*.lst
|
*.lst
|
||||||
lzocompress_test
|
|
||||||
*.marker
|
*.marker
|
||||||
Makefile
|
|
||||||
/m4
|
|
||||||
*.mod
|
*.mod
|
||||||
mod-*.c
|
|
||||||
missing
|
|
||||||
netboot_test
|
|
||||||
*.o
|
*.o
|
||||||
*.a
|
|
||||||
ohci_test
|
|
||||||
partmap_test
|
|
||||||
pata_test
|
|
||||||
*.pf2
|
*.pf2
|
||||||
*.pp
|
*.pp
|
||||||
po/*.mo
|
|
||||||
po/grub.pot
|
|
||||||
po/Makefile.in.in
|
|
||||||
po/Makevars
|
|
||||||
po/Makevars.template
|
|
||||||
po/POTFILES
|
|
||||||
po/Rules-quot
|
|
||||||
po/stamp-po
|
|
||||||
printf_test
|
|
||||||
priority_queue_unit_test
|
|
||||||
pseries_test
|
|
||||||
stamp-h
|
|
||||||
stamp-h1
|
|
||||||
stamp-h.in
|
|
||||||
symlist.c
|
|
||||||
symlist.h
|
|
||||||
trigtables.c
|
|
||||||
*.trs
|
*.trs
|
||||||
uhci_test
|
*~
|
||||||
update-grub_lib
|
.deps-core/
|
||||||
unidata.c
|
.deps-util/
|
||||||
xzcompress_test
|
.deps/
|
||||||
Makefile.in
|
.dirstamp
|
||||||
|
DISTLIST
|
||||||
GPATH
|
GPATH
|
||||||
GRTAGS
|
GRTAGS
|
||||||
GSYMS
|
GSYMS
|
||||||
GTAGS
|
GTAGS
|
||||||
compile
|
Makefile
|
||||||
depcomp
|
Makefile.in
|
||||||
|
ascii.bitmaps
|
||||||
|
genkernsyms.sh
|
||||||
|
gensymlist.sh
|
||||||
|
grub-bin2h
|
||||||
|
grub-emu
|
||||||
|
grub-emu-lite
|
||||||
|
grub-emu-lite.exe
|
||||||
|
grub-emu.exe
|
||||||
|
grub-macho2img
|
||||||
|
grub_emu_init.c
|
||||||
|
grub_emu_init.h
|
||||||
|
grub_probe_init.c
|
||||||
|
grub_probe_init.h
|
||||||
|
grub_script.tab.c
|
||||||
|
grub_script.tab.h
|
||||||
|
grub_script.yy.c
|
||||||
|
grub_script.yy.h
|
||||||
|
grub_script_check_init.c
|
||||||
|
grub_script_check_init.h
|
||||||
|
grub_setup_init.c
|
||||||
|
grub_setup_init.h
|
||||||
mdate-sh
|
mdate-sh
|
||||||
texinfo.tex
|
mod-*.c
|
||||||
grub-core/lib/libgcrypt-grub
|
update-grub_lib
|
||||||
.deps
|
|
||||||
.deps-util
|
|
||||||
.deps-core
|
|
||||||
.dirstamp
|
|
||||||
Makefile.util.am
|
|
||||||
contrib
|
|
||||||
grub-core/bootinfo.txt
|
|
||||||
grub-core/Makefile.core.am
|
|
||||||
grub-core/Makefile.gcry.def
|
|
||||||
grub-core/contrib
|
|
||||||
grub-core/gdb_grub
|
|
||||||
grub-core/genmod.sh
|
|
||||||
grub-core/gensyminfo.sh
|
|
||||||
grub-core/gmodule.pl
|
|
||||||
grub-core/grub.chrp
|
|
||||||
grub-core/modinfo.sh
|
|
||||||
grub-core/*.module
|
|
||||||
grub-core/*.module.exe
|
|
||||||
grub-core/*.pp
|
|
||||||
grub-core/kernel.img.bin
|
|
||||||
util/bash-completion.d/grub
|
|
||||||
grub-core/lib/gnulib
|
|
||||||
grub-core/rs_decoder.h
|
|
||||||
widthspec.bin
|
widthspec.bin
|
||||||
widthspec.h
|
|
||||||
docs/stamp-1
|
#
|
||||||
docs/version-dev.texi
|
# Ignore patterns relative to this .gitignore file's directory.
|
||||||
Makefile.utilgcry.def
|
#
|
||||||
po/*.po
|
/00_header
|
||||||
po/*.gmo
|
/10_*
|
||||||
po/LINGUAS
|
/20_linux_xen
|
||||||
po/remove-potcdate.sed
|
/30_os-prober
|
||||||
include/grub/gcrypt/gcrypt.h
|
/30_uefi-firmware
|
||||||
include/grub/gcrypt/g10lib.h
|
/40_custom
|
||||||
po/POTFILES.in
|
/41_custom
|
||||||
po/POTFILES-shell.in
|
/ABOUT-NLS
|
||||||
/grub-glue-efi
|
/ChangeLog
|
||||||
/grub-render-label
|
/INSTALL.grub
|
||||||
/grub-glue-efi.exe
|
/Makefile.util.am
|
||||||
/grub-render-label.exe
|
/Makefile.utilgcry.def
|
||||||
|
/aclocal.m4
|
||||||
|
/ahci_test
|
||||||
|
/ascii.h
|
||||||
|
/autom4te.cache/
|
||||||
|
/btrfs_test
|
||||||
|
/build-aux/
|
||||||
|
/build-grub-gen-asciih
|
||||||
|
/build-grub-gen-widthspec
|
||||||
|
/build-grub-mkfont
|
||||||
|
/cdboot_test
|
||||||
|
/cmp_test
|
||||||
|
/compile
|
||||||
|
/config-util.h
|
||||||
|
/config-util.h.in
|
||||||
|
/config.cache
|
||||||
|
/config.guess
|
||||||
|
/config.h
|
||||||
|
/config.log
|
||||||
|
/config.status
|
||||||
|
/config.sub
|
||||||
|
/configure
|
||||||
|
/contrib
|
||||||
|
/core_compress_test
|
||||||
|
/cpio_test
|
||||||
|
/date_test
|
||||||
|
/depcomp
|
||||||
|
/docs/*.info
|
||||||
|
/docs/*.info-[0-9]*
|
||||||
|
/docs/stamp-1
|
||||||
|
/docs/stamp-vti
|
||||||
|
/docs/version-dev.texi
|
||||||
|
/docs/version.texi
|
||||||
|
/ehci_test
|
||||||
|
/example_grub_script_test
|
||||||
|
/example_scripted_test
|
||||||
|
/example_unit_test
|
||||||
|
/exfat_test
|
||||||
|
/ext234_test
|
||||||
|
/f2fs_test
|
||||||
|
/fat_test
|
||||||
|
/fddboot_test
|
||||||
|
/file_filter_test
|
||||||
/garbage-gen
|
/garbage-gen
|
||||||
/garbage-gen.exe
|
/garbage-gen.exe
|
||||||
|
/gettext_strings_test
|
||||||
|
/gnulib/
|
||||||
|
/grub-2.[0-9]*/
|
||||||
|
/grub-2.[0-9]*.tar.gz
|
||||||
|
/grub-bios-setup
|
||||||
|
/grub-bios-setup.exe
|
||||||
|
/grub-core/*.module
|
||||||
|
/grub-core/*.module.exe
|
||||||
|
/grub-core/*.pp
|
||||||
|
/grub-core/Makefile.core.am
|
||||||
|
/grub-core/Makefile.gcry.def
|
||||||
|
/grub-core/bootinfo.txt
|
||||||
|
/grub-core/build-grub-module-verifier
|
||||||
|
/grub-core/build-grub-pe2elf.exe
|
||||||
|
/grub-core/contrib
|
||||||
|
/grub-core/gdb_grub
|
||||||
|
/grub-core/genmod.sh
|
||||||
|
/grub-core/gensyminfo.sh
|
||||||
|
/grub-core/gentrigtables
|
||||||
|
/grub-core/gentrigtables.exe
|
||||||
|
/grub-core/gmodule.pl
|
||||||
|
/grub-core/grub.chrp
|
||||||
|
/grub-core/kernel.img.bin
|
||||||
|
/grub-core/lib/gnulib
|
||||||
|
/grub-core/lib/libgcrypt-grub
|
||||||
|
/grub-core/modinfo.sh
|
||||||
|
/grub-core/rs_decoder.h
|
||||||
|
/grub-core/symlist.c
|
||||||
|
/grub-core/symlist.h
|
||||||
|
/grub-core/trigtables.c
|
||||||
|
/grub-core/unidata.c
|
||||||
|
/grub-editenv
|
||||||
|
/grub-editenv.exe
|
||||||
|
/grub-file
|
||||||
|
/grub-file.exe
|
||||||
/grub-fs-tester
|
/grub-fs-tester
|
||||||
grub-core/build-grub-module-verifier
|
/grub-fstest
|
||||||
|
/grub-fstest.exe
|
||||||
|
/grub-glue-efi
|
||||||
|
/grub-glue-efi.exe
|
||||||
|
/grub-install
|
||||||
|
/grub-install.exe
|
||||||
|
/grub-kbdcomp
|
||||||
|
/grub-macbless
|
||||||
|
/grub-macbless.exe
|
||||||
|
/grub-menulst2cfg
|
||||||
|
/grub-menulst2cfg.exe
|
||||||
|
/grub-mk*
|
||||||
|
/grub-mount
|
||||||
|
/grub-ofpathname
|
||||||
|
/grub-ofpathname.exe
|
||||||
|
/grub-probe
|
||||||
|
/grub-probe.exe
|
||||||
|
/grub-reboot
|
||||||
|
/grub-render-label
|
||||||
|
/grub-render-label.exe
|
||||||
|
/grub-script-check
|
||||||
|
/grub-script-check.exe
|
||||||
|
/grub-set-default
|
||||||
|
/grub-shell
|
||||||
|
/grub-shell-tester
|
||||||
|
/grub-sparc64-setup
|
||||||
|
/grub-sparc64-setup.exe
|
||||||
|
/grub-syslinux2cfg
|
||||||
|
/grub-syslinux2cfg.exe
|
||||||
|
/grub_cmd_date
|
||||||
|
/grub_cmd_echo
|
||||||
|
/grub_cmd_regexp
|
||||||
|
/grub_cmd_set_date
|
||||||
|
/grub_cmd_sleep
|
||||||
|
/grub_cmd_test
|
||||||
|
/grub_cmd_tr
|
||||||
|
/grub_fstest_init.c
|
||||||
|
/grub_fstest_init.h
|
||||||
|
/grub_func_test
|
||||||
|
/grub_script_blanklines
|
||||||
|
/grub_script_blockarg
|
||||||
|
/grub_script_break
|
||||||
|
/grub_script_comments
|
||||||
|
/grub_script_continue
|
||||||
|
/grub_script_dollar
|
||||||
|
/grub_script_echo1
|
||||||
|
/grub_script_echo_keywords
|
||||||
|
/grub_script_escape_comma
|
||||||
|
/grub_script_eval
|
||||||
|
/grub_script_expansion
|
||||||
|
/grub_script_final_semicolon
|
||||||
|
/grub_script_for1
|
||||||
|
/grub_script_functions
|
||||||
|
/grub_script_gettext
|
||||||
|
/grub_script_if
|
||||||
|
/grub_script_leading_whitespace
|
||||||
|
/grub_script_no_commands
|
||||||
|
/grub_script_not
|
||||||
|
/grub_script_return
|
||||||
|
/grub_script_setparams
|
||||||
|
/grub_script_shift
|
||||||
|
/grub_script_strcmp
|
||||||
|
/grub_script_test
|
||||||
|
/grub_script_vars1
|
||||||
|
/grub_script_while1
|
||||||
|
/gzcompress_test
|
||||||
|
/hddboot_test
|
||||||
|
/help_test
|
||||||
|
/hfs_test
|
||||||
|
/hfsplus_test
|
||||||
|
/include/grub/cpu
|
||||||
|
/include/grub/gcrypt/g10lib.h
|
||||||
|
/include/grub/gcrypt/gcrypt.h
|
||||||
|
/include/grub/machine
|
||||||
|
/install-sh
|
||||||
|
/iso9660_test
|
||||||
|
/jfs_test
|
||||||
|
/lib/libgcrypt-grub
|
||||||
|
/libgrub_a_init.c
|
||||||
|
/lzocompress_test
|
||||||
|
/m4/
|
||||||
|
/minixfs_test
|
||||||
|
/missing
|
||||||
|
/netboot_test
|
||||||
|
/nilfs2_test
|
||||||
|
/ntfs_test
|
||||||
|
/ohci_test
|
||||||
|
/partmap_test
|
||||||
|
/pata_test
|
||||||
|
/po/*.gmo
|
||||||
|
/po/*.mo
|
||||||
|
/po/*.po
|
||||||
|
/po/LINGUAS
|
||||||
|
/po/Makefile.in.in
|
||||||
|
/po/Makevars
|
||||||
|
/po/Makevars.template
|
||||||
|
/po/POTFILES
|
||||||
|
/po/POTFILES-shell.in
|
||||||
|
/po/POTFILES.in
|
||||||
|
/po/Rules-quot
|
||||||
|
/po/grub.pot
|
||||||
|
/po/remove-potcdate.sed
|
||||||
|
/po/stamp-po
|
||||||
|
/printf_test
|
||||||
|
/priority_queue_unit_test
|
||||||
|
/pseries_test
|
||||||
|
/reiserfs_test
|
||||||
|
/romfs_test
|
||||||
|
/squashfs_test
|
||||||
|
/stamp-h
|
||||||
|
/stamp-h.in
|
||||||
|
/stamp-h1
|
||||||
|
/syslinux_test
|
||||||
|
/tar_test
|
||||||
|
/test_sha512sum
|
||||||
|
/test_unset
|
||||||
|
/tests/syslinux/ubuntu10.04_grub.cfg
|
||||||
|
/texinfo.tex
|
||||||
|
/udf_test
|
||||||
|
/uhci_test
|
||||||
|
/util/bash-completion.d/grub
|
||||||
|
/widthspec.h
|
||||||
|
/xfs_test
|
||||||
|
/xzcompress_test
|
||||||
|
/zfs_test
|
||||||
|
|
|
@ -12,6 +12,7 @@ language: c
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
|
- autopoint
|
||||||
- libsdl1.2-dev
|
- libsdl1.2-dev
|
||||||
- lzop
|
- lzop
|
||||||
- ovmf
|
- ovmf
|
||||||
|
@ -35,7 +36,7 @@ before_script:
|
||||||
script:
|
script:
|
||||||
# Comments must be outside the command strings below, or the Travis parser
|
# Comments must be outside the command strings below, or the Travis parser
|
||||||
# will get confused.
|
# will get confused.
|
||||||
- ./autogen.sh
|
- ./bootstrap
|
||||||
|
|
||||||
# Build all selected GRUB targets.
|
# Build all selected GRUB targets.
|
||||||
- for target in $GRUB_TARGETS; do
|
- for target in $GRUB_TARGETS; do
|
||||||
|
|
69
INSTALL
69
INSTALL
|
@ -11,27 +11,9 @@ GRUB depends on some software packages installed into your system. If
|
||||||
you don't have any of them, please obtain and install them before
|
you don't have any of them, please obtain and install them before
|
||||||
configuring the GRUB.
|
configuring the GRUB.
|
||||||
|
|
||||||
* GCC 4.1.3 or later
|
* GCC 5.1.0 or later
|
||||||
Note: older versions may work but support is limited
|
Experimental support for clang 3.8.0 or later (results in much bigger binaries)
|
||||||
|
|
||||||
Experimental support for clang 3.3 or later (results in much bigger binaries)
|
|
||||||
for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64
|
for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64
|
||||||
Note: clang 3.2 or later works for i386 and x86_64 targets but results in
|
|
||||||
much bigger binaries.
|
|
||||||
earlier versions not tested
|
|
||||||
Note: clang 3.2 or later works for arm
|
|
||||||
earlier versions not tested
|
|
||||||
Note: clang on arm64 is not supported due to
|
|
||||||
https://llvm.org/bugs/show_bug.cgi?id=26030
|
|
||||||
Note: clang 3.3 or later works for mips(el)
|
|
||||||
earlier versions fail to generate .reginfo and hence gprel relocations
|
|
||||||
fail.
|
|
||||||
Note: clang 3.2 or later works for powerpc
|
|
||||||
earlier versions not tested
|
|
||||||
Note: clang 3.5 or later works for sparc64
|
|
||||||
earlier versions return "error: unable to interface with target machine"
|
|
||||||
Note: clang has no support for ia64 and hence you can't compile GRUB
|
|
||||||
for ia64 with clang
|
|
||||||
* GNU Make
|
* GNU Make
|
||||||
* GNU Bison 2.3 or later
|
* GNU Bison 2.3 or later
|
||||||
* GNU gettext 0.17 or later
|
* GNU gettext 0.17 or later
|
||||||
|
@ -160,12 +142,20 @@ For this example the configure line might look like (more details below)
|
||||||
(some options are optional and included here for completeness but some rarely
|
(some options are optional and included here for completeness but some rarely
|
||||||
used options are omitted):
|
used options are omitted):
|
||||||
|
|
||||||
./configure BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config --host=amd64-linux-gnu
|
./configure --host=x86_64-linux-gnu --target=arm-linux-gnueabihf \
|
||||||
CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" PKG_CONFIG=amd64-linux-gnu-pkg-config
|
--with-platform=efi BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config \
|
||||||
--target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc
|
HOST_CC=x86_64-linux-gnu-gcc HOST_CFLAGS='-g -O2' \
|
||||||
TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6"
|
PKG_CONFIG=x86_64-linux-gnu-pkg-config TARGET_CC=arm-linux-gnueabihf-gcc \
|
||||||
TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip"
|
TARGET_CFLAGS='-Os -march=armv8.3-a' TARGET_CCASFLAGS='-march=armv8.3-a' \
|
||||||
TARGET_NM=arm-elf-nm TARGET_RANLIB=arm-elf-ranlib LEX=gflex
|
TARGET_OBJCOPY=arm-linux-gnueabihf-objcopy \
|
||||||
|
TARGET_STRIP=arm-linux-gnueabihf-strip TARGET_NM=arm-linux-gnueabihf-nm \
|
||||||
|
TARGET_RANLIB=arm-linux-gnueabihf-ranlib LEX=flex
|
||||||
|
|
||||||
|
Normally, for building a GRUB on amd64 with tools to run on amd64 to
|
||||||
|
generate images to run on ARM, using your Linux distribution's
|
||||||
|
packaged cross compiler, the following would suffice:
|
||||||
|
|
||||||
|
./configure --target=arm-linux-gnueabihf --with-platform=efi
|
||||||
|
|
||||||
You need to use following options to specify tools and platforms. For minimum
|
You need to use following options to specify tools and platforms. For minimum
|
||||||
version look at prerequisites. All tools not mentioned in this section under
|
version look at prerequisites. All tools not mentioned in this section under
|
||||||
|
@ -182,20 +172,23 @@ corresponding platform are not needed for the platform in question.
|
||||||
|
|
||||||
- For host
|
- For host
|
||||||
1. --host= to autoconf name of host.
|
1. --host= to autoconf name of host.
|
||||||
2. CC= for gcc able to compile for host
|
2. CC= for gcc able to compile for host.
|
||||||
3. HOST_CFLAGS= for C options for host.
|
3. CFLAGS= for C options for host.
|
||||||
4. HOST_CPPFLAGS= for C preprocessor options for host.
|
4. HOST_CC= for gcc able to compile for host.
|
||||||
5. HOST_LDFLAGS= for linker options for host.
|
5. HOST_CFLAGS= for C options for host.
|
||||||
6. PKG_CONFIG= for pkg-config for host (optional).
|
6. HOST_CPPFLAGS= for C preprocessor options for host.
|
||||||
7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional).
|
7. HOST_LDFLAGS= for linker options for host.
|
||||||
8. Libfuse if any must be in standard linker folders (-lfuse) (optional).
|
8. PKG_CONFIG= for pkg-config for host (optional).
|
||||||
9. Libzfs if any must be in standard linker folders (-lzfs) (optional).
|
9. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional).
|
||||||
10. Liblzma if any must be in standard linker folders (-llzma) (optional).
|
10. Libfuse if any must be in standard linker folders (-lfuse) (optional).
|
||||||
|
11. Libzfs if any must be in standard linker folders (-lzfs) (optional).
|
||||||
|
12. Liblzma if any must be in standard linker folders (-llzma) (optional).
|
||||||
|
Note: The HOST_* variables override not prefixed variables.
|
||||||
|
|
||||||
- For target
|
- For target
|
||||||
1. --target= to autoconf cpu name of target.
|
1. --target= to autoconf cpu name of target.
|
||||||
2. --with-platform to choose firmware.
|
2. --with-platform to choose firmware.
|
||||||
3. TARGET_CC= for gcc able to compile for target
|
3. TARGET_CC= for gcc able to compile for target.
|
||||||
4. TARGET_CFLAGS= for C options for target.
|
4. TARGET_CFLAGS= for C options for target.
|
||||||
5. TARGET_CPPFLAGS= for C preprocessor options for target.
|
5. TARGET_CPPFLAGS= for C preprocessor options for target.
|
||||||
6. TARGET_CCASFLAGS= for assembler options for target.
|
6. TARGET_CCASFLAGS= for assembler options for target.
|
||||||
|
@ -204,6 +197,10 @@ corresponding platform are not needed for the platform in question.
|
||||||
9. TARGET_STRIP= for strip for target.
|
9. TARGET_STRIP= for strip for target.
|
||||||
10. TARGET_NM= for nm for target.
|
10. TARGET_NM= for nm for target.
|
||||||
11. TARGET_RANLIB= for ranlib for target.
|
11. TARGET_RANLIB= for ranlib for target.
|
||||||
|
Note: If the TARGET_* variables are not specified then they will default
|
||||||
|
to be the same as the host variables. If host variables are not
|
||||||
|
specified then the TARGET_* variables will default to be the same
|
||||||
|
as not prefixed variables.
|
||||||
|
|
||||||
- Additionally for emu, for host and target.
|
- Additionally for emu, for host and target.
|
||||||
1. SDL is looked for in standard linker directories (-lSDL) (optional)
|
1. SDL is looked for in standard linker directories (-lSDL) (optional)
|
||||||
|
|
|
@ -37,7 +37,7 @@ grub_script.yy.c: grub_script.yy.h
|
||||||
CLEANFILES += grub_script.yy.c grub_script.yy.h
|
CLEANFILES += grub_script.yy.c grub_script.yy.h
|
||||||
|
|
||||||
# For libgrub.a
|
# For libgrub.a
|
||||||
libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES)
|
libgrub.pp: config-util.h grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES)
|
||||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrubmods_a_CPPFLAGS) $(libgrubkern_a_CPPFLAGS) $(CPPFLAGS) \
|
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrubmods_a_CPPFLAGS) $(libgrubkern_a_CPPFLAGS) $(CPPFLAGS) \
|
||||||
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||||
CLEANFILES += libgrub.pp
|
CLEANFILES += libgrub.pp
|
||||||
|
|
|
@ -3,7 +3,7 @@ AutoGen definitions Makefile.tpl;
|
||||||
library = {
|
library = {
|
||||||
name = libgrubkern.a;
|
name = libgrubkern.a;
|
||||||
cflags = '$(CFLAGS_GNULIB)';
|
cflags = '$(CFLAGS_GNULIB)';
|
||||||
cppflags = '$(CPPFLAGS_GNULIB)';
|
cppflags = '$(CPPFLAGS_GNULIB) -I$(srcdir)/grub-core/lib/json';
|
||||||
|
|
||||||
common = util/misc.c;
|
common = util/misc.c;
|
||||||
common = grub-core/kern/command.c;
|
common = grub-core/kern/command.c;
|
||||||
|
@ -36,7 +36,9 @@ library = {
|
||||||
common = grub-core/kern/misc.c;
|
common = grub-core/kern/misc.c;
|
||||||
common = grub-core/kern/partition.c;
|
common = grub-core/kern/partition.c;
|
||||||
common = grub-core/lib/crypto.c;
|
common = grub-core/lib/crypto.c;
|
||||||
|
common = grub-core/lib/json/json.c;
|
||||||
common = grub-core/disk/luks.c;
|
common = grub-core/disk/luks.c;
|
||||||
|
common = grub-core/disk/luks2.c;
|
||||||
common = grub-core/disk/geli.c;
|
common = grub-core/disk/geli.c;
|
||||||
common = grub-core/disk/cryptodisk.c;
|
common = grub-core/disk/cryptodisk.c;
|
||||||
common = grub-core/disk/AFSplitter.c;
|
common = grub-core/disk/AFSplitter.c;
|
||||||
|
@ -139,7 +141,7 @@ library = {
|
||||||
common = grub-core/lib/crc.c;
|
common = grub-core/lib/crc.c;
|
||||||
common = grub-core/lib/adler32.c;
|
common = grub-core/lib/adler32.c;
|
||||||
common = grub-core/lib/crc64.c;
|
common = grub-core/lib/crc64.c;
|
||||||
common = grub-core/normal/datetime.c;
|
common = grub-core/lib/datetime.c;
|
||||||
common = grub-core/normal/misc.c;
|
common = grub-core/normal/misc.c;
|
||||||
common = grub-core/partmap/acorn.c;
|
common = grub-core/partmap/acorn.c;
|
||||||
common = grub-core/partmap/amiga.c;
|
common = grub-core/partmap/amiga.c;
|
||||||
|
@ -240,8 +242,19 @@ program = {
|
||||||
|
|
||||||
common = util/grub-editenv.c;
|
common = util/grub-editenv.c;
|
||||||
common = util/editenv.c;
|
common = util/editenv.c;
|
||||||
|
common = util/grub-install-common.c;
|
||||||
common = grub-core/osdep/init.c;
|
common = grub-core/osdep/init.c;
|
||||||
|
common = grub-core/osdep/compress.c;
|
||||||
|
extra_dist = grub-core/osdep/unix/compress.c;
|
||||||
|
extra_dist = grub-core/osdep/basic/compress.c;
|
||||||
|
common = util/mkimage.c;
|
||||||
|
common = util/grub-mkimage32.c;
|
||||||
|
common = util/grub-mkimage64.c;
|
||||||
|
common = grub-core/osdep/config.c;
|
||||||
|
common = util/config.c;
|
||||||
|
common = util/resolve.c;
|
||||||
|
|
||||||
|
ldadd = '$(LIBLZMA)';
|
||||||
ldadd = libgrubmods.a;
|
ldadd = libgrubmods.a;
|
||||||
ldadd = libgrubgcry.a;
|
ldadd = libgrubgcry.a;
|
||||||
ldadd = libgrubkern.a;
|
ldadd = libgrubkern.a;
|
||||||
|
@ -502,6 +515,12 @@ script = {
|
||||||
installdir = grubconf;
|
installdir = grubconf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script = {
|
||||||
|
name = '30_uefi-firmware';
|
||||||
|
common = util/grub.d/30_uefi-firmware.in;
|
||||||
|
installdir = grubconf;
|
||||||
|
};
|
||||||
|
|
||||||
script = {
|
script = {
|
||||||
name = '40_custom';
|
name = '40_custom';
|
||||||
common = util/grub.d/40_custom.in;
|
common = util/grub.d/40_custom.in;
|
||||||
|
|
|
@ -13,7 +13,7 @@ fi
|
||||||
export LC_COLLATE=C
|
export LC_COLLATE=C
|
||||||
unset LC_ALL
|
unset LC_ALL
|
||||||
|
|
||||||
find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' ! -ipath './gnulib/*' ! -iname './grub-core/lib/gnulib/*' |sort > po/POTFILES.in
|
find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' ! -ipath './gnulib/*' ! -ipath './grub-core/lib/gnulib/*' |sort > po/POTFILES.in
|
||||||
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
|
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
|
||||||
|
|
||||||
echo "Importing unicode..."
|
echo "Importing unicode..."
|
||||||
|
|
|
@ -23,6 +23,7 @@ GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263
|
||||||
# directly.
|
# directly.
|
||||||
gnulib_modules="
|
gnulib_modules="
|
||||||
argp
|
argp
|
||||||
|
base64
|
||||||
error
|
error
|
||||||
fnmatch
|
fnmatch
|
||||||
getdelim
|
getdelim
|
||||||
|
@ -78,10 +79,18 @@ cp -a INSTALL INSTALL.grub
|
||||||
|
|
||||||
bootstrap_post_import_hook () {
|
bootstrap_post_import_hook () {
|
||||||
set -e
|
set -e
|
||||||
for patchname in fix-null-deref fix-width no-abort; do
|
for patchname in fix-base64 fix-null-deref fix-width no-abort; do
|
||||||
patch -d grub-core/lib/gnulib -p2 \
|
patch -d grub-core/lib/gnulib -p2 \
|
||||||
< "grub-core/lib/gnulib-patches/$patchname.patch"
|
< "grub-core/lib/gnulib-patches/$patchname.patch"
|
||||||
done
|
done
|
||||||
|
for patchname in \
|
||||||
|
0001-Support-POTFILES-shell \
|
||||||
|
0002-Handle-gettext_printf-shell-function \
|
||||||
|
0003-Make-msgfmt-output-in-little-endian \
|
||||||
|
0004-Use-SHELL-rather-than-bin-sh; do
|
||||||
|
patch -d po -p3 \
|
||||||
|
< "po/gettext-patches/$patchname.patch"
|
||||||
|
done
|
||||||
FROM_BOOTSTRAP=1 ./autogen.sh
|
FROM_BOOTSTRAP=1 ./autogen.sh
|
||||||
set +e # bootstrap expects this
|
set +e # bootstrap expects this
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ EXTRA_DIST += grub-core/gensymlist.sh
|
||||||
EXTRA_DIST += grub-core/genemuinit.sh
|
EXTRA_DIST += grub-core/genemuinit.sh
|
||||||
EXTRA_DIST += grub-core/genemuinitheader.sh
|
EXTRA_DIST += grub-core/genemuinitheader.sh
|
||||||
|
|
||||||
|
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-base64.patch
|
||||||
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch
|
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch
|
||||||
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch
|
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch
|
||||||
EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch
|
EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch
|
||||||
|
@ -110,6 +111,21 @@ EXTRA_DIST += grub-core/osdep/windows/password.c
|
||||||
EXTRA_DIST += grub-core/osdep/windows/random.c
|
EXTRA_DIST += grub-core/osdep/windows/random.c
|
||||||
EXTRA_DIST += grub-core/osdep/windows/sleep.c
|
EXTRA_DIST += grub-core/osdep/windows/sleep.c
|
||||||
|
|
||||||
|
EXTRA_DIST += po/gettext-patches/0001-Support-POTFILES-shell.patch
|
||||||
|
EXTRA_DIST += po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch
|
||||||
|
EXTRA_DIST += po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch
|
||||||
|
EXTRA_DIST += po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch
|
||||||
|
|
||||||
|
EXTRA_DIST += po/POTFILES-shell.in
|
||||||
|
EXTRA_DIST += po/README
|
||||||
|
EXTRA_DIST += po/Rules-translit
|
||||||
|
EXTRA_DIST += po/Rules-windowsdir
|
||||||
|
EXTRA_DIST += po/arabic.sed
|
||||||
|
EXTRA_DIST += po/cyrillic.sed
|
||||||
|
EXTRA_DIST += po/greek.sed
|
||||||
|
EXTRA_DIST += po/grub.d.sed
|
||||||
|
EXTRA_DIST += po/hebrew.sed
|
||||||
|
|
||||||
EXTRA_DIST += tests/dfly-mbr-mbexample.mbr.img.gz
|
EXTRA_DIST += tests/dfly-mbr-mbexample.mbr.img.gz
|
||||||
EXTRA_DIST += tests/dfly-mbr-mbexample.dfly.img.gz
|
EXTRA_DIST += tests/dfly-mbr-mbexample.dfly.img.gz
|
||||||
|
|
||||||
|
|
87
configure.ac
87
configure.ac
|
@ -26,12 +26,15 @@ dnl This is necessary because the target type in autoconf does not
|
||||||
dnl describe such a system very well.
|
dnl describe such a system very well.
|
||||||
dnl
|
dnl
|
||||||
dnl The current strategy is to use variables with no prefix (such as
|
dnl The current strategy is to use variables with no prefix (such as
|
||||||
dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_"
|
dnl CC, CFLAGS, etc.) for the host and target type, variables with
|
||||||
dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
|
dnl prefix "BUILD_" (such as BUILD_CC, BUILD_CFLAGS, etc.) for the
|
||||||
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
|
dnl build type, variables with prefix "HOST_" (such as HOST_CC,
|
||||||
dnl used for the target type. See INSTALL for full list of variables.
|
dnl HOST_CFLAGS, etc.) for the host type and variables with the prefix
|
||||||
|
dnl "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for
|
||||||
|
dnl the target type. See INSTALL for full list of variables and
|
||||||
|
dnl description of the relationships between them.
|
||||||
|
|
||||||
AC_INIT([GRUB],[2.04],[bug-grub@gnu.org])
|
AC_INIT([GRUB],[2.05],[bug-grub@gnu.org])
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
|
||||||
|
@ -77,9 +80,15 @@ grub_TRANSFORM([grub-file])
|
||||||
|
|
||||||
# Optimization flag. Allow user to override.
|
# Optimization flag. Allow user to override.
|
||||||
if test "x$TARGET_CFLAGS" = x; then
|
if test "x$TARGET_CFLAGS" = x; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -Os"
|
TARGET_CFLAGS=-Os
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Enable support for "restrict" keyword and other
|
||||||
|
# features from gnu99 C language standard.
|
||||||
|
BUILD_CFLAGS="-std=gnu99 $BUILD_CFLAGS"
|
||||||
|
HOST_CFLAGS="-std=gnu99 $HOST_CFLAGS"
|
||||||
|
TARGET_CFLAGS="-std=gnu99 $TARGET_CFLAGS"
|
||||||
|
|
||||||
# Default HOST_CPPFLAGS
|
# Default HOST_CPPFLAGS
|
||||||
HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
|
HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
|
||||||
HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
|
HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
|
||||||
|
@ -562,6 +571,24 @@ CPPFLAGS="$TARGET_CPPFLAGS"
|
||||||
LDFLAGS="$TARGET_LDFLAGS"
|
LDFLAGS="$TARGET_LDFLAGS"
|
||||||
LIBS=""
|
LIBS=""
|
||||||
|
|
||||||
|
if test "x$target_m32" = x1; then
|
||||||
|
# Force 32-bit mode.
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -m32"
|
||||||
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32"
|
||||||
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32"
|
||||||
|
TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
|
||||||
|
TARGET_MODULE_FORMAT="elf32"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$target_m64" = x1; then
|
||||||
|
# Force 64-bit mode.
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -m64"
|
||||||
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64"
|
||||||
|
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64"
|
||||||
|
TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
|
||||||
|
TARGET_MODULE_FORMAT="elf64"
|
||||||
|
fi
|
||||||
|
|
||||||
# debug flags.
|
# debug flags.
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations"
|
TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations"
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g"
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g"
|
||||||
|
@ -750,24 +777,6 @@ if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -march=i386"
|
TARGET_CFLAGS="$TARGET_CFLAGS -march=i386"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$target_m32" = x1; then
|
|
||||||
# Force 32-bit mode.
|
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -m32"
|
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32"
|
|
||||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32"
|
|
||||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -m32"
|
|
||||||
TARGET_MODULE_FORMAT="elf32"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x$target_m64" = x1; then
|
|
||||||
# Force 64-bit mode.
|
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -m64"
|
|
||||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64"
|
|
||||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64"
|
|
||||||
TARGET_LDFLAGS="$TARGET_LDFLAGS -m64"
|
|
||||||
TARGET_MODULE_FORMAT="elf64"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then
|
if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3"
|
TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3"
|
||||||
fi
|
fi
|
||||||
|
@ -854,6 +863,11 @@ if test x"$platform" != xemu ; then
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||||
[grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], [])
|
[grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], [])
|
||||||
fi
|
fi
|
||||||
|
if test "x$target_cpu" = xsh4; then
|
||||||
|
CFLAGS="$TARGET_CFLAGS -m4-nofpu -Werror"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||||
|
[grub_cv_target_cc_soft_float="-m4-nofpu"], [])
|
||||||
|
fi
|
||||||
for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \
|
for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \
|
||||||
"-Xclang -msoft-float -Xclang -no-implicit-float" \
|
"-Xclang -msoft-float -Xclang -no-implicit-float" \
|
||||||
"-Xclang -msoft-float" "-msoft-float"; do
|
"-Xclang -msoft-float" "-msoft-float"; do
|
||||||
|
@ -999,6 +1013,17 @@ if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
|
TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Do not generate .ident sections.
|
||||||
|
AC_CACHE_CHECK([whether -fno-ident works], [grub_cv_cc_fno_ident], [
|
||||||
|
CFLAGS="$TARGET_CFLAGS -fno-ident"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||||
|
[grub_cv_cc_fno_ident=yes],
|
||||||
|
[grub_cv_cc_fno_ident=no])
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "x$grub_cv_cc_fno_ident" = xyes; then
|
||||||
|
TARGET_CFLAGS="$TARGET_CFLAGS -fno-ident"
|
||||||
|
fi
|
||||||
|
|
||||||
CFLAGS="$TARGET_CFLAGS"
|
CFLAGS="$TARGET_CFLAGS"
|
||||||
|
|
||||||
|
@ -1198,7 +1223,8 @@ if test "x$target_cpu" = xarm; then
|
||||||
AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [
|
AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [
|
||||||
grub_cv_target_cc_mno_movt=no
|
grub_cv_target_cc_mno_movt=no
|
||||||
for cand in "-mno-movt" \
|
for cand in "-mno-movt" \
|
||||||
"-mllvm -arm-use-movt=0"; do
|
"-mllvm -arm-use-movt=0" \
|
||||||
|
"-mword-relocations"; do
|
||||||
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
|
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
@ -1251,6 +1277,7 @@ grub_CHECK_LINK_PIE
|
||||||
# `-fPIE' or '-fpie' and '-pie' in the default specs.
|
# `-fPIE' or '-fpie' and '-pie' in the default specs.
|
||||||
if [ x"$pie_possible" = xyes ]; then
|
if [ x"$pie_possible" = xyes ]; then
|
||||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
|
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
|
||||||
|
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -fno-PIE -fno-pie"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then
|
if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then
|
||||||
|
@ -1358,7 +1385,7 @@ fi
|
||||||
|
|
||||||
# Check for libgcc symbols
|
# Check for libgcc symbols
|
||||||
if test x"$platform" = xemu; then
|
if test x"$platform" = xemu; then
|
||||||
AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms)
|
AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __clzdi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$TARGET_APPLE_LINKER" = x1 ; then
|
if test "x$TARGET_APPLE_LINKER" = x1 ; then
|
||||||
|
@ -1435,9 +1462,11 @@ LIBS="$tmp_LIBS"
|
||||||
# Memory manager debugging.
|
# Memory manager debugging.
|
||||||
AC_ARG_ENABLE([mm-debug],
|
AC_ARG_ENABLE([mm-debug],
|
||||||
AS_HELP_STRING([--enable-mm-debug],
|
AS_HELP_STRING([--enable-mm-debug],
|
||||||
[include memory manager debugging]),
|
[include memory manager debugging]))
|
||||||
[AC_DEFINE([MM_DEBUG], [1],
|
if test x$enable_mm_debug = xyes; then
|
||||||
[Define to 1 if you enable memory manager debugging.])])
|
AC_DEFINE([MM_DEBUG], [1],
|
||||||
|
[Define to 1 if you enable memory manager debugging.])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE([cache-stats],
|
AC_ARG_ENABLE([cache-stats],
|
||||||
AS_HELP_STRING([--enable-cache-stats],
|
AS_HELP_STRING([--enable-cache-stats],
|
||||||
|
|
|
@ -490,6 +490,8 @@ to update it.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Gnulib::
|
* Gnulib::
|
||||||
|
* jsmn::
|
||||||
|
* minilzo::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Gnulib
|
@node Gnulib
|
||||||
|
@ -545,6 +547,41 @@ AC_SYS_LARGEFILE
|
||||||
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
It will also be necessary to adjust the patches in
|
||||||
|
@file{po/gettext-patches/} to apply to an older version of gettext.
|
||||||
|
|
||||||
|
@node jsmn
|
||||||
|
@section jsmn
|
||||||
|
|
||||||
|
jsmn is a minimalistic JSON parser which is implemented in a single header file
|
||||||
|
@file{jsmn.h}. To import a different version of the jsmn parser, you may simply
|
||||||
|
download the @file{jsmn.h} header from the desired tag or commit to the target
|
||||||
|
directory:
|
||||||
|
|
||||||
|
@example
|
||||||
|
curl -L https://raw.githubusercontent.com/zserge/jsmn/v1.1.0/jsmn.h \
|
||||||
|
-o grub-core/lib/json/jsmn.h
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@node minilzo
|
||||||
|
@section minilzo
|
||||||
|
|
||||||
|
miniLZO is a very lightweight subset of the LZO library intended for easy
|
||||||
|
inclusion in other projects. It is generated automatically from the LZO
|
||||||
|
source code and contains the most important LZO functions.
|
||||||
|
|
||||||
|
To upgrade to a new version of the miniLZO library, download the release
|
||||||
|
tarball and copy the files into the target directory:
|
||||||
|
|
||||||
|
@example
|
||||||
|
curl -L -O http://www.oberhumer.com/opensource/lzo/download/minilzo-2.08.tar.gz
|
||||||
|
tar -zxf minilzo-2.08.tar.gz
|
||||||
|
rm minilzo-2.08/testmini.c
|
||||||
|
rm -r grub-core/lib/minilzo/*
|
||||||
|
cp minilzo-2.08/*.[hc] grub-core/lib/minilzo
|
||||||
|
rm -r minilzo-2.08*
|
||||||
|
@end example
|
||||||
|
|
||||||
@node Porting
|
@node Porting
|
||||||
@chapter Porting
|
@chapter Porting
|
||||||
|
|
||||||
|
|
321
docs/grub.texi
321
docs/grub.texi
|
@ -894,6 +894,7 @@ magic.
|
||||||
@menu
|
@menu
|
||||||
* General boot methods:: How to boot OSes with GRUB generally
|
* General boot methods:: How to boot OSes with GRUB generally
|
||||||
* Loopback booting:: Notes on booting from loopbacks
|
* Loopback booting:: Notes on booting from loopbacks
|
||||||
|
* LVM cache booting:: Notes on booting from LVM cache logical volume
|
||||||
* OS-specific notes:: Notes on some operating systems
|
* OS-specific notes:: Notes on some operating systems
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
@ -991,6 +992,26 @@ way. Please consider alternative boot methods like copying all files
|
||||||
from the image to actual partition. Consult your OS documentation for
|
from the image to actual partition. Consult your OS documentation for
|
||||||
more details
|
more details
|
||||||
|
|
||||||
|
@node LVM cache booting
|
||||||
|
@section Booting from LVM cache logical volume
|
||||||
|
|
||||||
|
The LVM cache logical volume is the logical volume consisting of the original
|
||||||
|
and the cache pool logical volume. The original is usually on a larger and
|
||||||
|
slower storage device while the cache pool is on a smaller and faster one. The
|
||||||
|
performance of the original volume can be improved by storing the frequently
|
||||||
|
used data on the cache pool to utilize the greater performance of faster
|
||||||
|
device.
|
||||||
|
|
||||||
|
GRUB boots from LVM cache logical volume merely by reading it's original
|
||||||
|
logical volume so that dirty data in cache pool volume is disregarded. This is
|
||||||
|
not a problem for "writethrough" cache mode as it ensures that any data written
|
||||||
|
will be stored both on the cache and the origin LV. For the other cache mode
|
||||||
|
"writeback", which delays writing from the cache pool back to the origin LV to
|
||||||
|
boost performance, GRUB may fail to boot in the wake of accidental power outage
|
||||||
|
due to it's inability to assemble the cache device for reading the required
|
||||||
|
dirty data left behind. The situation will be improved after adding full
|
||||||
|
support to the LVM cache logical volume in the future.
|
||||||
|
|
||||||
@node OS-specific notes
|
@node OS-specific notes
|
||||||
@section Some caveats on OS-specific issues
|
@section Some caveats on OS-specific issues
|
||||||
|
|
||||||
|
@ -1093,12 +1114,6 @@ grub> @kbd{initrd16 /initrd}
|
||||||
Finally, run the command @command{boot} (@pxref{boot}).
|
Finally, run the command @command{boot} (@pxref{boot}).
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
@strong{Caution:} If you use an initrd and specify the @samp{mem=}
|
|
||||||
option to the kernel to let it use less than actual memory size, you
|
|
||||||
will also have to specify the same memory size to GRUB. To let GRUB know
|
|
||||||
the size, run the command @command{uppermem} @emph{before} loading the
|
|
||||||
kernel. @xref{uppermem}, for more information.
|
|
||||||
|
|
||||||
|
|
||||||
@node NetBSD
|
@node NetBSD
|
||||||
@subsection NetBSD
|
@subsection NetBSD
|
||||||
|
@ -1309,12 +1324,12 @@ menu and then wait for the timeout set by @samp{GRUB_TIMEOUT} to expire
|
||||||
before booting the default entry. Pressing a key interrupts the timeout.
|
before booting the default entry. Pressing a key interrupts the timeout.
|
||||||
|
|
||||||
If this option is set to @samp{countdown} or @samp{hidden}, then, before
|
If this option is set to @samp{countdown} or @samp{hidden}, then, before
|
||||||
displaying the menu, GRUB will wait for the timeout set by
|
displaying the menu, GRUB will wait for the timeout set by @samp{GRUB_TIMEOUT}
|
||||||
@samp{GRUB_TIMEOUT} to expire. If @key{ESC} is pressed during that time, it
|
to expire. If @key{ESC} or @key{F4} are pressed, or @key{SHIFT} is held down
|
||||||
will display the menu and wait for input. If a hotkey associated with a
|
during that time, it will display the menu and wait for input. If a hotkey
|
||||||
menu entry is pressed, it will boot the associated menu entry immediately.
|
associated with a menu entry is pressed, it will boot the associated menu entry
|
||||||
If the timeout expires before either of these happens, it will boot the
|
immediately. If the timeout expires before either of these happens, it will
|
||||||
default entry. In the @samp{countdown} case, it will show a one-line
|
boot the default entry. In the @samp{countdown} case, it will show a one-line
|
||||||
indication of the remaining time.
|
indication of the remaining time.
|
||||||
|
|
||||||
@item GRUB_DEFAULT_BUTTON
|
@item GRUB_DEFAULT_BUTTON
|
||||||
|
@ -1441,6 +1456,15 @@ enable the use of partition UUIDs, set this option to @samp{false}.
|
||||||
If this option is set to @samp{true}, disable the generation of recovery
|
If this option is set to @samp{true}, disable the generation of recovery
|
||||||
mode menu entries.
|
mode menu entries.
|
||||||
|
|
||||||
|
@item GRUB_DISABLE_UUID
|
||||||
|
Normally, @command{grub-mkconfig} will generate menu entries that use
|
||||||
|
universally-unique identifiers (UUIDs) to identify various filesystems to
|
||||||
|
search for files. This is usually more reliable, but in some cases it may
|
||||||
|
not be appropriate. To disable this use of UUIDs, set this option to
|
||||||
|
@samp{true}. Setting this option to @samp{true}, will also set the options
|
||||||
|
@samp{GRUB_DISABLE_LINUX_UUID} and @samp{GRUB_DISABLE_LINUX_PARTUUID} to
|
||||||
|
@samp{true}, unless they have been explicilty set to @samp{false}.
|
||||||
|
|
||||||
@item GRUB_VIDEO_BACKEND
|
@item GRUB_VIDEO_BACKEND
|
||||||
If graphical video support is required, either because the @samp{gfxterm}
|
If graphical video support is required, either because the @samp{gfxterm}
|
||||||
graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set,
|
graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set,
|
||||||
|
@ -1495,7 +1519,7 @@ Normally, @command{grub-mkconfig} will generate top level menu entry for
|
||||||
the kernel with highest version number and put all other found kernels
|
the kernel with highest version number and put all other found kernels
|
||||||
or alternative menu entries for recovery mode in submenu. For entries returned
|
or alternative menu entries for recovery mode in submenu. For entries returned
|
||||||
by @command{os-prober} first entry will be put on top level and all others
|
by @command{os-prober} first entry will be put on top level and all others
|
||||||
in submenu. If this option is set to @samp{y}, flat menu with all entries
|
in submenu. If this option is set to @samp{true}, flat menu with all entries
|
||||||
on top level will be generated instead. Changing this option will require
|
on top level will be generated instead. Changing this option will require
|
||||||
changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback})
|
changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback})
|
||||||
and @samp{default} (@pxref{default}) environment variables as well as saved
|
and @samp{default} (@pxref{default}) environment variables as well as saved
|
||||||
|
@ -1529,16 +1553,16 @@ configurations, but have better replacements:
|
||||||
|
|
||||||
@table @samp
|
@table @samp
|
||||||
@item GRUB_HIDDEN_TIMEOUT
|
@item GRUB_HIDDEN_TIMEOUT
|
||||||
Wait this many seconds before displaying the menu. If @key{ESC} is pressed
|
Wait this many seconds before displaying the menu. If @key{ESC} or @key{F4} are
|
||||||
during that time, display the menu and wait for input according to
|
pressed, or @key{SHIFT} is held down during that time, display the menu and wait
|
||||||
@samp{GRUB_TIMEOUT}. If a hotkey associated with a menu entry is pressed,
|
for input according to @samp{GRUB_TIMEOUT}. If a hotkey associated with a menu
|
||||||
boot the associated menu entry immediately. If the timeout expires before
|
entry is pressed, boot the associated menu entry immediately. If the timeout
|
||||||
either of these happens, display the menu for the number of seconds
|
expires before either of these happens, display the menu for the number of
|
||||||
specified in @samp{GRUB_TIMEOUT} before booting the default entry.
|
seconds specified in @samp{GRUB_TIMEOUT} before booting the default entry.
|
||||||
|
|
||||||
If you set @samp{GRUB_HIDDEN_TIMEOUT}, you should also set
|
If you set @samp{GRUB_HIDDEN_TIMEOUT}, you should also set
|
||||||
@samp{GRUB_TIMEOUT=0} so that the menu is not displayed at all unless
|
@samp{GRUB_TIMEOUT=0} so that the menu is not displayed at all unless
|
||||||
@key{ESC} is pressed.
|
@key{ESC} or @key{F4} are pressed, or @key{SHIFT} is held down.
|
||||||
|
|
||||||
This option is unset by default, and is deprecated in favour of the less
|
This option is unset by default, and is deprecated in favour of the less
|
||||||
confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or
|
confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or
|
||||||
|
@ -2486,6 +2510,57 @@ grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i38
|
||||||
Then follow instructions printed out by grub-mknetdir on configuring your DHCP
|
Then follow instructions printed out by grub-mknetdir on configuring your DHCP
|
||||||
server.
|
server.
|
||||||
|
|
||||||
|
The grub.cfg file is placed in the same directory as the path output by
|
||||||
|
grub-mknetdir hereafter referred to as FWPATH. GRUB will search for its
|
||||||
|
configuration files in order using the following rules where the appended
|
||||||
|
value corresponds to a value on the client machine.
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
@samp{(FWPATH)}/grub.cfg-@samp{(UUID OF MACHINE)}
|
||||||
|
@samp{(FWPATH)}/grub.cfg-@samp{(MAC ADDRESS OF NIC)}
|
||||||
|
@samp{(FWPATH)}/grub.cfg-@samp{(IPv4 OR IPv6 ADDRESS)}
|
||||||
|
@samp{(FWPATH)}/grub.cfg
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The UUID is the Client Machine Identifier Option Definition as specified in
|
||||||
|
RFC 4578. The client will only attempt to loouk up a UUID config file if it
|
||||||
|
was provided by the DHCP server.
|
||||||
|
|
||||||
|
The client will only attempt to look up an IPv6 address config once, however,
|
||||||
|
it will try the IPv4 multiple times. The concrete example below shows what
|
||||||
|
would happen under the IPv4 case.
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
UUID: 7726a678-7fc0-4853-a4f6-c85ac36a120a
|
||||||
|
MAC: 52:54:00:ec:33:81
|
||||||
|
IPV4: 10.0.0.130 (0A000082)
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@example
|
||||||
|
@group
|
||||||
|
@samp{(FWPATH)}/grub.cfg-7726a678-7fc0-4853-a4f6-c85ac36a120a
|
||||||
|
@samp{(FWPATH)}/grub.cfg-52-54-00-ec-33-81
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A000082
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A00008
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A0000
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A000
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A00
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A0
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0A
|
||||||
|
@samp{(FWPATH)}/grub.cfg-0
|
||||||
|
@samp{(FWPATH)}/grub.cfg
|
||||||
|
@end group
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This feature is enabled by default but it can be disabled by setting the
|
||||||
|
@samp{feature_net_search_cfg} to @samp{n}. Since this happens before the
|
||||||
|
configuration file is read by GRUB, this option has to be disabled in an
|
||||||
|
embedded configuration file (@pxref{Embedded configuration}).
|
||||||
|
|
||||||
After GRUB has started, files on the TFTP server will be accessible via the
|
After GRUB has started, files on the TFTP server will be accessible via the
|
||||||
@samp{(tftp)} device.
|
@samp{(tftp)} device.
|
||||||
|
|
||||||
|
@ -3930,7 +4005,6 @@ you forget a command, you can run the command @command{help}
|
||||||
* password_pbkdf2:: Set a hashed password
|
* password_pbkdf2:: Set a hashed password
|
||||||
* play:: Play a tune
|
* play:: Play a tune
|
||||||
* probe:: Retrieve device info
|
* probe:: Retrieve device info
|
||||||
* pxe_unload:: Unload the PXE environment
|
|
||||||
* rdmsr:: Read values from model-specific registers
|
* rdmsr:: Read values from model-specific registers
|
||||||
* read:: Read user input
|
* read:: Read user input
|
||||||
* reboot:: Reboot your computer
|
* reboot:: Reboot your computer
|
||||||
|
@ -3944,12 +4018,12 @@ you forget a command, you can run the command @command{help}
|
||||||
* sha256sum:: Compute or check SHA256 hash
|
* sha256sum:: Compute or check SHA256 hash
|
||||||
* sha512sum:: Compute or check SHA512 hash
|
* sha512sum:: Compute or check SHA512 hash
|
||||||
* sleep:: Wait for a specified number of seconds
|
* sleep:: Wait for a specified number of seconds
|
||||||
|
* smbios:: Retrieve SMBIOS information
|
||||||
* source:: Read a configuration file in same context
|
* source:: Read a configuration file in same context
|
||||||
* test:: Check file types and compare values
|
* test:: Check file types and compare values
|
||||||
* true:: Do nothing, successfully
|
* true:: Do nothing, successfully
|
||||||
* trust:: Add public key to list of trusted keys
|
* trust:: Add public key to list of trusted keys
|
||||||
* unset:: Unset an environment variable
|
* unset:: Unset an environment variable
|
||||||
* uppermem:: Set the upper memory size
|
|
||||||
@comment * vbeinfo:: List available video modes
|
@comment * vbeinfo:: List available video modes
|
||||||
* verify_detached:: Verify detached digital signature
|
* verify_detached:: Verify detached digital signature
|
||||||
* videoinfo:: List available video modes
|
* videoinfo:: List available video modes
|
||||||
|
@ -4201,8 +4275,9 @@ is requested interactively. Option @var{device} configures specific grub device
|
||||||
with specified @var{uuid}; option @option{-a} configures all detected encrypted
|
with specified @var{uuid}; option @option{-a} configures all detected encrypted
|
||||||
devices; option @option{-b} configures all geli containers that have boot flag set.
|
devices; option @option{-b} configures all geli containers that have boot flag set.
|
||||||
|
|
||||||
GRUB suports devices encrypted using LUKS and geli. Note that necessary modules (@var{luks} and @var{geli}) have to be loaded manually before this command can
|
GRUB suports devices encrypted using LUKS, LUKS2 and geli. Note that necessary
|
||||||
be used.
|
modules (@var{luks}, @var{luks2} and @var{geli}) have to be loaded manually
|
||||||
|
before this command can be used.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -4220,13 +4295,12 @@ hour, minute, and second unchanged.
|
||||||
|
|
||||||
|
|
||||||
@node devicetree
|
@node devicetree
|
||||||
@subsection linux
|
@subsection devicetree
|
||||||
|
|
||||||
@deffn Command devicetree file
|
@deffn Command devicetree file
|
||||||
Load a device tree blob (.dtb) from a filesystem, for later use by a Linux
|
Load a device tree blob (.dtb) from a filesystem, for later use by a Linux
|
||||||
kernel. Does not perform merging with any device tree supplied by firmware,
|
kernel. Does not perform merging with any device tree supplied by firmware,
|
||||||
but rather replaces it completely.
|
but rather replaces it completely.
|
||||||
@ref{GNU/Linux}.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@node distrust
|
@node distrust
|
||||||
|
@ -4423,22 +4497,22 @@ about each of the commands whose names begin with those @var{patterns}.
|
||||||
@node initrd
|
@node initrd
|
||||||
@subsection initrd
|
@subsection initrd
|
||||||
|
|
||||||
@deffn Command initrd file
|
@deffn Command initrd file [file @dots{}]
|
||||||
Load an initial ramdisk for a Linux kernel image, and set the appropriate
|
Load, in order, all initial ramdisks for a Linux kernel image, and set
|
||||||
parameters in the Linux setup area in memory. This may only be used after
|
the appropriate parameters in the Linux setup area in memory. This may only
|
||||||
the @command{linux} command (@pxref{linux}) has been run. See also
|
be used after the @command{linux} command (@pxref{linux}) has been run. See
|
||||||
@ref{GNU/Linux}.
|
also @ref{GNU/Linux}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node initrd16
|
@node initrd16
|
||||||
@subsection initrd16
|
@subsection initrd16
|
||||||
|
|
||||||
@deffn Command initrd16 file
|
@deffn Command initrd16 file [file @dots{}]
|
||||||
Load an initial ramdisk for a Linux kernel image to be booted in 16-bit
|
Load, in order, all initial ramdisks for a Linux kernel image to be booted in
|
||||||
mode, and set the appropriate parameters in the Linux setup area in memory.
|
16-bit mode, and set the appropriate parameters in the Linux setup area in
|
||||||
This may only be used after the @command{linux16} command (@pxref{linux16})
|
memory. This may only be used after the @command{linux16} command
|
||||||
has been run. See also @ref{GNU/Linux}.
|
(@pxref{linux16}) has been run. See also @ref{GNU/Linux}.
|
||||||
|
|
||||||
This command is only available on x86 systems.
|
This command is only available on x86 systems.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
@ -4646,7 +4720,7 @@ be reloaded after using this command (@pxref{module}).
|
||||||
Some kernels have known problems. You need to specify --quirk-* for those.
|
Some kernels have known problems. You need to specify --quirk-* for those.
|
||||||
--quirk-bad-kludge is a problem seen in several products that they include
|
--quirk-bad-kludge is a problem seen in several products that they include
|
||||||
loading kludge information with invalid data in ELF file. GRUB prior to 0.97
|
loading kludge information with invalid data in ELF file. GRUB prior to 0.97
|
||||||
and some custom builds prefered ELF information while 0.97 and GRUB 2
|
and some custom builds preferred ELF information while 0.97 and GRUB 2
|
||||||
use kludge. Use this option to ignore kludge.
|
use kludge. Use this option to ignore kludge.
|
||||||
Known affected systems: old Solaris, SkyOS.
|
Known affected systems: old Solaris, SkyOS.
|
||||||
|
|
||||||
|
@ -4771,19 +4845,11 @@ a rest.
|
||||||
@node probe
|
@node probe
|
||||||
@subsection probe
|
@subsection probe
|
||||||
|
|
||||||
@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label} device
|
@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label}|@option{--part-uuid} device
|
||||||
Retrieve device information. If option @option{--set} is given, assign result
|
Retrieve device information. If option @option{--set} is given, assign result
|
||||||
to variable @var{var}, otherwise print information on the screen.
|
to variable @var{var}, otherwise print information on the screen.
|
||||||
@end deffn
|
|
||||||
|
|
||||||
|
The option @option{--part-uuid} is currently only implemented for MSDOS and GPT formatted disks.
|
||||||
@node pxe_unload
|
|
||||||
@subsection pxe_unload
|
|
||||||
|
|
||||||
@deffn Command pxe_unload
|
|
||||||
Unload the PXE environment (@pxref{Network}).
|
|
||||||
|
|
||||||
This command is only available on PC BIOS systems.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -5077,9 +5143,84 @@ Alias for @code{hashsum --hash sha512 arg @dots{}}. See command @command{hashsum
|
||||||
|
|
||||||
@deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count
|
@deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count
|
||||||
Sleep for @var{count} seconds. If option @option{--interruptible} is given,
|
Sleep for @var{count} seconds. If option @option{--interruptible} is given,
|
||||||
allow @key{ESC} to interrupt sleep. With @option{--verbose} show countdown
|
allow pressing @key{ESC}, @key{F4} or holding down @key{SHIFT} to interrupt
|
||||||
of remaining seconds. Exit code is set to 0 if timeout expired and to 1
|
sleep. With @option{--verbose} show countdown of remaining seconds. Exit code
|
||||||
if timeout was interrupted by @key{ESC}.
|
is set to 0 if timeout expired and to 1 if timeout was interrupted using any
|
||||||
|
of the mentioned keys.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node smbios
|
||||||
|
@subsection smbios
|
||||||
|
|
||||||
|
@deffn Command smbios @
|
||||||
|
[@option{--type} @var{type}] @
|
||||||
|
[@option{--handle} @var{handle}] @
|
||||||
|
[@option{--match} @var{match}] @
|
||||||
|
(@option{--get-byte} | @option{--get-word} | @option{--get-dword} | @
|
||||||
|
@option{--get-qword} | @option{--get-string} | @option{--get-uuid}) @
|
||||||
|
@var{offset} @
|
||||||
|
[@option{--set} @var{variable}]
|
||||||
|
Retrieve SMBIOS information.
|
||||||
|
|
||||||
|
The @command{smbios} command returns the value of a field in an SMBIOS
|
||||||
|
structure. The following options determine which structure to select.
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Specifying @option{--type} will select structures with a matching
|
||||||
|
@var{type}. The type can be any integer from 0 to 255.
|
||||||
|
@item
|
||||||
|
Specifying @option{--handle} will select structures with a matching
|
||||||
|
@var{handle}. The handle can be any integer from 0 to 65535.
|
||||||
|
@item
|
||||||
|
Specifying @option{--match} will select structure number @var{match} in the
|
||||||
|
filtered list of structures; e.g. @code{smbios --type 4 --match 2} will select
|
||||||
|
the second Process Information (Type 4) structure. The list is always ordered
|
||||||
|
the same as the hardware's SMBIOS table. The match number must be a positive
|
||||||
|
integer. If unspecified, the first matching structure will be selected.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The remaining options determine which field in the selected SMBIOS structure to
|
||||||
|
return. Only one of these options may be specified at a time.
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
When given @option{--get-byte}, return the value of the byte
|
||||||
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
|
@item
|
||||||
|
When given @option{--get-word}, return the value of the word (two bytes)
|
||||||
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
|
@item
|
||||||
|
When given @option{--get-dword}, return the value of the dword (four bytes)
|
||||||
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
|
@item
|
||||||
|
When given @option{--get-qword}, return the value of the qword (eight bytes)
|
||||||
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
|
@item
|
||||||
|
When given @option{--get-string}, return the string with its index found
|
||||||
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
@item
|
||||||
|
When given @option{--get-uuid}, return the value of the UUID (sixteen bytes)
|
||||||
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as lower-case hyphenated hexadecimal digits, with the
|
||||||
|
first three fields as little-endian, and the rest printed byte-by-byte.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The default action is to print the value of the requested field to the console,
|
||||||
|
but a variable name can be specified with @option{--set} to store the value
|
||||||
|
instead of printing it.
|
||||||
|
|
||||||
|
For example, this will store and then display the system manufacturer's name.
|
||||||
|
|
||||||
|
@example
|
||||||
|
smbios --type 1 --get-string 4 --set system_manufacturer
|
||||||
|
echo $system_manufacturer
|
||||||
|
@end example
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -5199,12 +5340,6 @@ Unset the environment variable @var{envvar}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node uppermem
|
|
||||||
@subsection uppermem
|
|
||||||
|
|
||||||
This command is not yet implemented for GRUB 2, although it is planned.
|
|
||||||
|
|
||||||
|
|
||||||
@ignore
|
@ignore
|
||||||
@node vbeinfo
|
@node vbeinfo
|
||||||
@subsection vbeinfo
|
@subsection vbeinfo
|
||||||
|
@ -5288,10 +5423,11 @@ This command is only available on AArch64 systems.
|
||||||
* net_add_addr:: Add a network address
|
* net_add_addr:: Add a network address
|
||||||
* net_add_dns:: Add a DNS server
|
* net_add_dns:: Add a DNS server
|
||||||
* net_add_route:: Add routing entry
|
* net_add_route:: Add routing entry
|
||||||
* net_bootp:: Perform a bootp autoconfiguration
|
* net_bootp:: Perform a bootp/DHCP autoconfiguration
|
||||||
* net_del_addr:: Remove IP address from interface
|
* net_del_addr:: Remove IP address from interface
|
||||||
* net_del_dns:: Remove a DNS server
|
* net_del_dns:: Remove a DNS server
|
||||||
* net_del_route:: Remove a route entry
|
* net_del_route:: Remove a route entry
|
||||||
|
* net_dhcp:: Perform a DHCP autoconfiguration
|
||||||
* net_get_dhcp_option:: Retrieve DHCP options
|
* net_get_dhcp_option:: Retrieve DHCP options
|
||||||
* net_ipv6_autoconf:: Perform IPv6 autoconfiguration
|
* net_ipv6_autoconf:: Perform IPv6 autoconfiguration
|
||||||
* net_ls_addr:: List interfaces
|
* net_ls_addr:: List interfaces
|
||||||
|
@ -5338,8 +5474,44 @@ by @var{shortname} which can be used to remove it (@pxref{net_del_route}).
|
||||||
@subsection net_bootp
|
@subsection net_bootp
|
||||||
|
|
||||||
@deffn Command net_bootp [@var{card}]
|
@deffn Command net_bootp [@var{card}]
|
||||||
|
Alias for net_dhcp, for compatibility with older Grub versions. Will perform
|
||||||
|
the same DHCP handshake with potential fallback to BOOTP as the net_dhcp
|
||||||
|
command (@pxref{net_dhcp}).
|
||||||
|
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node net_del_addr
|
||||||
|
@subsection net_del_addr
|
||||||
|
|
||||||
|
@deffn Command net_del_addr @var{interface}
|
||||||
|
Remove configured @var{interface} with associated address.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node net_del_dns
|
||||||
|
@subsection net_del_dns
|
||||||
|
|
||||||
|
@deffn Command net_del_dns @var{address}
|
||||||
|
Remove @var{address} from list of servers used during name lookup.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node net_del_route
|
||||||
|
@subsection net_del_route
|
||||||
|
|
||||||
|
@deffn Command net_del_route @var{shortname}
|
||||||
|
Remove route entry identified by @var{shortname}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node net_dhcp
|
||||||
|
@subsection net_dhcp
|
||||||
|
|
||||||
|
@deffn Command net_dhcp [@var{card}]
|
||||||
Perform configuration of @var{card} using DHCP protocol. If no card name
|
Perform configuration of @var{card} using DHCP protocol. If no card name
|
||||||
is specified, try to configure all existing cards. If configuration was
|
is specified, try to configure all existing cards.
|
||||||
|
Falls back to the BOOTP protocol, if needed. If configuration was
|
||||||
successful, interface with name @var{card}@samp{:dhcp} and configured
|
successful, interface with name @var{card}@samp{:dhcp} and configured
|
||||||
address is added to @var{card}.
|
address is added to @var{card}.
|
||||||
@comment If server provided gateway information in
|
@comment If server provided gateway information in
|
||||||
|
@ -5366,35 +5538,17 @@ Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_rootpath}
|
||||||
@item 18 (Extensions Path)
|
@item 18 (Extensions Path)
|
||||||
Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_extensionspath}
|
Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_extensionspath}
|
||||||
(@pxref{net_@var{<interface>}_extensionspath}) to the value of option.
|
(@pxref{net_@var{<interface>}_extensionspath}) to the value of option.
|
||||||
|
@item 66 (TFTP Server Name)
|
||||||
|
Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_server_name}
|
||||||
|
(@pxref{net_@var{<interface>}_dhcp_server_name}) to the value of option.
|
||||||
|
@item 67 (Filename)
|
||||||
|
Sets environment variable @samp{net_}@var{<card>}@samp{_boot_file}
|
||||||
|
(@pxref{net_@var{<interface>}_boot_file}) to the value of option.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node net_del_addr
|
|
||||||
@subsection net_del_addr
|
|
||||||
|
|
||||||
@deffn Command net_del_addr @var{interface}
|
|
||||||
Remove configured @var{interface} with associated address.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
|
|
||||||
@node net_del_dns
|
|
||||||
@subsection net_del_dns
|
|
||||||
|
|
||||||
@deffn Command net_del_dns @var{address}
|
|
||||||
Remove @var{address} from list of servers used during name lookup.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
|
|
||||||
@node net_del_route
|
|
||||||
@subsection net_del_route
|
|
||||||
|
|
||||||
@deffn Command net_del_route @var{shortname}
|
|
||||||
Remove route entry identified by @var{shortname}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
|
|
||||||
@node net_get_dhcp_option
|
@node net_get_dhcp_option
|
||||||
@subsection net_get_dhcp_option
|
@subsection net_get_dhcp_option
|
||||||
|
|
||||||
|
@ -5612,7 +5766,8 @@ the GRUB command line, edit menu entries, and execute any menu entry. If
|
||||||
@samp{superusers} is set, then use of the command line and editing of menu
|
@samp{superusers} is set, then use of the command line and editing of menu
|
||||||
entries are automatically restricted to superusers. Setting @samp{superusers}
|
entries are automatically restricted to superusers. Setting @samp{superusers}
|
||||||
to empty string effectively disables both access to CLI and editing of menu
|
to empty string effectively disables both access to CLI and editing of menu
|
||||||
entries.
|
entries. Note: The environment variable needs to be exported to also affect
|
||||||
|
the section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||||
|
|
||||||
Other users may be allowed to execute specific menu entries by giving a list of
|
Other users may be allowed to execute specific menu entries by giving a list of
|
||||||
usernames (as above) using the @option{--users} option to the
|
usernames (as above) using the @option{--users} option to the
|
||||||
|
|
|
@ -766,7 +766,7 @@ def image(defn, platform):
|
||||||
if test x$(TARGET_APPLE_LINKER) = x1; then \
|
if test x$(TARGET_APPLE_LINKER) = x1; then \
|
||||||
$(MACHO2IMG) $< $@; \
|
$(MACHO2IMG) $< $@; \
|
||||||
else \
|
else \
|
||||||
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .ARM.exidx $< $@; \
|
$(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx $< $@; \
|
||||||
fi
|
fi
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
|
@ -950,7 +950,7 @@ module = {
|
||||||
module = {
|
module = {
|
||||||
name = shim_lock;
|
name = shim_lock;
|
||||||
common = commands/efi/shim_lock.c;
|
common = commands/efi/shim_lock.c;
|
||||||
enable = x86_64_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1097,6 +1097,21 @@ module = {
|
||||||
common = commands/sleep.c;
|
common = commands/sleep.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = smbios;
|
||||||
|
|
||||||
|
common = commands/smbios.c;
|
||||||
|
efi = commands/efi/smbios.c;
|
||||||
|
i386_pc = commands/i386/pc/smbios.c;
|
||||||
|
i386_coreboot = commands/i386/pc/smbios.c;
|
||||||
|
i386_multiboot = commands/i386/pc/smbios.c;
|
||||||
|
|
||||||
|
enable = efi;
|
||||||
|
enable = i386_pc;
|
||||||
|
enable = i386_coreboot;
|
||||||
|
enable = i386_multiboot;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = suspend;
|
name = suspend;
|
||||||
ieee1275 = commands/ieee1275/suspend.c;
|
ieee1275 = commands/ieee1275/suspend.c;
|
||||||
|
@ -1161,10 +1176,27 @@ module = {
|
||||||
common = disk/cryptodisk.c;
|
common = disk/cryptodisk.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = json;
|
||||||
|
common = lib/json/json.c;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = afsplitter;
|
||||||
|
common = disk/AFSplitter.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = luks;
|
name = luks;
|
||||||
common = disk/luks.c;
|
common = disk/luks.c;
|
||||||
common = disk/AFSplitter.c;
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = luks2;
|
||||||
|
common = disk/luks2.c;
|
||||||
|
common = lib/gnulib/base64.c;
|
||||||
|
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
|
||||||
|
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/json';
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1655,6 +1687,7 @@ module = {
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = datetime;
|
name = datetime;
|
||||||
|
common = lib/datetime.c;
|
||||||
cmos = lib/cmos_datetime.c;
|
cmos = lib/cmos_datetime.c;
|
||||||
efi = lib/efi/datetime.c;
|
efi = lib/efi/datetime.c;
|
||||||
uboot = lib/dummy/datetime.c;
|
uboot = lib/dummy/datetime.c;
|
||||||
|
@ -1667,7 +1700,6 @@ module = {
|
||||||
i386_xen_pvh = lib/xen/datetime.c;
|
i386_xen_pvh = lib/xen/datetime.c;
|
||||||
|
|
||||||
mips_arc = lib/arc/datetime.c;
|
mips_arc = lib/arc/datetime.c;
|
||||||
enable = noemu;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
@ -1894,7 +1926,6 @@ module = {
|
||||||
common = normal/autofs.c;
|
common = normal/autofs.c;
|
||||||
common = normal/color.c;
|
common = normal/color.c;
|
||||||
common = normal/completion.c;
|
common = normal/completion.c;
|
||||||
common = normal/datetime.c;
|
|
||||||
common = normal/menu.c;
|
common = normal/menu.c;
|
||||||
common = normal/menu_entry.c;
|
common = normal/menu_entry.c;
|
||||||
common = normal/menu_text.c;
|
common = normal/menu_text.c;
|
||||||
|
@ -2469,7 +2500,7 @@ module = {
|
||||||
name = tpm;
|
name = tpm;
|
||||||
common = commands/tpm.c;
|
common = commands/tpm.c;
|
||||||
efi = commands/efi/tpm.c;
|
efi = commands/efi/tpm.c;
|
||||||
enable = x86_64_efi;
|
enable = efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
|
|
|
@ -149,8 +149,8 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
||||||
grub_usb_set_configuration (dev, 1);
|
grub_usb_set_configuration (dev, 1);
|
||||||
|
|
||||||
dev->nports = hubdesc.portcnt;
|
dev->nports = hubdesc.portcnt;
|
||||||
dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
|
dev->children = grub_calloc (hubdesc.portcnt, sizeof (dev->children[0]));
|
||||||
dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0]));
|
dev->ports = grub_calloc (dev->nports, sizeof (dev->ports[0]));
|
||||||
if (!dev->children || !dev->ports)
|
if (!dev->children || !dev->ports)
|
||||||
{
|
{
|
||||||
grub_free (dev->children);
|
grub_free (dev->children);
|
||||||
|
@ -268,8 +268,8 @@ grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *d
|
||||||
|
|
||||||
/* Query the number of ports the root Hub has. */
|
/* Query the number of ports the root Hub has. */
|
||||||
hub->nports = controller->dev->hubports (controller);
|
hub->nports = controller->dev->hubports (controller);
|
||||||
hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports);
|
hub->devices = grub_calloc (hub->nports, sizeof (hub->devices[0]));
|
||||||
hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports);
|
hub->ports = grub_calloc (hub->nports, sizeof (hub->ports[0]));
|
||||||
if (!hub->devices || !hub->ports)
|
if (!hub->devices || !hub->ports)
|
||||||
{
|
{
|
||||||
grub_free (hub->devices);
|
grub_free (hub->devices);
|
||||||
|
|
|
@ -59,7 +59,8 @@ grub_cmd_date (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
for (; argc; argc--, args++)
|
for (; argc; argc--, args++)
|
||||||
{
|
{
|
||||||
char *p, c;
|
const char *p;
|
||||||
|
char c;
|
||||||
int m1, ofs, n, cur_mask;
|
int m1, ofs, n, cur_mask;
|
||||||
|
|
||||||
p = args[0];
|
p = args[0];
|
||||||
|
|
|
@ -40,6 +40,7 @@ static const struct guid_mapping guid_mappings[] =
|
||||||
{ GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID,
|
{ GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID,
|
||||||
"CRC32 GUIDED SECTION EXTRACTION"},
|
"CRC32 GUIDED SECTION EXTRACTION"},
|
||||||
{ GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID, "DEBUG IMAGE INFO"},
|
{ GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID, "DEBUG IMAGE INFO"},
|
||||||
|
{ GRUB_EFI_DEVICE_TREE_GUID, "DEVICE TREE"},
|
||||||
{ GRUB_EFI_DXE_SERVICES_TABLE_GUID, "DXE SERVICES"},
|
{ GRUB_EFI_DXE_SERVICES_TABLE_GUID, "DXE SERVICES"},
|
||||||
{ GRUB_EFI_HCDP_TABLE_GUID, "HCDP"},
|
{ GRUB_EFI_HCDP_TABLE_GUID, "HCDP"},
|
||||||
{ GRUB_EFI_HOB_LIST_GUID, "HOB LIST"},
|
{ GRUB_EFI_HOB_LIST_GUID, "HOB LIST"},
|
||||||
|
@ -48,6 +49,7 @@ static const struct guid_mapping guid_mappings[] =
|
||||||
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
|
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
|
||||||
{ GRUB_EFI_SAL_TABLE_GUID, "SAL"},
|
{ GRUB_EFI_SAL_TABLE_GUID, "SAL"},
|
||||||
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
|
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
|
||||||
|
{ GRUB_EFI_SMBIOS3_TABLE_GUID, "SMBIOS3"},
|
||||||
{ GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"},
|
{ GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"},
|
||||||
{ GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"},
|
{ GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"},
|
||||||
{ GRUB_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"},
|
{ GRUB_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"},
|
||||||
|
@ -71,7 +73,8 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
grub_printf ("Vendor: ");
|
grub_printf ("Vendor: ");
|
||||||
|
|
||||||
for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
|
for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
|
||||||
vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1);
|
/* Allocate extra 3 bytes to simplify math. */
|
||||||
|
vendor = grub_calloc (4, vendor_utf16 - st->firmware_vendor + 1);
|
||||||
if (!vendor)
|
if (!vendor)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
|
*grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
|
||||||
|
|
61
grub-core/commands/efi/smbios.c
Normal file
61
grub-core/commands/efi/smbios.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* smbios.c - get smbios tables. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#include <grub/efi/api.h>
|
||||||
|
|
||||||
|
struct grub_smbios_eps *
|
||||||
|
grub_machine_smbios_get_eps (void)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
static grub_efi_packed_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
|
||||||
|
|
||||||
|
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||||
|
{
|
||||||
|
grub_efi_packed_guid_t *guid =
|
||||||
|
&grub_efi_system_table->configuration_table[i].vendor_guid;
|
||||||
|
|
||||||
|
if (! grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_packed_guid_t)))
|
||||||
|
return (struct grub_smbios_eps *)
|
||||||
|
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_smbios_eps3 *
|
||||||
|
grub_machine_smbios_get_eps3 (void)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
static grub_efi_packed_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
|
||||||
|
|
||||||
|
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||||
|
{
|
||||||
|
grub_efi_packed_guid_t *guid =
|
||||||
|
&grub_efi_system_table->configuration_table[i].vendor_guid;
|
||||||
|
|
||||||
|
if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_packed_guid_t)))
|
||||||
|
return (struct grub_smbios_eps3 *)
|
||||||
|
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -119,103 +119,6 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_tpm1_execute (grub_efi_handle_t tpm_handle,
|
|
||||||
PassThroughToTPM_InputParamBlock *inbuf,
|
|
||||||
PassThroughToTPM_OutputParamBlock *outbuf)
|
|
||||||
{
|
|
||||||
grub_efi_status_t status;
|
|
||||||
grub_efi_tpm_protocol_t *tpm;
|
|
||||||
grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn);
|
|
||||||
grub_uint32_t outhdrsize =
|
|
||||||
sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut);
|
|
||||||
|
|
||||||
tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
||||||
|
|
||||||
if (!grub_tpm1_present (tpm))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* UEFI TPM protocol takes the raw operand block, no param block header. */
|
|
||||||
status = efi_call_5 (tpm->pass_through_to_tpm, tpm,
|
|
||||||
inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
|
|
||||||
outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case GRUB_EFI_SUCCESS:
|
|
||||||
return 0;
|
|
||||||
case GRUB_EFI_DEVICE_ERROR:
|
|
||||||
return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
|
||||||
case GRUB_EFI_INVALID_PARAMETER:
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
|
|
||||||
case GRUB_EFI_BUFFER_TOO_SMALL:
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
N_("Output buffer too small"));
|
|
||||||
case GRUB_EFI_NOT_FOUND:
|
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
|
||||||
default:
|
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_tpm2_execute (grub_efi_handle_t tpm_handle,
|
|
||||||
PassThroughToTPM_InputParamBlock *inbuf,
|
|
||||||
PassThroughToTPM_OutputParamBlock *outbuf)
|
|
||||||
{
|
|
||||||
grub_efi_status_t status;
|
|
||||||
grub_efi_tpm2_protocol_t *tpm;
|
|
||||||
grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn);
|
|
||||||
grub_uint32_t outhdrsize =
|
|
||||||
sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut);
|
|
||||||
|
|
||||||
tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
||||||
|
|
||||||
if (!grub_tpm2_present (tpm))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* UEFI TPM protocol takes the raw operand block, no param block header. */
|
|
||||||
status = efi_call_5 (tpm->submit_command, tpm,
|
|
||||||
inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn,
|
|
||||||
outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut);
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case GRUB_EFI_SUCCESS:
|
|
||||||
return 0;
|
|
||||||
case GRUB_EFI_DEVICE_ERROR:
|
|
||||||
return grub_error (GRUB_ERR_IO, N_("Command failed"));
|
|
||||||
case GRUB_EFI_INVALID_PARAMETER:
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter"));
|
|
||||||
case GRUB_EFI_BUFFER_TOO_SMALL:
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
N_("Output buffer too small"));
|
|
||||||
case GRUB_EFI_NOT_FOUND:
|
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
|
||||||
default:
|
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_err_t
|
|
||||||
grub_tpm_execute (PassThroughToTPM_InputParamBlock *inbuf,
|
|
||||||
PassThroughToTPM_OutputParamBlock *outbuf)
|
|
||||||
{
|
|
||||||
grub_efi_handle_t tpm_handle;
|
|
||||||
grub_uint8_t protocol_version;
|
|
||||||
|
|
||||||
/* Absence of a TPM isn't a failure. */
|
|
||||||
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (protocol_version == 1)
|
|
||||||
return grub_tpm1_execute (tpm_handle, inbuf, outbuf);
|
|
||||||
else
|
|
||||||
return grub_tpm2_execute (tpm_handle, inbuf, outbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||||
grub_size_t size, grub_uint8_t pcr,
|
grub_size_t size, grub_uint8_t pcr,
|
||||||
|
@ -247,6 +150,7 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||||
algorithm = TCG_ALG_SHA;
|
algorithm = TCG_ALG_SHA;
|
||||||
status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size,
|
status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size,
|
||||||
algorithm, event, &eventnum, &lastevent);
|
algorithm, event, &eventnum, &lastevent);
|
||||||
|
grub_free (event);
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
|
@ -297,6 +201,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||||
|
|
||||||
status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf,
|
status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf,
|
||||||
(grub_uint64_t) size, event);
|
(grub_uint64_t) size, event);
|
||||||
|
grub_free (event);
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
|
@ -317,7 +222,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_tpm_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||||
const char *description)
|
const char *description)
|
||||||
{
|
{
|
||||||
grub_efi_handle_t tpm_handle;
|
grub_efi_handle_t tpm_handle;
|
||||||
|
|
|
@ -27,7 +27,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
parse_args (int argc, char *argv[], int *byte, int *bit)
|
parse_args (int argc, char *argv[], int *byte, int *bit)
|
||||||
{
|
{
|
||||||
char *rest;
|
const char *rest;
|
||||||
|
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "address required");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "address required");
|
||||||
|
|
|
@ -132,7 +132,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *end;
|
const char *end;
|
||||||
unsigned tempo;
|
unsigned tempo;
|
||||||
struct note note;
|
struct note note;
|
||||||
int i;
|
int i;
|
||||||
|
|
52
grub-core/commands/i386/pc/smbios.c
Normal file
52
grub-core/commands/i386/pc/smbios.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* smbios.c - get smbios tables. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/acpi.h>
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
|
||||||
|
struct grub_smbios_eps *
|
||||||
|
grub_machine_smbios_get_eps (void)
|
||||||
|
{
|
||||||
|
grub_uint8_t *ptr;
|
||||||
|
|
||||||
|
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
|
||||||
|
|
||||||
|
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||||
|
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
||||||
|
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
|
||||||
|
return (struct grub_smbios_eps *) ptr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct grub_smbios_eps3 *
|
||||||
|
grub_machine_smbios_get_eps3 (void)
|
||||||
|
{
|
||||||
|
grub_uint8_t *ptr;
|
||||||
|
|
||||||
|
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
|
||||||
|
|
||||||
|
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||||
|
if (grub_memcmp (ptr, "_SM3_", 5) == 0
|
||||||
|
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
|
||||||
|
return (struct grub_smbios_eps3 *) ptr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -44,7 +44,7 @@ grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
{
|
{
|
||||||
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
|
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
|
||||||
grub_uint64_t value;
|
grub_uint64_t value;
|
||||||
char *ptr;
|
const char *ptr;
|
||||||
char buf[sizeof("1122334455667788")];
|
char buf[sizeof("1122334455667788")];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -37,7 +37,7 @@ grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char
|
||||||
{
|
{
|
||||||
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
|
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
|
||||||
grub_uint64_t value;
|
grub_uint64_t value;
|
||||||
char *ptr;
|
const char *ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The CPUID instruction should be used to determine whether MSRs
|
* The CPUID instruction should be used to determine whether MSRs
|
||||||
|
|
|
@ -35,24 +35,6 @@ static const struct grub_arg_option options[] =
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
|
||||||
grub_getkeystatus (void)
|
|
||||||
{
|
|
||||||
int status = 0;
|
|
||||||
grub_term_input_t term;
|
|
||||||
|
|
||||||
if (grub_term_poll_usb)
|
|
||||||
grub_term_poll_usb (0);
|
|
||||||
|
|
||||||
FOR_ACTIVE_TERM_INPUTS(term)
|
|
||||||
{
|
|
||||||
if (term->getkeystatus)
|
|
||||||
status |= term->getkeystatus (term);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_keystatus (grub_extcmd_context_t ctxt,
|
grub_cmd_keystatus (grub_extcmd_context_t ctxt,
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <grub/auth.h>
|
#include <grub/auth.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -104,13 +105,22 @@ legacy_file (const char *filename)
|
||||||
if (newsuffix)
|
if (newsuffix)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
goto fail_0;
|
||||||
|
}
|
||||||
|
|
||||||
t = suffix;
|
t = suffix;
|
||||||
suffix = grub_realloc (suffix, grub_strlen (suffix)
|
suffix = grub_realloc (suffix, sz);
|
||||||
+ grub_strlen (newsuffix) + 1);
|
|
||||||
if (!suffix)
|
if (!suffix)
|
||||||
{
|
{
|
||||||
grub_free (t);
|
grub_free (t);
|
||||||
|
|
||||||
|
fail_0:
|
||||||
grub_free (entrysrc);
|
grub_free (entrysrc);
|
||||||
grub_free (parsed);
|
grub_free (parsed);
|
||||||
grub_free (newsuffix);
|
grub_free (newsuffix);
|
||||||
|
@ -154,13 +164,22 @@ legacy_file (const char *filename)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
|
||||||
t = entrysrc;
|
t = entrysrc;
|
||||||
entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
|
entrysrc = grub_realloc (entrysrc, sz);
|
||||||
+ grub_strlen (parsed) + 1);
|
|
||||||
if (!entrysrc)
|
if (!entrysrc)
|
||||||
{
|
{
|
||||||
grub_free (t);
|
grub_free (t);
|
||||||
|
|
||||||
|
fail_1:
|
||||||
grub_free (parsed);
|
grub_free (parsed);
|
||||||
grub_free (suffix);
|
grub_free (suffix);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -314,7 +333,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||||
|
|
||||||
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
|
cutargs = grub_calloc (argc - 1, sizeof (cutargs[0]));
|
||||||
if (!cutargs)
|
if (!cutargs)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
cutargc = argc - 1;
|
cutargc = argc - 1;
|
||||||
|
@ -436,7 +455,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||||
{
|
{
|
||||||
char rbuf[3] = "-r";
|
char rbuf[3] = "-r";
|
||||||
bsdargc = cutargc + 2;
|
bsdargc = cutargc + 2;
|
||||||
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
|
bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0]));
|
||||||
if (!bsdargs)
|
if (!bsdargs)
|
||||||
{
|
{
|
||||||
err = grub_errno;
|
err = grub_errno;
|
||||||
|
@ -559,7 +578,7 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||||
"module");
|
"module");
|
||||||
|
|
||||||
newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
|
newargs = grub_calloc (argc + 1, sizeof (newargs[0]));
|
||||||
if (!newargs)
|
if (!newargs)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
|
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
|
||||||
|
|
|
@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Save argc, args to pass as parameters to block arg later. */
|
/* Save argc, args to pass as parameters to block arg later. */
|
||||||
menu_args = grub_malloc (sizeof (char*) * (argc + 1));
|
menu_args = grub_calloc (argc + 1, sizeof (char *));
|
||||||
if (! menu_args)
|
if (! menu_args)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
||||||
else
|
else
|
||||||
path_prefix = prefix;
|
path_prefix = prefix;
|
||||||
|
|
||||||
mods = grub_malloc (argc * sizeof (mods[0]));
|
mods = grub_calloc (argc, sizeof (mods[0]));
|
||||||
if (!mods)
|
if (!mods)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,13 @@ grub_parttool_register(const char *part_name,
|
||||||
for (nargs = 0; args[nargs].name != 0; nargs++);
|
for (nargs = 0; args[nargs].name != 0; nargs++);
|
||||||
cur->nargs = nargs;
|
cur->nargs = nargs;
|
||||||
cur->args = (struct grub_parttool_argdesc *)
|
cur->args = (struct grub_parttool_argdesc *)
|
||||||
grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
|
grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc));
|
||||||
|
if (!cur->args)
|
||||||
|
{
|
||||||
|
grub_free (cur);
|
||||||
|
curhandle--;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
grub_memcpy (cur->args, args,
|
grub_memcpy (cur->args, args,
|
||||||
(nargs + 1) * sizeof (struct grub_parttool_argdesc));
|
(nargs + 1) * sizeof (struct grub_parttool_argdesc));
|
||||||
|
|
||||||
|
@ -257,7 +263,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed = (int *) grub_zalloc (argc * sizeof (int));
|
parsed = (int *) grub_calloc (argc, sizeof (int));
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
if (! parsed[i])
|
if (! parsed[i])
|
||||||
|
@ -290,7 +296,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
ptool = cur;
|
ptool = cur;
|
||||||
pargs = (struct grub_parttool_args *)
|
pargs = (struct grub_parttool_args *)
|
||||||
grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));
|
grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args));
|
||||||
for (j = i; j < argc; j++)
|
for (j = i; j < argc; j++)
|
||||||
if (! parsed[j])
|
if (! parsed[j])
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,7 +86,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc, char **args)
|
int argc, char **args)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
char *ptr, *ptr2;
|
const char *ptr, *ptr2;
|
||||||
grub_uint8_t *ptro;
|
grub_uint8_t *ptro;
|
||||||
struct pbkdf2_password *pass;
|
struct pbkdf2_password *pass;
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
||||||
if (ctxt->state[0].set)
|
if (ctxt->state[0].set)
|
||||||
{
|
{
|
||||||
ptr = ctxt->state[0].arg;
|
ptr = ctxt->state[0].arg;
|
||||||
ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
|
ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff);
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -108,8 +108,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
||||||
if (*ptr != ':')
|
if (*ptr != ':')
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||||
ptr++;
|
ptr++;
|
||||||
ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
|
ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16;
|
||||||
<< 16;
|
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
else
|
else
|
||||||
|
@ -124,7 +123,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
||||||
|
|
||||||
ptr = ctxt->state[1].arg;
|
ptr = ctxt->state[1].arg;
|
||||||
optr = ptr;
|
optr = ptr;
|
||||||
ctx.bus = grub_strtoul (ptr, (char **) &ptr, 16);
|
ctx.bus = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -138,7 +137,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||||
ptr++;
|
ptr++;
|
||||||
optr = ptr;
|
optr = ptr;
|
||||||
ctx.device = grub_strtoul (ptr, (char **) &ptr, 16);
|
ctx.device = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -149,7 +148,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
||||||
if (*ptr == '.')
|
if (*ptr == '.')
|
||||||
{
|
{
|
||||||
ptr++;
|
ptr++;
|
||||||
ctx.function = grub_strtoul (ptr, (char **) &ptr, 16);
|
ctx.function = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
ctx.check_function = 1;
|
ctx.check_function = 1;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/device.h>
|
#include <grub/device.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
|
#include <grub/gpt_partition.h>
|
||||||
#include <grub/net.h>
|
#include <grub/net.h>
|
||||||
#include <grub/fs.h>
|
#include <grub/fs.h>
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/i386/pc/boot.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@ static const struct grub_arg_option options[] =
|
||||||
{"fs", 'f', 0, N_("Determine filesystem type."), 0, 0},
|
{"fs", 'f', 0, N_("Determine filesystem type."), 0, 0},
|
||||||
{"fs-uuid", 'u', 0, N_("Determine filesystem UUID."), 0, 0},
|
{"fs-uuid", 'u', 0, N_("Determine filesystem UUID."), 0, 0},
|
||||||
{"label", 'l', 0, N_("Determine filesystem label."), 0, 0},
|
{"label", 'l', 0, N_("Determine filesystem label."), 0, 0},
|
||||||
|
{"part-uuid", 0, 0, N_("Determine partition UUID."), 0, 0},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,6 +101,52 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
grub_device_close (dev);
|
grub_device_close (dev);
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
if (state[6].set)
|
||||||
|
{
|
||||||
|
/* AAAABBBB-CCCC-DDDD-EEEE-FFFFFFFFFFFF + null terminator */
|
||||||
|
char val[37] = "none";
|
||||||
|
if (dev->disk && dev->disk->partition)
|
||||||
|
{
|
||||||
|
struct grub_partition *p = dev->disk->partition;
|
||||||
|
grub_disk_t disk = grub_disk_open(dev->disk->name);
|
||||||
|
|
||||||
|
if (!disk)
|
||||||
|
return grub_errno;
|
||||||
|
if (grub_strcmp(dev->disk->partition->partmap->name, "gpt") == 0)
|
||||||
|
{
|
||||||
|
struct grub_gpt_partentry entry;
|
||||||
|
grub_gpt_part_guid_t *guid;
|
||||||
|
|
||||||
|
if (grub_disk_read(disk, p->offset, p->index, sizeof(entry), &entry))
|
||||||
|
return grub_errno;
|
||||||
|
guid = &entry.guid;
|
||||||
|
grub_snprintf (val, sizeof(val),
|
||||||
|
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
|
grub_le_to_cpu32 (guid->data1),
|
||||||
|
grub_le_to_cpu16 (guid->data2),
|
||||||
|
grub_le_to_cpu16 (guid->data3),
|
||||||
|
guid->data4[0], guid->data4[1], guid->data4[2],
|
||||||
|
guid->data4[3], guid->data4[4], guid->data4[5],
|
||||||
|
guid->data4[6], guid->data4[7]);
|
||||||
|
}
|
||||||
|
else if (grub_strcmp(dev->disk->partition->partmap->name, "msdos") == 0)
|
||||||
|
{
|
||||||
|
grub_uint32_t nt_disk_sig;
|
||||||
|
|
||||||
|
if (grub_disk_read(disk, 0, GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
|
||||||
|
sizeof(nt_disk_sig), &nt_disk_sig) == 0)
|
||||||
|
grub_snprintf (val, sizeof(val), "%08x-%02x",
|
||||||
|
grub_le_to_cpu32(nt_disk_sig), 1 + p->number);
|
||||||
|
}
|
||||||
|
grub_disk_close(disk);
|
||||||
|
}
|
||||||
|
if (state[0].set)
|
||||||
|
grub_env_set (state[0].arg, val);
|
||||||
|
else
|
||||||
|
grub_printf ("%s", val);
|
||||||
|
grub_device_close (dev);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
fs = grub_fs_probe (dev);
|
fs = grub_fs_probe (dev);
|
||||||
if (! fs)
|
if (! fs)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -64,7 +64,7 @@ set_matches (char **varnames, char *str, grub_size_t nmatches,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
char *q;
|
const char * q;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
unsigned long j;
|
unsigned long j;
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1));
|
matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches));
|
||||||
if (! matches)
|
if (! matches)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++)
|
for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++)
|
||||||
nhints++;
|
nhints++;
|
||||||
|
|
||||||
hints = grub_malloc (sizeof (hints[0]) * nhints);
|
hints = grub_calloc (nhints, sizeof (hints[0]));
|
||||||
if (!hints)
|
if (!hints)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
j = 0;
|
j = 0;
|
||||||
|
|
|
@ -169,7 +169,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
if (ctxt->state[0].set)
|
if (ctxt->state[0].set)
|
||||||
{
|
{
|
||||||
ptr = ctxt->state[0].arg;
|
ptr = ctxt->state[0].arg;
|
||||||
pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
|
pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff);
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -182,8 +182,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
if (*ptr != ':')
|
if (*ptr != ':')
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||||
ptr++;
|
ptr++;
|
||||||
pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
|
pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16;
|
||||||
<< 16;
|
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
else
|
else
|
||||||
|
@ -200,7 +199,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
|
|
||||||
ptr = ctxt->state[1].arg;
|
ptr = ctxt->state[1].arg;
|
||||||
optr = ptr;
|
optr = ptr;
|
||||||
bus = grub_strtoul (ptr, (char **) &ptr, 16);
|
bus = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -214,7 +213,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||||
ptr++;
|
ptr++;
|
||||||
optr = ptr;
|
optr = ptr;
|
||||||
device = grub_strtoul (ptr, (char **) &ptr, 16);
|
device = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -225,7 +224,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
if (*ptr == '.')
|
if (*ptr == '.')
|
||||||
{
|
{
|
||||||
ptr++;
|
ptr++;
|
||||||
function = grub_strtoul (ptr, (char **) &ptr, 16);
|
function = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
check_function = 1;
|
check_function = 1;
|
||||||
|
@ -253,7 +252,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
if (i == ARRAY_SIZE (pci_registers))
|
if (i == ARRAY_SIZE (pci_registers))
|
||||||
{
|
{
|
||||||
regsize = 0;
|
regsize = 0;
|
||||||
regaddr = grub_strtoul (ptr, (char **) &ptr, 16);
|
regaddr = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown register");
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown register");
|
||||||
}
|
}
|
||||||
|
@ -270,7 +269,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
if (*ptr == '+')
|
if (*ptr == '+')
|
||||||
{
|
{
|
||||||
ptr++;
|
ptr++;
|
||||||
regaddr += grub_strtoul (ptr, (char **) &ptr, 16);
|
regaddr += grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
@ -302,14 +301,14 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||||
if (*ptr == '=')
|
if (*ptr == '=')
|
||||||
{
|
{
|
||||||
ptr++;
|
ptr++;
|
||||||
regwrite = grub_strtoul (ptr, (char **) &ptr, 16);
|
regwrite = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
write_mask = 0xffffffff;
|
write_mask = 0xffffffff;
|
||||||
if (*ptr == ':')
|
if (*ptr == ':')
|
||||||
{
|
{
|
||||||
ptr++;
|
ptr++;
|
||||||
write_mask = grub_strtoul (ptr, (char **) &ptr, 16);
|
write_mask = grub_strtoul (ptr, &ptr, 16);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
write_mask = 0xffffffff;
|
write_mask = 0xffffffff;
|
||||||
|
|
|
@ -55,7 +55,7 @@ grub_interruptible_millisleep (grub_uint32_t ms)
|
||||||
start = grub_get_time_ms ();
|
start = grub_get_time_ms ();
|
||||||
|
|
||||||
while (grub_get_time_ms () - start < ms)
|
while (grub_get_time_ms () - start < ms)
|
||||||
if (grub_getkey_noblock () == GRUB_TERM_ESC)
|
if (grub_key_is_interrupt (grub_getkey_noblock ()))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
398
grub-core/commands/smbios.c
Normal file
398
grub-core/commands/smbios.c
Normal file
|
@ -0,0 +1,398 @@
|
||||||
|
/* smbios.c - retrieve smbios information. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/extcmd.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
|
||||||
|
static struct {
|
||||||
|
grub_addr_t start;
|
||||||
|
grub_addr_t end;
|
||||||
|
grub_uint16_t structures;
|
||||||
|
} table_desc;
|
||||||
|
|
||||||
|
static grub_extcmd_t cmd;
|
||||||
|
|
||||||
|
/* Locate the SMBIOS entry point structure depending on the hardware. */
|
||||||
|
struct grub_smbios_eps *
|
||||||
|
grub_smbios_get_eps (void)
|
||||||
|
{
|
||||||
|
static struct grub_smbios_eps *eps = NULL;
|
||||||
|
|
||||||
|
if (eps != NULL)
|
||||||
|
return eps;
|
||||||
|
|
||||||
|
eps = grub_machine_smbios_get_eps ();
|
||||||
|
|
||||||
|
return eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
|
||||||
|
static struct grub_smbios_eps3 *
|
||||||
|
grub_smbios_get_eps3 (void)
|
||||||
|
{
|
||||||
|
static struct grub_smbios_eps3 *eps = NULL;
|
||||||
|
|
||||||
|
if (eps != NULL)
|
||||||
|
return eps;
|
||||||
|
|
||||||
|
eps = grub_machine_smbios_get_eps3 ();
|
||||||
|
|
||||||
|
return eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
linux_string (const char *value)
|
||||||
|
{
|
||||||
|
char *out = grub_malloc( grub_strlen (value) + 1);
|
||||||
|
const char *src = value;
|
||||||
|
char *dst = out;
|
||||||
|
|
||||||
|
for (; *src; src++)
|
||||||
|
if (*src > ' ' && *src < 127 && *src != ':')
|
||||||
|
*dst++ = *src;
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These functions convert values from the various SMBIOS structure field types
|
||||||
|
* into a string formatted to be returned to the user. They expect that the
|
||||||
|
* structure and offset were already validated. When the requested data is
|
||||||
|
* successfully retrieved and formatted, the pointer to the string is returned;
|
||||||
|
* otherwise, NULL is returned on failure. Don't free the result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("255")];
|
||||||
|
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("65535")];
|
||||||
|
|
||||||
|
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%u", value);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("4294967295")];
|
||||||
|
|
||||||
|
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("18446744073709551615")];
|
||||||
|
|
||||||
|
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
const grub_uint8_t *ptr = structure + structure[1];
|
||||||
|
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
|
||||||
|
const grub_uint8_t referenced_string_number = structure[offset];
|
||||||
|
grub_uint8_t i;
|
||||||
|
|
||||||
|
/* A string referenced with zero is interpreted as unset. */
|
||||||
|
if (referenced_string_number == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Search the string set. */
|
||||||
|
for (i = 1; *ptr != 0 && ptr < table_end; i++)
|
||||||
|
if (i == referenced_string_number)
|
||||||
|
{
|
||||||
|
const char *str = (const char *)ptr;
|
||||||
|
while (*ptr++ != 0)
|
||||||
|
if (ptr >= table_end)
|
||||||
|
return NULL; /* The string isn't terminated. */
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
while (*ptr++ != 0 && ptr < table_end);
|
||||||
|
|
||||||
|
/* The string number is greater than the number of strings in the set. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
|
{
|
||||||
|
static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")];
|
||||||
|
const grub_uint8_t *f = structure + offset; /* little-endian fields */
|
||||||
|
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
|
||||||
|
|
||||||
|
grub_snprintf (buffer, sizeof (buffer),
|
||||||
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||||
|
"%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
|
f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6],
|
||||||
|
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
|
||||||
|
|
||||||
|
return (const char *)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List the field formatting functions and the number of bytes they need. */
|
||||||
|
static const struct {
|
||||||
|
const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset);
|
||||||
|
grub_uint8_t field_length;
|
||||||
|
} field_extractors[] = {
|
||||||
|
{grub_smbios_format_byte, 1},
|
||||||
|
{grub_smbios_format_word, 2},
|
||||||
|
{grub_smbios_format_dword, 4},
|
||||||
|
{grub_smbios_format_qword, 8},
|
||||||
|
{grub_smbios_get_string, 1},
|
||||||
|
{grub_smbios_format_uuid, 16}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List command options, with structure field getters ordered as above. */
|
||||||
|
#define FIRST_GETTER_OPT (3)
|
||||||
|
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
|
||||||
|
#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1)
|
||||||
|
|
||||||
|
static const struct grub_arg_option options[] = {
|
||||||
|
{"type", 't', 0, N_("Match structures with the given type."),
|
||||||
|
N_("type"), ARG_TYPE_INT},
|
||||||
|
{"handle", 'h', 0, N_("Match structures with the given handle."),
|
||||||
|
N_("handle"), ARG_TYPE_INT},
|
||||||
|
{"match", 'm', 0, N_("Select a structure when several match."),
|
||||||
|
N_("match"), ARG_TYPE_INT},
|
||||||
|
{"get-byte", 'b', 0, N_("Get the byte's value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-word", 'w', 0, N_("Get two bytes' value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-dword", 'd', 0, N_("Get four bytes' value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-qword", 'q', 0, N_("Get eight bytes' value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-string", 's', 0, N_("Get the string specified at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"get-uuid", 'u', 0, N_("Get the UUID's value at the given offset."),
|
||||||
|
N_("offset"), ARG_TYPE_INT},
|
||||||
|
{"set", '\0', 0, N_("Store the value in the given variable name."),
|
||||||
|
N_("variable"), ARG_TYPE_STRING},
|
||||||
|
{"linux", '\0', 0, N_("Filter the result like linux does."),
|
||||||
|
N_("variable"), ARG_TYPE_NONE},
|
||||||
|
{0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a matching SMBIOS structure.
|
||||||
|
*
|
||||||
|
* This method can use up to three criteria for selecting a structure:
|
||||||
|
* - The "type" field (use -1 to ignore)
|
||||||
|
* - The "handle" field (use -1 to ignore)
|
||||||
|
* - Which to return if several match (use 0 to ignore)
|
||||||
|
*
|
||||||
|
* The return value is a pointer to the first matching structure. If no
|
||||||
|
* structures match the given parameters, NULL is returned.
|
||||||
|
*/
|
||||||
|
static const grub_uint8_t *
|
||||||
|
grub_smbios_match_structure (const grub_int16_t type,
|
||||||
|
const grub_int32_t handle,
|
||||||
|
const grub_uint16_t match)
|
||||||
|
{
|
||||||
|
const grub_uint8_t *ptr = (const grub_uint8_t *)table_desc.start;
|
||||||
|
const grub_uint8_t *table_end = (const grub_uint8_t *)table_desc.end;
|
||||||
|
grub_uint16_t structures = table_desc.structures;
|
||||||
|
grub_uint16_t structure_count = 0;
|
||||||
|
grub_uint16_t matches = 0;
|
||||||
|
|
||||||
|
while (ptr < table_end
|
||||||
|
&& ptr[1] >= 4 /* Valid structures include the 4-byte header. */
|
||||||
|
&& (structure_count++ < structures || structures == 0))
|
||||||
|
{
|
||||||
|
grub_uint16_t structure_handle = grub_get_unaligned16 (ptr + 2);
|
||||||
|
grub_uint8_t structure_type = ptr[0];
|
||||||
|
|
||||||
|
if ((handle < 0 || handle == structure_handle)
|
||||||
|
&& (type < 0 || type == structure_type)
|
||||||
|
&& (match == 0 || match == ++matches))
|
||||||
|
return ptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr += ptr[1];
|
||||||
|
while ((*ptr++ != 0 || *ptr++ != 0) && ptr < table_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (structure_type == GRUB_SMBIOS_TYPE_END_OF_TABLE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||||
|
int argc __attribute__ ((unused)),
|
||||||
|
char **argv __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
struct grub_arg_list *state = ctxt->state;
|
||||||
|
|
||||||
|
grub_int16_t type = -1;
|
||||||
|
grub_int32_t handle = -1;
|
||||||
|
grub_uint16_t match = 0;
|
||||||
|
grub_uint8_t offset = 0;
|
||||||
|
|
||||||
|
const grub_uint8_t *structure;
|
||||||
|
const char *value;
|
||||||
|
char *modified_value = NULL;
|
||||||
|
grub_int32_t option;
|
||||||
|
grub_int8_t field_type = -1;
|
||||||
|
grub_uint8_t i;
|
||||||
|
|
||||||
|
if (table_desc.start == 0)
|
||||||
|
return grub_error (GRUB_ERR_IO,
|
||||||
|
N_("the SMBIOS entry point structure was not found"));
|
||||||
|
|
||||||
|
/* Read the given filtering options. */
|
||||||
|
if (state[0].set)
|
||||||
|
{
|
||||||
|
option = grub_strtol (state[0].arg, NULL, 0);
|
||||||
|
if (option < 0 || option > 255)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("the type must be between 0 and 255"));
|
||||||
|
type = (grub_int16_t)option;
|
||||||
|
}
|
||||||
|
if (state[1].set)
|
||||||
|
{
|
||||||
|
option = grub_strtol (state[1].arg, NULL, 0);
|
||||||
|
if (option < 0 || option > 65535)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("the handle must be between 0 and 65535"));
|
||||||
|
handle = (grub_int32_t)option;
|
||||||
|
}
|
||||||
|
if (state[2].set)
|
||||||
|
{
|
||||||
|
option = grub_strtol (state[2].arg, NULL, 0);
|
||||||
|
if (option <= 0 || option > 65535)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("the match must be a positive integer"));
|
||||||
|
match = (grub_uint16_t)option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the data type of the structure field to retrieve. */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(field_extractors); i++)
|
||||||
|
if (state[FIRST_GETTER_OPT + i].set)
|
||||||
|
{
|
||||||
|
if (field_type >= 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("only one --get option is usable at a time"));
|
||||||
|
field_type = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Require a choice of a structure field to return. */
|
||||||
|
if (field_type < 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("one of the --get options is required"));
|
||||||
|
|
||||||
|
/* Locate a matching SMBIOS structure. */
|
||||||
|
structure = grub_smbios_match_structure (type, handle, match);
|
||||||
|
if (structure == NULL)
|
||||||
|
return grub_error (GRUB_ERR_IO,
|
||||||
|
N_("no structure matched the given options"));
|
||||||
|
|
||||||
|
/* Ensure the requested byte offset is inside the structure. */
|
||||||
|
option = grub_strtol (state[FIRST_GETTER_OPT + field_type].arg, NULL, 0);
|
||||||
|
if (option < 0 || option >= structure[1])
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
N_("the given offset is outside the structure"));
|
||||||
|
|
||||||
|
/* Ensure the requested data type at the offset is inside the structure. */
|
||||||
|
offset = (grub_uint8_t)option;
|
||||||
|
if (offset + field_extractors[field_type].field_length > structure[1])
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
N_("the field ends outside the structure"));
|
||||||
|
|
||||||
|
/* Format the requested structure field into a readable string. */
|
||||||
|
value = field_extractors[field_type].format (structure, offset);
|
||||||
|
if (value == NULL)
|
||||||
|
return grub_error (GRUB_ERR_IO,
|
||||||
|
N_("failed to retrieve the structure field"));
|
||||||
|
|
||||||
|
if (state[LINUX_OPT].set)
|
||||||
|
value = modified_value = linux_string (value);
|
||||||
|
|
||||||
|
/* Store or print the formatted value. */
|
||||||
|
if (state[SETTER_OPT].set)
|
||||||
|
grub_env_set (state[SETTER_OPT].arg, value);
|
||||||
|
else
|
||||||
|
grub_printf ("%s\n", value);
|
||||||
|
|
||||||
|
grub_free(modified_value);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(smbios)
|
||||||
|
{
|
||||||
|
struct grub_smbios_eps3 *eps3;
|
||||||
|
struct grub_smbios_eps *eps;
|
||||||
|
|
||||||
|
if ((eps3 = grub_smbios_get_eps3 ()))
|
||||||
|
{
|
||||||
|
table_desc.start = (grub_addr_t)eps3->table_address;
|
||||||
|
table_desc.end = table_desc.start + eps3->maximum_table_length;
|
||||||
|
table_desc.structures = 0; /* SMBIOS3 drops the structure count. */
|
||||||
|
}
|
||||||
|
else if ((eps = grub_smbios_get_eps ()))
|
||||||
|
{
|
||||||
|
table_desc.start = (grub_addr_t)eps->intermediate.table_address;
|
||||||
|
table_desc.end = table_desc.start + eps->intermediate.table_length;
|
||||||
|
table_desc.structures = eps->intermediate.structures;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = grub_register_extcmd ("smbios", grub_cmd_smbios, 0,
|
||||||
|
N_("[-t type] [-h handle] [-m match] "
|
||||||
|
"(-b|-w|-d|-q|-s|-u) offset "
|
||||||
|
"[--set variable]"),
|
||||||
|
N_("Retrieve SMBIOS information."), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(smbios)
|
||||||
|
{
|
||||||
|
grub_unregister_extcmd (cmd);
|
||||||
|
}
|
|
@ -31,7 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
/* A simple implementation for signed numbers. */
|
/* A simple implementation for signed numbers. */
|
||||||
static int
|
static int
|
||||||
grub_strtosl (char *arg, char **end, int base)
|
grub_strtosl (char *arg, const char ** const end, int base)
|
||||||
{
|
{
|
||||||
if (arg[0] == '-')
|
if (arg[0] == '-')
|
||||||
return -grub_strtoul (arg + 1, end, base);
|
return -grub_strtoul (arg + 1, end, base);
|
||||||
|
|
|
@ -29,13 +29,6 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
grub_err_t
|
|
||||||
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
|
||||||
const char *description)
|
|
||||||
{
|
|
||||||
return grub_tpm_log_event (buf, size, pcr, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_tpm_verify_init (grub_file_t io,
|
grub_tpm_verify_init (grub_file_t io,
|
||||||
enum grub_file_type type __attribute__ ((unused)),
|
enum grub_file_type type __attribute__ ((unused)),
|
||||||
|
|
|
@ -196,6 +196,7 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (ver->close)
|
||||||
ver->close (context);
|
ver->close (context);
|
||||||
fail_noclose:
|
fail_noclose:
|
||||||
verified_free (verified);
|
verified_free (verified);
|
||||||
|
@ -207,6 +208,9 @@ grub_err_t
|
||||||
grub_verify_string (char *str, enum grub_verify_string_type type)
|
grub_verify_string (char *str, enum grub_verify_string_type type)
|
||||||
{
|
{
|
||||||
struct grub_file_verifier *ver;
|
struct grub_file_verifier *ver;
|
||||||
|
|
||||||
|
grub_dprintf ("verify", "string: %s, type: %d\n", str, type);
|
||||||
|
|
||||||
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
|
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
|
@ -136,7 +136,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
|
||||||
ctx.height = ctx.width = ctx.depth = 0;
|
ctx.height = ctx.width = ctx.depth = 0;
|
||||||
if (argc)
|
if (argc)
|
||||||
{
|
{
|
||||||
char *ptr;
|
const char *ptr;
|
||||||
ptr = args[0];
|
ptr = args[0];
|
||||||
ctx.width = grub_strtoul (ptr, &ptr, 0);
|
ctx.width = grub_strtoul (ptr, &ptr, 0);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/device.h>
|
#include <grub/device.h>
|
||||||
#include <grub/script_sh.h>
|
#include <grub/script_sh.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ merge (char **dest, char **ps)
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
char **p;
|
char **p;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (! dest)
|
if (! dest)
|
||||||
return ps;
|
return ps;
|
||||||
|
@ -60,7 +62,12 @@ merge (char **dest, char **ps)
|
||||||
for (j = 0; ps[j]; j++)
|
for (j = 0; ps[j]; j++)
|
||||||
;
|
;
|
||||||
|
|
||||||
p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
|
if (grub_add (i, j, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
p = grub_realloc (dest, sz);
|
||||||
if (! p)
|
if (! p)
|
||||||
{
|
{
|
||||||
grub_free (dest);
|
grub_free (dest);
|
||||||
|
@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp)
|
||||||
char ch;
|
char ch;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
unsigned len = end - start;
|
unsigned len = end - start;
|
||||||
char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
|
char *buffer;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
/* Worst case size is (len * 2 + 2 + 1). */
|
||||||
|
if (grub_mul (len, 2, &sz) ||
|
||||||
|
grub_add (sz, 3, &sz))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
buffer = grub_malloc (sz);
|
||||||
if (! buffer)
|
if (! buffer)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data)
|
||||||
struct match_devices_ctx *ctx = data;
|
struct match_devices_ctx *ctx = data;
|
||||||
char **t;
|
char **t;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
/* skip partitions if asked to. */
|
/* skip partitions if asked to. */
|
||||||
if (ctx->noparts && grub_strchr (name, ','))
|
if (ctx->noparts && grub_strchr (name, ','))
|
||||||
|
@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data)
|
||||||
if (regexec (ctx->regexp, buffer, 0, 0, 0))
|
if (regexec (ctx->regexp, buffer, 0, 0, 0))
|
||||||
{
|
{
|
||||||
grub_dprintf ("expand", "not matched\n");
|
grub_dprintf ("expand", "not matched\n");
|
||||||
|
fail:
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
|
if (grub_add (ctx->ndev, 2, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
t = grub_realloc (ctx->devs, sz);
|
||||||
if (! t)
|
if (! t)
|
||||||
{
|
{
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
|
@ -300,6 +320,7 @@ match_files_iter (const char *name,
|
||||||
struct match_files_ctx *ctx = data;
|
struct match_files_ctx *ctx = data;
|
||||||
char **t;
|
char **t;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
/* skip . and .. names */
|
/* skip . and .. names */
|
||||||
if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
|
if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
|
||||||
|
@ -315,9 +336,14 @@ match_files_iter (const char *name,
|
||||||
if (! buffer)
|
if (! buffer)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
|
if (grub_add (ctx->nfile, 2, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
t = grub_realloc (ctx->files, sz);
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/crypto.h>
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv2+");
|
||||||
|
|
||||||
gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
||||||
grub_uint8_t * dst, grub_size_t blocksize,
|
grub_uint8_t * dst, grub_size_t blocksize,
|
||||||
grub_size_t blocknumbers);
|
grub_size_t blocknumbers);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc.
|
* Copyright (C) 2003,2007,2010,2011,2019 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -404,6 +404,167 @@ grub_cryptodisk_decrypt (struct grub_cryptodisk *dev,
|
||||||
return grub_cryptodisk_endecrypt (dev, data, len, sector, 0);
|
return grub_cryptodisk_endecrypt (dev, data, len, sector, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_cryptodisk_setcipher (grub_cryptodisk_t crypt, const char *ciphername, const char *ciphermode)
|
||||||
|
{
|
||||||
|
const char *cipheriv = NULL;
|
||||||
|
grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
|
||||||
|
grub_crypto_cipher_handle_t essiv_cipher = NULL;
|
||||||
|
const gcry_md_spec_t *essiv_hash = NULL;
|
||||||
|
const struct gcry_cipher_spec *ciph;
|
||||||
|
grub_cryptodisk_mode_t mode;
|
||||||
|
grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
|
||||||
|
int benbi_log = 0;
|
||||||
|
grub_err_t ret = GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
ciph = grub_crypto_lookup_cipher_by_name (ciphername);
|
||||||
|
if (!ciph)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
|
||||||
|
ciphername);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the cipher used for the bulk data. */
|
||||||
|
cipher = grub_crypto_cipher_open (ciph);
|
||||||
|
if (!cipher)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s could not be initialized",
|
||||||
|
ciphername);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the cipher mode. */
|
||||||
|
if (grub_strcmp (ciphermode, "ecb") == 0)
|
||||||
|
{
|
||||||
|
mode = GRUB_CRYPTODISK_MODE_ECB;
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
|
||||||
|
cipheriv = NULL;
|
||||||
|
}
|
||||||
|
else if (grub_strcmp (ciphermode, "plain") == 0)
|
||||||
|
{
|
||||||
|
mode = GRUB_CRYPTODISK_MODE_CBC;
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
|
||||||
|
cipheriv = NULL;
|
||||||
|
}
|
||||||
|
else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
|
||||||
|
{
|
||||||
|
mode = GRUB_CRYPTODISK_MODE_CBC;
|
||||||
|
cipheriv = ciphermode + sizeof ("cbc-") - 1;
|
||||||
|
}
|
||||||
|
else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
|
||||||
|
{
|
||||||
|
mode = GRUB_CRYPTODISK_MODE_PCBC;
|
||||||
|
cipheriv = ciphermode + sizeof ("pcbc-") - 1;
|
||||||
|
}
|
||||||
|
else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
|
||||||
|
{
|
||||||
|
mode = GRUB_CRYPTODISK_MODE_XTS;
|
||||||
|
cipheriv = ciphermode + sizeof ("xts-") - 1;
|
||||||
|
secondary_cipher = grub_crypto_cipher_open (ciph);
|
||||||
|
if (!secondary_cipher)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||||
|
"Secondary cipher %s isn't available", ciphername);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
|
||||||
|
cipher->cipher->blocksize);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
|
||||||
|
secondary_cipher->cipher->blocksize);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
|
||||||
|
{
|
||||||
|
mode = GRUB_CRYPTODISK_MODE_LRW;
|
||||||
|
cipheriv = ciphermode + sizeof ("lrw-") - 1;
|
||||||
|
if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d",
|
||||||
|
cipher->cipher->blocksize);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
|
||||||
|
ciphermode);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cipheriv == NULL)
|
||||||
|
;
|
||||||
|
else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
|
||||||
|
else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
|
||||||
|
else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
|
||||||
|
{
|
||||||
|
if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
|
||||||
|
|| cipher->cipher->blocksize == 0)
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d",
|
||||||
|
cipher->cipher->blocksize);
|
||||||
|
/* FIXME should we return an error here? */
|
||||||
|
for (benbi_log = 0;
|
||||||
|
(cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
|
||||||
|
benbi_log++);
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
|
||||||
|
}
|
||||||
|
else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
|
||||||
|
else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
|
||||||
|
{
|
||||||
|
const char *hash_str = cipheriv + 6;
|
||||||
|
|
||||||
|
mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
|
||||||
|
|
||||||
|
/* Configure the hash and cipher used for ESSIV. */
|
||||||
|
essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
|
||||||
|
if (!essiv_hash)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||||
|
"Couldn't load %s hash", hash_str);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
essiv_cipher = grub_crypto_cipher_open (ciph);
|
||||||
|
if (!essiv_cipher)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||||
|
"Couldn't load %s cipher", ciphername);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
|
||||||
|
cipheriv);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypt->cipher = cipher;
|
||||||
|
crypt->benbi_log = benbi_log;
|
||||||
|
crypt->mode = mode;
|
||||||
|
crypt->mode_iv = mode_iv;
|
||||||
|
crypt->secondary_cipher = secondary_cipher;
|
||||||
|
crypt->essiv_cipher = essiv_cipher;
|
||||||
|
crypt->essiv_hash = essiv_hash;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
grub_crypto_cipher_close (cipher);
|
||||||
|
grub_crypto_cipher_close (secondary_cipher);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gcry_err_code_t
|
gcry_err_code_t
|
||||||
grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize)
|
grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize)
|
||||||
{
|
{
|
||||||
|
@ -596,9 +757,8 @@ grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
size, sector, dev->offset);
|
size, sector, dev->offset);
|
||||||
|
|
||||||
err = grub_disk_read (dev->source_disk,
|
err = grub_disk_read (dev->source_disk,
|
||||||
(sector << (disk->log_sector_size
|
grub_disk_from_native_sector (disk, sector + dev->offset),
|
||||||
- GRUB_DISK_SECTOR_BITS)) + dev->offset, 0,
|
0, size << disk->log_sector_size, buf);
|
||||||
size << disk->log_sector_size, buf);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err);
|
grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err);
|
||||||
|
@ -655,12 +815,10 @@ grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Since ->write was called so disk.mod is loaded but be paranoid */
|
/* Since ->write was called so disk.mod is loaded but be paranoid */
|
||||||
|
sector = sector + dev->offset;
|
||||||
if (grub_disk_write_weak)
|
if (grub_disk_write_weak)
|
||||||
err = grub_disk_write_weak (dev->source_disk,
|
err = grub_disk_write_weak (dev->source_disk,
|
||||||
(sector << (disk->log_sector_size
|
grub_disk_from_native_sector (disk, sector),
|
||||||
- GRUB_DISK_SECTOR_BITS))
|
|
||||||
+ dev->offset,
|
|
||||||
0, size << disk->log_sector_size, tmp);
|
0, size << disk->log_sector_size, tmp);
|
||||||
else
|
else
|
||||||
err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded");
|
err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded");
|
||||||
|
@ -1150,5 +1308,6 @@ GRUB_MOD_FINI (cryptodisk)
|
||||||
{
|
{
|
||||||
grub_disk_dev_unregister (&grub_cryptodisk_dev);
|
grub_disk_dev_unregister (&grub_cryptodisk_dev);
|
||||||
cryptodisk_cleanup ();
|
cryptodisk_cleanup ();
|
||||||
|
grub_unregister_extcmd (cmd);
|
||||||
grub_procfs_unregister (&luks_script);
|
grub_procfs_unregister (&luks_script);
|
||||||
}
|
}
|
||||||
|
|
|
@ -969,7 +969,8 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
|
||||||
for (p = vgp->lvs; p; p = p->next)
|
for (p = vgp->lvs; p; p = p->next)
|
||||||
{
|
{
|
||||||
int cur_num;
|
int cur_num;
|
||||||
char *num, *end;
|
char *num;
|
||||||
|
const char *end;
|
||||||
if (!p->fullname)
|
if (!p->fullname)
|
||||||
continue;
|
continue;
|
||||||
if (grub_strncmp (p->fullname, lv->fullname, len) != 0)
|
if (grub_strncmp (p->fullname, lv->fullname, len) != 0)
|
||||||
|
@ -1134,7 +1135,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
||||||
array->lvs->segments->node_count = nmemb;
|
array->lvs->segments->node_count = nmemb;
|
||||||
array->lvs->segments->raid_member_size = disk_size;
|
array->lvs->segments->raid_member_size = disk_size;
|
||||||
array->lvs->segments->nodes
|
array->lvs->segments->nodes
|
||||||
= grub_zalloc (nmemb * sizeof (array->lvs->segments->nodes[0]));
|
= grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0]));
|
||||||
array->lvs->segments->stripe_size = stripe_size;
|
array->lvs->segments->stripe_size = stripe_size;
|
||||||
for (i = 0; i < nmemb; i++)
|
for (i = 0; i < nmemb; i++)
|
||||||
{
|
{
|
||||||
|
@ -1226,7 +1227,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
|
||||||
grub_partition_t p;
|
grub_partition_t p;
|
||||||
for (p = disk->partition; p; p = p->parent)
|
for (p = disk->partition; p; p = p->parent)
|
||||||
s++;
|
s++;
|
||||||
pv->partmaps = xmalloc (s * sizeof (pv->partmaps[0]));
|
pv->partmaps = xcalloc (s, sizeof (pv->partmaps[0]));
|
||||||
s = 0;
|
s = 0;
|
||||||
for (p = disk->partition; p; p = p->parent)
|
for (p = disk->partition; p; p = p->parent)
|
||||||
pv->partmaps[s++] = xstrdup (p->partmap->name);
|
pv->partmaps[s++] = xstrdup (p->partmap->name);
|
||||||
|
|
|
@ -297,7 +297,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||||
/* Power machines documentation specify 672 as maximum SAS disks in
|
/* Power machines documentation specify 672 as maximum SAS disks in
|
||||||
one system. Using a slightly larger value to be safe. */
|
one system. Using a slightly larger value to be safe. */
|
||||||
table_size = 768;
|
table_size = 768;
|
||||||
table = grub_malloc (table_size * sizeof (grub_uint64_t));
|
table = grub_calloc (table_size, sizeof (grub_uint64_t));
|
||||||
|
|
||||||
if (!table)
|
if (!table)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <grub/msdos_partition.h>
|
#include <grub/msdos_partition.h>
|
||||||
#include <grub/gpt_partition.h>
|
#include <grub/gpt_partition.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/emu/misc.h>
|
#include <grub/emu/misc.h>
|
||||||
|
@ -289,6 +290,7 @@ make_vg (grub_disk_t disk,
|
||||||
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
||||||
/ sizeof (struct grub_ldm_vblk)];
|
/ sizeof (struct grub_ldm_vblk)];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
grub_size_t sz;
|
||||||
err = grub_disk_read (disk, cursec, 0,
|
err = grub_disk_read (disk, cursec, 0,
|
||||||
sizeof(vblk), &vblk);
|
sizeof(vblk), &vblk);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -323,8 +325,8 @@ make_vg (grub_disk_t disk,
|
||||||
lv->segments->type = GRUB_DISKFILTER_MIRROR;
|
lv->segments->type = GRUB_DISKFILTER_MIRROR;
|
||||||
lv->segments->node_count = 0;
|
lv->segments->node_count = 0;
|
||||||
lv->segments->node_alloc = 8;
|
lv->segments->node_alloc = 8;
|
||||||
lv->segments->nodes = grub_zalloc (sizeof (*lv->segments->nodes)
|
lv->segments->nodes = grub_calloc (lv->segments->node_alloc,
|
||||||
* lv->segments->node_alloc);
|
sizeof (*lv->segments->nodes));
|
||||||
if (!lv->segments->nodes)
|
if (!lv->segments->nodes)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
ptr = vblk[i].dynamic;
|
ptr = vblk[i].dynamic;
|
||||||
|
@ -350,7 +352,13 @@ make_vg (grub_disk_t disk,
|
||||||
grub_free (lv);
|
grub_free (lv);
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
lv->name = grub_malloc (*ptr + 1);
|
if (grub_add (*ptr, 1, &sz))
|
||||||
|
{
|
||||||
|
grub_free (lv->internal_id);
|
||||||
|
grub_free (lv);
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
lv->name = grub_malloc (sz);
|
||||||
if (!lv->name)
|
if (!lv->name)
|
||||||
{
|
{
|
||||||
grub_free (lv->internal_id);
|
grub_free (lv->internal_id);
|
||||||
|
@ -543,8 +551,8 @@ make_vg (grub_disk_t disk,
|
||||||
{
|
{
|
||||||
comp->segment_alloc = 8;
|
comp->segment_alloc = 8;
|
||||||
comp->segment_count = 0;
|
comp->segment_count = 0;
|
||||||
comp->segments = grub_malloc (sizeof (*comp->segments)
|
comp->segments = grub_calloc (comp->segment_alloc,
|
||||||
* comp->segment_alloc);
|
sizeof (*comp->segments));
|
||||||
if (!comp->segments)
|
if (!comp->segments)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
@ -590,8 +598,8 @@ make_vg (grub_disk_t disk,
|
||||||
}
|
}
|
||||||
comp->segments->node_count = read_int (ptr + 1, *ptr);
|
comp->segments->node_count = read_int (ptr + 1, *ptr);
|
||||||
comp->segments->node_alloc = comp->segments->node_count;
|
comp->segments->node_alloc = comp->segments->node_count;
|
||||||
comp->segments->nodes = grub_zalloc (sizeof (*comp->segments->nodes)
|
comp->segments->nodes = grub_calloc (comp->segments->node_alloc,
|
||||||
* comp->segments->node_alloc);
|
sizeof (*comp->segments->nodes));
|
||||||
if (!lv->segments->nodes)
|
if (!lv->segments->nodes)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
@ -599,10 +607,13 @@ make_vg (grub_disk_t disk,
|
||||||
if (lv->segments->node_alloc == lv->segments->node_count)
|
if (lv->segments->node_alloc == lv->segments->node_count)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
lv->segments->node_alloc *= 2;
|
grub_size_t sz;
|
||||||
t = grub_realloc (lv->segments->nodes,
|
|
||||||
sizeof (*lv->segments->nodes)
|
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
|
||||||
* lv->segments->node_alloc);
|
grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
|
||||||
|
goto fail2;
|
||||||
|
|
||||||
|
t = grub_realloc (lv->segments->nodes, sz);
|
||||||
if (!t)
|
if (!t)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
lv->segments->nodes = t;
|
lv->segments->nodes = t;
|
||||||
|
@ -723,10 +734,13 @@ make_vg (grub_disk_t disk,
|
||||||
if (comp->segment_alloc == comp->segment_count)
|
if (comp->segment_alloc == comp->segment_count)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
comp->segment_alloc *= 2;
|
grub_size_t sz;
|
||||||
t = grub_realloc (comp->segments,
|
|
||||||
comp->segment_alloc
|
if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
|
||||||
* sizeof (*comp->segments));
|
grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
|
||||||
|
goto fail2;
|
||||||
|
|
||||||
|
t = grub_realloc (comp->segments, sz);
|
||||||
if (!t)
|
if (!t)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
comp->segments = t;
|
comp->segments = t;
|
||||||
|
@ -1017,7 +1031,7 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
*nsectors = lv->size;
|
*nsectors = lv->size;
|
||||||
if (*nsectors > max_nsectors)
|
if (*nsectors > max_nsectors)
|
||||||
*nsectors = max_nsectors;
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_calloc (*nsectors, sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
for (i = 0; i < *nsectors; i++)
|
for (i = 0; i < *nsectors; i++)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc.
|
* Copyright (C) 2003,2007,2010,2011,2019 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -75,15 +75,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||||
char uuid[sizeof (header.uuid) + 1];
|
char uuid[sizeof (header.uuid) + 1];
|
||||||
char ciphername[sizeof (header.cipherName) + 1];
|
char ciphername[sizeof (header.cipherName) + 1];
|
||||||
char ciphermode[sizeof (header.cipherMode) + 1];
|
char ciphermode[sizeof (header.cipherMode) + 1];
|
||||||
char *cipheriv = NULL;
|
|
||||||
char hashspec[sizeof (header.hashSpec) + 1];
|
char hashspec[sizeof (header.hashSpec) + 1];
|
||||||
grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
|
|
||||||
grub_crypto_cipher_handle_t essiv_cipher = NULL;
|
|
||||||
const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL;
|
|
||||||
const struct gcry_cipher_spec *ciph;
|
|
||||||
grub_cryptodisk_mode_t mode;
|
|
||||||
grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
|
|
||||||
int benbi_log = 0;
|
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
if (check_boot)
|
if (check_boot)
|
||||||
|
@ -103,6 +95,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||||
|| grub_be_to_cpu16 (header.version) != 1)
|
|| grub_be_to_cpu16 (header.version) != 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
grub_memset (uuid, 0, sizeof (uuid));
|
||||||
optr = uuid;
|
optr = uuid;
|
||||||
for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
|
for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
|
||||||
iptr++)
|
iptr++)
|
||||||
|
@ -126,183 +119,33 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
||||||
grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec));
|
grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec));
|
||||||
hashspec[sizeof (header.hashSpec)] = 0;
|
hashspec[sizeof (header.hashSpec)] = 0;
|
||||||
|
|
||||||
ciph = grub_crypto_lookup_cipher_by_name (ciphername);
|
newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
|
||||||
if (!ciph)
|
if (!newdev)
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
|
|
||||||
ciphername);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
newdev->offset = grub_be_to_cpu32 (header.payloadOffset);
|
||||||
|
newdev->source_disk = NULL;
|
||||||
/* Configure the cipher used for the bulk data. */
|
newdev->log_sector_size = 9;
|
||||||
cipher = grub_crypto_cipher_open (ciph);
|
newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
|
||||||
if (!cipher)
|
grub_memcpy (newdev->uuid, uuid, sizeof (uuid));
|
||||||
return NULL;
|
newdev->modname = "luks";
|
||||||
|
|
||||||
if (grub_be_to_cpu32 (header.keyBytes) > 1024)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
|
|
||||||
grub_be_to_cpu32 (header.keyBytes));
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure the cipher mode. */
|
|
||||||
if (grub_strcmp (ciphermode, "ecb") == 0)
|
|
||||||
{
|
|
||||||
mode = GRUB_CRYPTODISK_MODE_ECB;
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
|
|
||||||
cipheriv = NULL;
|
|
||||||
}
|
|
||||||
else if (grub_strcmp (ciphermode, "plain") == 0)
|
|
||||||
{
|
|
||||||
mode = GRUB_CRYPTODISK_MODE_CBC;
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
|
|
||||||
cipheriv = NULL;
|
|
||||||
}
|
|
||||||
else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
|
|
||||||
{
|
|
||||||
mode = GRUB_CRYPTODISK_MODE_CBC;
|
|
||||||
cipheriv = ciphermode + sizeof ("cbc-") - 1;
|
|
||||||
}
|
|
||||||
else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
|
|
||||||
{
|
|
||||||
mode = GRUB_CRYPTODISK_MODE_PCBC;
|
|
||||||
cipheriv = ciphermode + sizeof ("pcbc-") - 1;
|
|
||||||
}
|
|
||||||
else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
|
|
||||||
{
|
|
||||||
mode = GRUB_CRYPTODISK_MODE_XTS;
|
|
||||||
cipheriv = ciphermode + sizeof ("xts-") - 1;
|
|
||||||
secondary_cipher = grub_crypto_cipher_open (ciph);
|
|
||||||
if (!secondary_cipher)
|
|
||||||
{
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
|
|
||||||
cipher->cipher->blocksize);
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
|
|
||||||
{
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
|
|
||||||
secondary_cipher->cipher->blocksize);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
|
|
||||||
{
|
|
||||||
mode = GRUB_CRYPTODISK_MODE_LRW;
|
|
||||||
cipheriv = ciphermode + sizeof ("lrw-") - 1;
|
|
||||||
if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d",
|
|
||||||
cipher->cipher->blocksize);
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
|
|
||||||
ciphermode);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cipheriv == NULL);
|
|
||||||
else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
|
|
||||||
else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
|
|
||||||
else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
|
|
||||||
{
|
|
||||||
if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
|
|
||||||
|| cipher->cipher->blocksize == 0)
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d",
|
|
||||||
cipher->cipher->blocksize);
|
|
||||||
/* FIXME should we return an error here? */
|
|
||||||
for (benbi_log = 0;
|
|
||||||
(cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
|
|
||||||
benbi_log++);
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
|
|
||||||
}
|
|
||||||
else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
|
|
||||||
else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
|
|
||||||
{
|
|
||||||
char *hash_str = cipheriv + 6;
|
|
||||||
|
|
||||||
mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
|
|
||||||
|
|
||||||
/* Configure the hash and cipher used for ESSIV. */
|
|
||||||
essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
|
|
||||||
if (!essiv_hash)
|
|
||||||
{
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
|
||||||
"Couldn't load %s hash", hash_str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
essiv_cipher = grub_crypto_cipher_open (ciph);
|
|
||||||
if (!essiv_cipher)
|
|
||||||
{
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grub_crypto_cipher_close (cipher);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
|
|
||||||
cipheriv);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure the hash used for the AF splitter and HMAC. */
|
/* Configure the hash used for the AF splitter and HMAC. */
|
||||||
hash = grub_crypto_lookup_md_by_name (hashspec);
|
newdev->hash = grub_crypto_lookup_md_by_name (hashspec);
|
||||||
if (!hash)
|
if (!newdev->hash)
|
||||||
{
|
{
|
||||||
grub_crypto_cipher_close (cipher);
|
grub_free (newdev);
|
||||||
grub_crypto_cipher_close (essiv_cipher);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
|
grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
|
||||||
hashspec);
|
hashspec);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
|
err = grub_cryptodisk_setcipher (newdev, ciphername, ciphermode);
|
||||||
if (!newdev)
|
if (err)
|
||||||
{
|
{
|
||||||
grub_crypto_cipher_close (cipher);
|
grub_free (newdev);
|
||||||
grub_crypto_cipher_close (essiv_cipher);
|
|
||||||
grub_crypto_cipher_close (secondary_cipher);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
newdev->cipher = cipher;
|
|
||||||
newdev->offset = grub_be_to_cpu32 (header.payloadOffset);
|
|
||||||
newdev->source_disk = NULL;
|
|
||||||
newdev->benbi_log = benbi_log;
|
|
||||||
newdev->mode = mode;
|
|
||||||
newdev->mode_iv = mode_iv;
|
|
||||||
newdev->secondary_cipher = secondary_cipher;
|
|
||||||
newdev->essiv_cipher = essiv_cipher;
|
|
||||||
newdev->essiv_hash = essiv_hash;
|
|
||||||
newdev->hash = hash;
|
|
||||||
newdev->log_sector_size = 9;
|
|
||||||
newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
|
|
||||||
grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
|
|
||||||
newdev->modname = "luks";
|
|
||||||
COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
|
COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
|
||||||
return newdev;
|
return newdev;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +179,7 @@ luks_recover_key (grub_disk_t source,
|
||||||
&& grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
|
&& grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
|
||||||
max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes);
|
max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes);
|
||||||
|
|
||||||
split_key = grub_malloc (keysize * max_stripes);
|
split_key = grub_calloc (keysize, max_stripes);
|
||||||
if (!split_key)
|
if (!split_key)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
|
687
grub-core/disk/luks2.c
Normal file
687
grub-core/disk/luks2.c
Normal file
|
@ -0,0 +1,687 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/cryptodisk.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/partition.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
#include <base64.h>
|
||||||
|
#include <json.h>
|
||||||
|
|
||||||
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
#define LUKS_MAGIC_1ST "LUKS\xBA\xBE"
|
||||||
|
#define LUKS_MAGIC_2ND "SKUL\xBA\xBE"
|
||||||
|
|
||||||
|
#define MAX_PASSPHRASE 256
|
||||||
|
|
||||||
|
enum grub_luks2_kdf_type
|
||||||
|
{
|
||||||
|
LUKS2_KDF_TYPE_ARGON2I,
|
||||||
|
LUKS2_KDF_TYPE_PBKDF2
|
||||||
|
};
|
||||||
|
typedef enum grub_luks2_kdf_type grub_luks2_kdf_type_t;
|
||||||
|
|
||||||
|
/* On disk LUKS header */
|
||||||
|
struct grub_luks2_header
|
||||||
|
{
|
||||||
|
char magic[6];
|
||||||
|
grub_uint16_t version;
|
||||||
|
grub_uint64_t hdr_size;
|
||||||
|
grub_uint64_t seqid;
|
||||||
|
char label[48];
|
||||||
|
char csum_alg[32];
|
||||||
|
grub_uint8_t salt[64];
|
||||||
|
char uuid[40];
|
||||||
|
char subsystem[48];
|
||||||
|
grub_uint64_t hdr_offset;
|
||||||
|
char _padding[184];
|
||||||
|
grub_uint8_t csum[64];
|
||||||
|
char _padding4096[7*512];
|
||||||
|
} GRUB_PACKED;
|
||||||
|
typedef struct grub_luks2_header grub_luks2_header_t;
|
||||||
|
|
||||||
|
struct grub_luks2_keyslot
|
||||||
|
{
|
||||||
|
grub_int64_t key_size;
|
||||||
|
grub_int64_t priority;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
const char *encryption;
|
||||||
|
grub_uint64_t offset;
|
||||||
|
grub_uint64_t size;
|
||||||
|
grub_int64_t key_size;
|
||||||
|
} area;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
const char *hash;
|
||||||
|
grub_int64_t stripes;
|
||||||
|
} af;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
grub_luks2_kdf_type_t type;
|
||||||
|
const char *salt;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
grub_int64_t time;
|
||||||
|
grub_int64_t memory;
|
||||||
|
grub_int64_t cpus;
|
||||||
|
} argon2i;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
const char *hash;
|
||||||
|
grub_int64_t iterations;
|
||||||
|
} pbkdf2;
|
||||||
|
} u;
|
||||||
|
} kdf;
|
||||||
|
};
|
||||||
|
typedef struct grub_luks2_keyslot grub_luks2_keyslot_t;
|
||||||
|
|
||||||
|
struct grub_luks2_segment
|
||||||
|
{
|
||||||
|
grub_uint64_t offset;
|
||||||
|
const char *size;
|
||||||
|
const char *encryption;
|
||||||
|
grub_int64_t sector_size;
|
||||||
|
};
|
||||||
|
typedef struct grub_luks2_segment grub_luks2_segment_t;
|
||||||
|
|
||||||
|
struct grub_luks2_digest
|
||||||
|
{
|
||||||
|
/* Both keyslots and segments are interpreted as bitfields here */
|
||||||
|
grub_uint64_t keyslots;
|
||||||
|
grub_uint64_t segments;
|
||||||
|
const char *salt;
|
||||||
|
const char *digest;
|
||||||
|
const char *hash;
|
||||||
|
grub_int64_t iterations;
|
||||||
|
};
|
||||||
|
typedef struct grub_luks2_digest grub_luks2_digest_t;
|
||||||
|
|
||||||
|
gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
||||||
|
grub_uint8_t * dst, grub_size_t blocksize,
|
||||||
|
grub_size_t blocknumbers);
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_parse_keyslot (grub_luks2_keyslot_t *out, const grub_json_t *keyslot)
|
||||||
|
{
|
||||||
|
grub_json_t area, af, kdf;
|
||||||
|
const char *type;
|
||||||
|
|
||||||
|
if (grub_json_getstring (&type, keyslot, "type"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid keyslot");
|
||||||
|
else if (grub_strcmp (type, "luks2"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported keyslot type %s", type);
|
||||||
|
else if (grub_json_getint64 (&out->key_size, keyslot, "key_size"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing keyslot information");
|
||||||
|
if (grub_json_getint64 (&out->priority, keyslot, "priority"))
|
||||||
|
out->priority = 1;
|
||||||
|
|
||||||
|
if (grub_json_getvalue (&area, keyslot, "area") ||
|
||||||
|
grub_json_getstring (&type, &area, "type"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid key area");
|
||||||
|
else if (grub_strcmp (type, "raw"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported key area type: %s", type);
|
||||||
|
else if (grub_json_getuint64 (&out->area.offset, &area, "offset") ||
|
||||||
|
grub_json_getuint64 (&out->area.size, &area, "size") ||
|
||||||
|
grub_json_getstring (&out->area.encryption, &area, "encryption") ||
|
||||||
|
grub_json_getint64 (&out->area.key_size, &area, "key_size"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing key area information");
|
||||||
|
|
||||||
|
if (grub_json_getvalue (&kdf, keyslot, "kdf") ||
|
||||||
|
grub_json_getstring (&type, &kdf, "type") ||
|
||||||
|
grub_json_getstring (&out->kdf.salt, &kdf, "salt"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing or invalid KDF");
|
||||||
|
else if (!grub_strcmp (type, "argon2i") || !grub_strcmp (type, "argon2id"))
|
||||||
|
{
|
||||||
|
out->kdf.type = LUKS2_KDF_TYPE_ARGON2I;
|
||||||
|
if (grub_json_getint64 (&out->kdf.u.argon2i.time, &kdf, "time") ||
|
||||||
|
grub_json_getint64 (&out->kdf.u.argon2i.memory, &kdf, "memory") ||
|
||||||
|
grub_json_getint64 (&out->kdf.u.argon2i.cpus, &kdf, "cpus"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing Argon2i parameters");
|
||||||
|
}
|
||||||
|
else if (!grub_strcmp (type, "pbkdf2"))
|
||||||
|
{
|
||||||
|
out->kdf.type = LUKS2_KDF_TYPE_PBKDF2;
|
||||||
|
if (grub_json_getstring (&out->kdf.u.pbkdf2.hash, &kdf, "hash") ||
|
||||||
|
grub_json_getint64 (&out->kdf.u.pbkdf2.iterations, &kdf, "iterations"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing PBKDF2 parameters");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported KDF type %s", type);
|
||||||
|
|
||||||
|
if (grub_json_getvalue (&af, keyslot, "af") ||
|
||||||
|
grub_json_getstring (&type, &af, "type"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing or invalid area");
|
||||||
|
if (grub_strcmp (type, "luks1"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported AF type %s", type);
|
||||||
|
if (grub_json_getint64 (&out->af.stripes, &af, "stripes") ||
|
||||||
|
grub_json_getstring (&out->af.hash, &af, "hash"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing AF parameters");
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_parse_segment (grub_luks2_segment_t *out, const grub_json_t *segment)
|
||||||
|
{
|
||||||
|
const char *type;
|
||||||
|
|
||||||
|
if (grub_json_getstring (&type, segment, "type"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid segment type");
|
||||||
|
else if (grub_strcmp (type, "crypt"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported segment type %s", type);
|
||||||
|
|
||||||
|
if (grub_json_getuint64 (&out->offset, segment, "offset") ||
|
||||||
|
grub_json_getstring (&out->size, segment, "size") ||
|
||||||
|
grub_json_getstring (&out->encryption, segment, "encryption") ||
|
||||||
|
grub_json_getint64 (&out->sector_size, segment, "sector_size"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing segment parameters", type);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_parse_digest (grub_luks2_digest_t *out, const grub_json_t *digest)
|
||||||
|
{
|
||||||
|
grub_json_t segments, keyslots, o;
|
||||||
|
grub_size_t i, size;
|
||||||
|
grub_uint64_t bit;
|
||||||
|
const char *type;
|
||||||
|
|
||||||
|
if (grub_json_getstring (&type, digest, "type"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest type");
|
||||||
|
else if (grub_strcmp (type, "pbkdf2"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported digest type %s", type);
|
||||||
|
|
||||||
|
if (grub_json_getvalue (&segments, digest, "segments") ||
|
||||||
|
grub_json_getvalue (&keyslots, digest, "keyslots") ||
|
||||||
|
grub_json_getstring (&out->salt, digest, "salt") ||
|
||||||
|
grub_json_getstring (&out->digest, digest, "digest") ||
|
||||||
|
grub_json_getstring (&out->hash, digest, "hash") ||
|
||||||
|
grub_json_getint64 (&out->iterations, digest, "iterations"))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing digest parameters");
|
||||||
|
|
||||||
|
if (grub_json_getsize (&size, &segments))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Digest references no segments", type);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (grub_json_getchild (&o, &segments, i) ||
|
||||||
|
grub_json_getuint64 (&bit, &o, NULL))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid segment");
|
||||||
|
out->segments |= (1 << bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_json_getsize (&size, &keyslots))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"Digest references no keyslots", type);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (grub_json_getchild (&o, &keyslots, i) ||
|
||||||
|
grub_json_getuint64 (&bit, &o, NULL))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot");
|
||||||
|
out->keyslots |= (1 << bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_segment_t *s,
|
||||||
|
const grub_json_t *root, grub_size_t i)
|
||||||
|
{
|
||||||
|
grub_json_t keyslots, keyslot, digests, digest, segments, segment;
|
||||||
|
grub_size_t j, size;
|
||||||
|
grub_uint64_t idx;
|
||||||
|
|
||||||
|
/* Get nth keyslot */
|
||||||
|
if (grub_json_getvalue (&keyslots, root, "keyslots") ||
|
||||||
|
grub_json_getchild (&keyslot, &keyslots, i) ||
|
||||||
|
grub_json_getuint64 (&idx, &keyslot, NULL) ||
|
||||||
|
grub_json_getchild (&keyslot, &keyslot, 0) ||
|
||||||
|
luks2_parse_keyslot (k, &keyslot))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse keyslot %"PRIuGRUB_SIZE, i);
|
||||||
|
|
||||||
|
/* Get digest that matches the keyslot. */
|
||||||
|
if (grub_json_getvalue (&digests, root, "digests") ||
|
||||||
|
grub_json_getsize (&size, &digests))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get digests");
|
||||||
|
for (j = 0; j < size; j++)
|
||||||
|
{
|
||||||
|
if (grub_json_getchild (&digest, &digests, i) ||
|
||||||
|
grub_json_getchild (&digest, &digest, 0) ||
|
||||||
|
luks2_parse_digest (d, &digest))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse digest %"PRIuGRUB_SIZE, i);
|
||||||
|
|
||||||
|
if ((d->keyslots & (1 << idx)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j == size)
|
||||||
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for keyslot %"PRIuGRUB_SIZE);
|
||||||
|
|
||||||
|
/* Get segment that matches the digest. */
|
||||||
|
if (grub_json_getvalue (&segments, root, "segments") ||
|
||||||
|
grub_json_getsize (&size, &segments))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get segments");
|
||||||
|
for (j = 0; j < size; j++)
|
||||||
|
{
|
||||||
|
if (grub_json_getchild (&segment, &segments, i) ||
|
||||||
|
grub_json_getuint64 (&idx, &segment, NULL) ||
|
||||||
|
grub_json_getchild (&segment, &segment, 0) ||
|
||||||
|
luks2_parse_segment (s, &segment))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse segment %"PRIuGRUB_SIZE, i);
|
||||||
|
|
||||||
|
if ((d->segments & (1 << idx)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j == size)
|
||||||
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest %"PRIuGRUB_SIZE);
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine whether to use primary or secondary header */
|
||||||
|
static grub_err_t
|
||||||
|
luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr)
|
||||||
|
{
|
||||||
|
grub_luks2_header_t primary, secondary, *header = &primary;
|
||||||
|
grub_err_t ret;
|
||||||
|
|
||||||
|
/* Read the primary LUKS header. */
|
||||||
|
ret = grub_disk_read (disk, 0, 0, sizeof (primary), &primary);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Look for LUKS magic sequence. */
|
||||||
|
if (grub_memcmp (primary.magic, LUKS_MAGIC_1ST, sizeof (primary.magic)) ||
|
||||||
|
grub_be_to_cpu16 (primary.version) != 2)
|
||||||
|
return GRUB_ERR_BAD_SIGNATURE;
|
||||||
|
|
||||||
|
/* Read the secondary header. */
|
||||||
|
ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (primary.hdr_size), sizeof (secondary), &secondary);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Look for LUKS magic sequence. */
|
||||||
|
if (grub_memcmp (secondary.magic, LUKS_MAGIC_2ND, sizeof (secondary.magic)) ||
|
||||||
|
grub_be_to_cpu16 (secondary.version) != 2)
|
||||||
|
return GRUB_ERR_BAD_SIGNATURE;
|
||||||
|
|
||||||
|
if (grub_be_to_cpu64 (primary.seqid) < grub_be_to_cpu64 (secondary.seqid))
|
||||||
|
header = &secondary;
|
||||||
|
grub_memcpy (outhdr, header, sizeof (*header));
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_cryptodisk_t
|
||||||
|
luks2_scan (grub_disk_t disk, const char *check_uuid, int check_boot)
|
||||||
|
{
|
||||||
|
grub_cryptodisk_t cryptodisk;
|
||||||
|
grub_luks2_header_t header;
|
||||||
|
char uuid[sizeof (header.uuid) + 1];
|
||||||
|
grub_size_t i, j;
|
||||||
|
|
||||||
|
if (check_boot)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (luks2_read_header (disk, &header))
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < sizeof (header.uuid); i++)
|
||||||
|
if (header.uuid[i] != '-')
|
||||||
|
uuid[j++] = header.uuid[i];
|
||||||
|
uuid[j] = '\0';
|
||||||
|
|
||||||
|
if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cryptodisk = grub_zalloc (sizeof (*cryptodisk));
|
||||||
|
if (!cryptodisk)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (uuid));
|
||||||
|
grub_memcpy (cryptodisk->uuid, uuid, sizeof (uuid));
|
||||||
|
|
||||||
|
cryptodisk->modname = "luks2";
|
||||||
|
return cryptodisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key,
|
||||||
|
grub_size_t candidate_key_len)
|
||||||
|
{
|
||||||
|
grub_uint8_t candidate_digest[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
|
grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN], salt[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
|
grub_size_t saltlen = sizeof (salt), digestlen = sizeof (digest);
|
||||||
|
const gcry_md_spec_t *hash;
|
||||||
|
gcry_err_code_t gcry_ret;
|
||||||
|
|
||||||
|
/* Decode both digest and salt */
|
||||||
|
if (!base64_decode (d->digest, grub_strlen (d->digest), (char *)digest, &digestlen))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest");
|
||||||
|
if (!base64_decode (d->salt, grub_strlen (d->salt), (char *)salt, &saltlen))
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest salt");
|
||||||
|
|
||||||
|
/* Configure the hash used for the digest. */
|
||||||
|
hash = grub_crypto_lookup_md_by_name (d->hash);
|
||||||
|
if (!hash)
|
||||||
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", d->hash);
|
||||||
|
|
||||||
|
/* Calculate the candidate key's digest */
|
||||||
|
gcry_ret = grub_crypto_pbkdf2 (hash,
|
||||||
|
candidate_key, candidate_key_len,
|
||||||
|
salt, saltlen,
|
||||||
|
d->iterations,
|
||||||
|
candidate_digest, digestlen);
|
||||||
|
if (gcry_ret)
|
||||||
|
return grub_crypto_gcry_error (gcry_ret);
|
||||||
|
|
||||||
|
if (grub_memcmp (candidate_digest, digest, digestlen) != 0)
|
||||||
|
return grub_error (GRUB_ERR_ACCESS_DENIED, "Mismatching digests");
|
||||||
|
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_decrypt_key (grub_uint8_t *out_key,
|
||||||
|
grub_disk_t disk, grub_cryptodisk_t crypt,
|
||||||
|
grub_luks2_keyslot_t *k,
|
||||||
|
const grub_uint8_t *passphrase, grub_size_t passphraselen)
|
||||||
|
{
|
||||||
|
grub_uint8_t area_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
|
grub_uint8_t salt[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
|
grub_uint8_t *split_key = NULL;
|
||||||
|
grub_size_t saltlen = sizeof (salt);
|
||||||
|
char cipher[32], *p;;
|
||||||
|
const gcry_md_spec_t *hash;
|
||||||
|
gcry_err_code_t gcry_ret;
|
||||||
|
grub_err_t ret;
|
||||||
|
|
||||||
|
if (!base64_decode (k->kdf.salt, grub_strlen (k->kdf.salt),
|
||||||
|
(char *)salt, &saltlen))
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot salt");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the binary area key of the user supplied passphrase. */
|
||||||
|
switch (k->kdf.type)
|
||||||
|
{
|
||||||
|
case LUKS2_KDF_TYPE_ARGON2I:
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Argon2 not supported");
|
||||||
|
goto err;
|
||||||
|
case LUKS2_KDF_TYPE_PBKDF2:
|
||||||
|
hash = grub_crypto_lookup_md_by_name (k->kdf.u.pbkdf2.hash);
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
|
||||||
|
k->kdf.u.pbkdf2.hash);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcry_ret = grub_crypto_pbkdf2 (hash, (grub_uint8_t *) passphrase,
|
||||||
|
passphraselen,
|
||||||
|
salt, saltlen,
|
||||||
|
k->kdf.u.pbkdf2.iterations,
|
||||||
|
area_key, k->area.key_size);
|
||||||
|
if (gcry_ret)
|
||||||
|
{
|
||||||
|
ret = grub_crypto_gcry_error (gcry_ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up disk encryption parameters for the key area */
|
||||||
|
grub_strncpy (cipher, k->area.encryption, sizeof (cipher));
|
||||||
|
p = grub_memchr (cipher, '-', grub_strlen (cipher));
|
||||||
|
if (!p)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid encryption");
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
ret = grub_cryptodisk_setcipher (crypt, cipher, p + 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
gcry_ret = grub_cryptodisk_setkey (crypt, area_key, k->area.key_size);
|
||||||
|
if (gcry_ret)
|
||||||
|
{
|
||||||
|
ret = grub_crypto_gcry_error (gcry_ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read and decrypt the binary key area with the area key. */
|
||||||
|
split_key = grub_malloc (k->area.size);
|
||||||
|
if (!split_key)
|
||||||
|
{
|
||||||
|
ret = grub_errno;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
ret = grub_disk_read (disk, 0, k->area.offset, k->area.size, split_key);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_IO, "Read error: %s\n", grub_errmsg);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcry_ret = grub_cryptodisk_decrypt (crypt, split_key, k->area.size, 0);
|
||||||
|
if (gcry_ret)
|
||||||
|
{
|
||||||
|
ret = grub_crypto_gcry_error (gcry_ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure the hash used for anti-forensic merging. */
|
||||||
|
hash = grub_crypto_lookup_md_by_name (k->af.hash);
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
|
||||||
|
k->af.hash);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge the decrypted key material to get the candidate master key. */
|
||||||
|
gcry_ret = AF_merge (hash, split_key, out_key, k->key_size, k->af.stripes);
|
||||||
|
if (gcry_ret)
|
||||||
|
{
|
||||||
|
ret = grub_crypto_gcry_error (gcry_ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_dprintf ("luks2", "Candidate key recovered\n");
|
||||||
|
|
||||||
|
err:
|
||||||
|
grub_free (split_key);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
luks2_recover_key (grub_disk_t disk,
|
||||||
|
grub_cryptodisk_t crypt)
|
||||||
|
{
|
||||||
|
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||||
|
char passphrase[MAX_PASSPHRASE], cipher[32];
|
||||||
|
char *json_header = NULL, *part = NULL, *ptr;
|
||||||
|
grub_size_t candidate_key_len = 0, i, size;
|
||||||
|
grub_luks2_header_t header;
|
||||||
|
grub_luks2_keyslot_t keyslot;
|
||||||
|
grub_luks2_digest_t digest;
|
||||||
|
grub_luks2_segment_t segment;
|
||||||
|
gcry_err_code_t gcry_ret;
|
||||||
|
grub_json_t *json = NULL, keyslots;
|
||||||
|
grub_err_t ret;
|
||||||
|
|
||||||
|
ret = luks2_read_header (disk, &header);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
json_header = grub_zalloc (grub_be_to_cpu64 (header.hdr_size) - sizeof (header));
|
||||||
|
if (!json_header)
|
||||||
|
return GRUB_ERR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/* Read the JSON area. */
|
||||||
|
ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (header.hdr_offset) + sizeof (header),
|
||||||
|
grub_be_to_cpu64 (header.hdr_size) - sizeof (header), json_header);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ptr = grub_memchr (json_header, 0, grub_be_to_cpu64 (header.hdr_size) - sizeof (header));
|
||||||
|
if (!ptr)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ret = grub_json_parse (&json, json_header, grub_be_to_cpu64 (header.hdr_size));
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid LUKS2 JSON header");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the passphrase from the user. */
|
||||||
|
if (disk->partition)
|
||||||
|
part = grub_partition_get_name (disk->partition);
|
||||||
|
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), disk->name,
|
||||||
|
disk->partition ? "," : "", part ? : "",
|
||||||
|
crypt->uuid);
|
||||||
|
if (!grub_password_get (passphrase, MAX_PASSPHRASE))
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grub_json_getvalue (&keyslots, json, "keyslots") ||
|
||||||
|
grub_json_getsize (&size, &keyslots))
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not get keyslots");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try all keyslot */
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ret = luks2_get_keyslot (&keyslot, &digest, &segment, json, i);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (keyslot.priority == 0)
|
||||||
|
{
|
||||||
|
grub_dprintf ("luks2", "Ignoring keyslot %"PRIuGRUB_SIZE" due to priority\n", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_dprintf ("luks2", "Trying keyslot %"PRIuGRUB_SIZE"\n", i);
|
||||||
|
|
||||||
|
/* Set up disk according to keyslot's segment. */
|
||||||
|
crypt->offset = grub_divmod64 (segment.offset, segment.sector_size, NULL);
|
||||||
|
crypt->log_sector_size = sizeof (unsigned int) * 8
|
||||||
|
- __builtin_clz ((unsigned int) segment.sector_size) - 1;
|
||||||
|
if (grub_strcmp (segment.size, "dynamic") == 0)
|
||||||
|
crypt->total_length = grub_disk_get_size (disk) - crypt->offset;
|
||||||
|
else
|
||||||
|
crypt->total_length = grub_strtoull (segment.size, NULL, 10);
|
||||||
|
|
||||||
|
ret = luks2_decrypt_key (candidate_key, disk, crypt, &keyslot,
|
||||||
|
(const grub_uint8_t *) passphrase, grub_strlen (passphrase));
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
grub_dprintf ("luks2", "Decryption with keyslot %"PRIuGRUB_SIZE" failed: %s\n",
|
||||||
|
i, grub_errmsg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = luks2_verify_key (&digest, candidate_key, keyslot.key_size);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
grub_dprintf ("luks2", "Could not open keyslot %"PRIuGRUB_SIZE": %s\n",
|
||||||
|
i, grub_errmsg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TRANSLATORS: It's a cryptographic key slot: one element of an array
|
||||||
|
* where each element is either empty or holds a key.
|
||||||
|
*/
|
||||||
|
grub_printf_ (N_("Slot %"PRIuGRUB_SIZE" opened\n"), i);
|
||||||
|
|
||||||
|
candidate_key_len = keyslot.key_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (candidate_key_len == 0)
|
||||||
|
{
|
||||||
|
ret = grub_error (GRUB_ERR_ACCESS_DENIED, "Invalid passphrase");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up disk cipher. */
|
||||||
|
grub_strncpy (cipher, segment.encryption, sizeof (cipher));
|
||||||
|
ptr = grub_memchr (cipher, '-', grub_strlen (cipher));
|
||||||
|
if (!ptr)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid encryption");
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
ret = grub_cryptodisk_setcipher (crypt, cipher, ptr + 1);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* Set the master key. */
|
||||||
|
gcry_ret = grub_cryptodisk_setkey (crypt, candidate_key, candidate_key_len);
|
||||||
|
if (gcry_ret)
|
||||||
|
{
|
||||||
|
ret = grub_crypto_gcry_error (gcry_ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
grub_free (part);
|
||||||
|
grub_free (json_header);
|
||||||
|
grub_json_free (json);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct grub_cryptodisk_dev luks2_crypto = {
|
||||||
|
.scan = luks2_scan,
|
||||||
|
.recover_key = luks2_recover_key
|
||||||
|
};
|
||||||
|
|
||||||
|
GRUB_MOD_INIT (luks2)
|
||||||
|
{
|
||||||
|
grub_cryptodisk_dev_register (&luks2_crypto);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI (luks2)
|
||||||
|
{
|
||||||
|
grub_cryptodisk_dev_unregister (&luks2_crypto);
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
#include <grub/lvm.h>
|
#include <grub/lvm.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/emu/misc.h>
|
#include <grub/emu/misc.h>
|
||||||
|
@ -33,12 +34,20 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
struct cache_lv
|
||||||
|
{
|
||||||
|
struct grub_diskfilter_lv *lv;
|
||||||
|
char *cache_pool;
|
||||||
|
char *origin;
|
||||||
|
struct cache_lv *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Go the string STR and return the number after STR. *P will point
|
/* Go the string STR and return the number after STR. *P will point
|
||||||
at the number. In case STR is not found, *P will be NULL and the
|
at the number. In case STR is not found, *P will be NULL and the
|
||||||
return value will be 0. */
|
return value will be 0. */
|
||||||
static grub_uint64_t
|
static grub_uint64_t
|
||||||
grub_lvm_getvalue (char **p, const char *str)
|
grub_lvm_getvalue (const char ** const p, const char *str)
|
||||||
{
|
{
|
||||||
*p = grub_strstr (*p, str);
|
*p = grub_strstr (*p, str);
|
||||||
if (! *p)
|
if (! *p)
|
||||||
|
@ -63,12 +72,12 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_lvm_check_flag (char *p, const char *str, const char *flag)
|
grub_lvm_check_flag (const char *p, const char *str, const char *flag)
|
||||||
{
|
{
|
||||||
grub_size_t len_str = grub_strlen (str), len_flag = grub_strlen (flag);
|
grub_size_t len_str = grub_strlen (str), len_flag = grub_strlen (flag);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
char *q;
|
const char *q;
|
||||||
p = grub_strstr (p, str);
|
p = grub_strstr (p, str);
|
||||||
if (! p)
|
if (! p)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -95,6 +104,34 @@ grub_lvm_check_flag (char *p, const char *str, const char *flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_lvm_free_cache_lvs (struct cache_lv *cache_lvs)
|
||||||
|
{
|
||||||
|
struct cache_lv *cache;
|
||||||
|
|
||||||
|
while ((cache = cache_lvs))
|
||||||
|
{
|
||||||
|
cache_lvs = cache_lvs->next;
|
||||||
|
|
||||||
|
if (cache->lv)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < cache->lv->segment_count; ++i)
|
||||||
|
if (cache->lv->segments)
|
||||||
|
grub_free (cache->lv->segments[i].nodes);
|
||||||
|
grub_free (cache->lv->segments);
|
||||||
|
grub_free (cache->lv->fullname);
|
||||||
|
grub_free (cache->lv->idname);
|
||||||
|
grub_free (cache->lv->name);
|
||||||
|
}
|
||||||
|
grub_free (cache->lv);
|
||||||
|
grub_free (cache->origin);
|
||||||
|
grub_free (cache->cache_pool);
|
||||||
|
grub_free (cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct grub_diskfilter_vg *
|
static struct grub_diskfilter_vg *
|
||||||
grub_lvm_detect (grub_disk_t disk,
|
grub_lvm_detect (grub_disk_t disk,
|
||||||
struct grub_diskfilter_pv_id *id,
|
struct grub_diskfilter_pv_id *id,
|
||||||
|
@ -102,10 +139,12 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_uint64_t mda_offset, mda_size;
|
grub_uint64_t mda_offset, mda_size;
|
||||||
|
grub_size_t ptr;
|
||||||
char buf[GRUB_LVM_LABEL_SIZE];
|
char buf[GRUB_LVM_LABEL_SIZE];
|
||||||
char vg_id[GRUB_LVM_ID_STRLEN+1];
|
char vg_id[GRUB_LVM_ID_STRLEN+1];
|
||||||
char pv_id[GRUB_LVM_ID_STRLEN+1];
|
char pv_id[GRUB_LVM_ID_STRLEN+1];
|
||||||
char *metadatabuf, *p, *q, *vgname;
|
char *metadatabuf, *mda_end, *vgname;
|
||||||
|
const char *p, *q;
|
||||||
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
|
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
|
||||||
struct grub_lvm_pv_header *pvh;
|
struct grub_lvm_pv_header *pvh;
|
||||||
struct grub_lvm_disk_locn *dlocn;
|
struct grub_lvm_disk_locn *dlocn;
|
||||||
|
@ -173,7 +212,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
first one. */
|
first one. */
|
||||||
|
|
||||||
/* Allocate buffer space for the circular worst-case scenario. */
|
/* Allocate buffer space for the circular worst-case scenario. */
|
||||||
metadatabuf = grub_malloc (2 * mda_size);
|
metadatabuf = grub_calloc (2, mda_size);
|
||||||
if (! metadatabuf)
|
if (! metadatabuf)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -205,19 +244,31 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
grub_le_to_cpu64 (rlocn->size) -
|
grub_le_to_cpu64 (rlocn->size) -
|
||||||
grub_le_to_cpu64 (mdah->size));
|
grub_le_to_cpu64 (mdah->size));
|
||||||
}
|
}
|
||||||
p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
|
|
||||||
|
|
||||||
while (*q != ' ' && q < metadatabuf + mda_size)
|
if (grub_add ((grub_size_t)metadatabuf,
|
||||||
q++;
|
(grub_size_t)grub_le_to_cpu64 (rlocn->offset),
|
||||||
|
&ptr))
|
||||||
if (q == metadatabuf + mda_size)
|
|
||||||
{
|
{
|
||||||
|
error_parsing_metadata:
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_util_info ("error parsing metadata");
|
grub_util_info ("error parsing metadata");
|
||||||
#endif
|
#endif
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = q = (char *)ptr;
|
||||||
|
|
||||||
|
if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
|
||||||
|
goto error_parsing_metadata;
|
||||||
|
|
||||||
|
mda_end = (char *)ptr;
|
||||||
|
|
||||||
|
while (*q != ' ' && q < mda_end)
|
||||||
|
q++;
|
||||||
|
|
||||||
|
if (q == mda_end)
|
||||||
|
goto error_parsing_metadata;
|
||||||
|
|
||||||
vgname_len = q - p;
|
vgname_len = q - p;
|
||||||
vgname = grub_malloc (vgname_len + 1);
|
vgname = grub_malloc (vgname_len + 1);
|
||||||
if (!vgname)
|
if (!vgname)
|
||||||
|
@ -242,6 +293,8 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
|
|
||||||
if (! vg)
|
if (! vg)
|
||||||
{
|
{
|
||||||
|
struct cache_lv *cache_lvs = NULL;
|
||||||
|
|
||||||
/* First time we see this volume group. We've to create the
|
/* First time we see this volume group. We've to create the
|
||||||
whole volume group structure. */
|
whole volume group structure. */
|
||||||
vg = grub_malloc (sizeof (*vg));
|
vg = grub_malloc (sizeof (*vg));
|
||||||
|
@ -367,8 +420,26 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
{
|
{
|
||||||
const char *iptr;
|
const char *iptr;
|
||||||
char *optr;
|
char *optr;
|
||||||
lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
|
|
||||||
+ 1 + 2 * s + 1);
|
/*
|
||||||
|
* This is kind of hard to read with our safe (but rather
|
||||||
|
* baroque) math primatives, but it boils down to:
|
||||||
|
*
|
||||||
|
* sz0 = vgname_len * 2 + 1 +
|
||||||
|
* s * 2 + 1 +
|
||||||
|
* sizeof ("lvm/") - 1;
|
||||||
|
*/
|
||||||
|
grub_size_t sz0 = vgname_len, sz1 = s;
|
||||||
|
|
||||||
|
if (grub_mul (sz0, 2, &sz0) ||
|
||||||
|
grub_add (sz0, 1, &sz0) ||
|
||||||
|
grub_mul (sz1, 2, &sz1) ||
|
||||||
|
grub_add (sz1, 1, &sz1) ||
|
||||||
|
grub_add (sz0, sz1, &sz0) ||
|
||||||
|
grub_add (sz0, sizeof ("lvm/") - 1, &sz0))
|
||||||
|
goto lvs_fail;
|
||||||
|
|
||||||
|
lv->fullname = grub_malloc (sz0);
|
||||||
if (!lv->fullname)
|
if (!lv->fullname)
|
||||||
goto lvs_fail;
|
goto lvs_fail;
|
||||||
|
|
||||||
|
@ -426,7 +497,7 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
#endif
|
#endif
|
||||||
goto lvs_fail;
|
goto lvs_fail;
|
||||||
}
|
}
|
||||||
lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count);
|
lv->segments = grub_calloc (lv->segment_count, sizeof (*seg));
|
||||||
seg = lv->segments;
|
seg = lv->segments;
|
||||||
|
|
||||||
for (i = 0; i < lv->segment_count; i++)
|
for (i = 0; i < lv->segment_count; i++)
|
||||||
|
@ -483,8 +554,8 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
if (seg->node_count != 1)
|
if (seg->node_count != 1)
|
||||||
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
|
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
|
||||||
|
|
||||||
seg->nodes = grub_zalloc (sizeof (*stripe)
|
seg->nodes = grub_calloc (seg->node_count,
|
||||||
* seg->node_count);
|
sizeof (*stripe));
|
||||||
stripe = seg->nodes;
|
stripe = seg->nodes;
|
||||||
|
|
||||||
p = grub_strstr (p, "stripes = [");
|
p = grub_strstr (p, "stripes = [");
|
||||||
|
@ -671,6 +742,106 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
seg->nodes[seg->node_count - 1].name = tmp;
|
seg->nodes[seg->node_count - 1].name = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (grub_memcmp (p, "cache\"",
|
||||||
|
sizeof ("cache\"") - 1) == 0)
|
||||||
|
{
|
||||||
|
struct cache_lv *cache = NULL;
|
||||||
|
|
||||||
|
char *p2, *p3;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
cache = grub_zalloc (sizeof (*cache));
|
||||||
|
if (!cache)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
cache->lv = grub_zalloc (sizeof (*cache->lv));
|
||||||
|
if (!cache->lv)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
grub_memcpy (cache->lv, lv, sizeof (*cache->lv));
|
||||||
|
|
||||||
|
if (lv->fullname)
|
||||||
|
{
|
||||||
|
cache->lv->fullname = grub_strdup (lv->fullname);
|
||||||
|
if (!cache->lv->fullname)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
}
|
||||||
|
if (lv->idname)
|
||||||
|
{
|
||||||
|
cache->lv->idname = grub_strdup (lv->idname);
|
||||||
|
if (!cache->lv->idname)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
}
|
||||||
|
if (lv->name)
|
||||||
|
{
|
||||||
|
cache->lv->name = grub_strdup (lv->name);
|
||||||
|
if (!cache->lv->name)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_lv = 1;
|
||||||
|
|
||||||
|
p2 = grub_strstr (p, "cache_pool = \"");
|
||||||
|
if (!p2)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
|
||||||
|
p2 = grub_strchr (p2, '"');
|
||||||
|
if (!p2)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
|
||||||
|
p3 = ++p2;
|
||||||
|
p3 = grub_strchr (p3, '"');
|
||||||
|
if (!p3)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
|
||||||
|
sz = p3 - p2;
|
||||||
|
|
||||||
|
cache->cache_pool = grub_malloc (sz + 1);
|
||||||
|
if (!cache->cache_pool)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
grub_memcpy (cache->cache_pool, p2, sz);
|
||||||
|
cache->cache_pool[sz] = '\0';
|
||||||
|
|
||||||
|
p2 = grub_strstr (p, "origin = \"");
|
||||||
|
if (!p2)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
|
||||||
|
p2 = grub_strchr (p2, '"');
|
||||||
|
if (!p2)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
|
||||||
|
p3 = ++p2;
|
||||||
|
p3 = grub_strchr (p3, '"');
|
||||||
|
if (!p3)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
|
||||||
|
sz = p3 - p2;
|
||||||
|
|
||||||
|
cache->origin = grub_malloc (sz + 1);
|
||||||
|
if (!cache->origin)
|
||||||
|
goto cache_lv_fail;
|
||||||
|
grub_memcpy (cache->origin, p2, sz);
|
||||||
|
cache->origin[sz] = '\0';
|
||||||
|
|
||||||
|
cache->next = cache_lvs;
|
||||||
|
cache_lvs = cache;
|
||||||
|
break;
|
||||||
|
|
||||||
|
cache_lv_fail:
|
||||||
|
if (cache)
|
||||||
|
{
|
||||||
|
grub_free (cache->origin);
|
||||||
|
grub_free (cache->cache_pool);
|
||||||
|
if (cache->lv)
|
||||||
|
{
|
||||||
|
grub_free (cache->lv->fullname);
|
||||||
|
grub_free (cache->lv->idname);
|
||||||
|
grub_free (cache->lv->name);
|
||||||
|
}
|
||||||
|
grub_free (cache->lv);
|
||||||
|
grub_free (cache);
|
||||||
|
}
|
||||||
|
grub_lvm_free_cache_lvs (cache_lvs);
|
||||||
|
goto fail4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
|
@ -747,6 +918,58 @@ grub_lvm_detect (grub_disk_t disk,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct cache_lv *cache;
|
||||||
|
|
||||||
|
for (cache = cache_lvs; cache; cache = cache->next)
|
||||||
|
{
|
||||||
|
struct grub_diskfilter_lv *lv;
|
||||||
|
|
||||||
|
for (lv = vg->lvs; lv; lv = lv->next)
|
||||||
|
if (grub_strcmp (lv->name, cache->origin) == 0)
|
||||||
|
break;
|
||||||
|
if (lv)
|
||||||
|
{
|
||||||
|
cache->lv->segments = grub_calloc (lv->segment_count, sizeof (*lv->segments));
|
||||||
|
if (!cache->lv->segments)
|
||||||
|
{
|
||||||
|
grub_lvm_free_cache_lvs (cache_lvs);
|
||||||
|
goto fail4;
|
||||||
|
}
|
||||||
|
grub_memcpy (cache->lv->segments, lv->segments, lv->segment_count * sizeof (*lv->segments));
|
||||||
|
|
||||||
|
for (i = 0; i < lv->segment_count; ++i)
|
||||||
|
{
|
||||||
|
struct grub_diskfilter_node *nodes = lv->segments[i].nodes;
|
||||||
|
grub_size_t node_count = lv->segments[i].node_count;
|
||||||
|
|
||||||
|
cache->lv->segments[i].nodes = grub_calloc (node_count, sizeof (*nodes));
|
||||||
|
if (!cache->lv->segments[i].nodes)
|
||||||
|
{
|
||||||
|
for (j = 0; j < i; ++j)
|
||||||
|
grub_free (cache->lv->segments[j].nodes);
|
||||||
|
grub_free (cache->lv->segments);
|
||||||
|
cache->lv->segments = NULL;
|
||||||
|
grub_lvm_free_cache_lvs (cache_lvs);
|
||||||
|
goto fail4;
|
||||||
|
}
|
||||||
|
grub_memcpy (cache->lv->segments[i].nodes, nodes, node_count * sizeof (*nodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->lv->segments)
|
||||||
|
{
|
||||||
|
cache->lv->segment_count = lv->segment_count;
|
||||||
|
cache->lv->vg = vg;
|
||||||
|
cache->lv->next = vg->lvs;
|
||||||
|
vg->lvs = cache->lv;
|
||||||
|
cache->lv = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_lvm_free_cache_lvs (cache_lvs);
|
||||||
if (grub_diskfilter_vg_register (vg))
|
if (grub_diskfilter_vg_register (vg))
|
||||||
goto fail4;
|
goto fail4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ grub_mdraid_detect (grub_disk_t disk,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (grub_disk_read (disk, sector,
|
if (grub_disk_read (disk, sector,
|
||||||
(char *) &sb.dev_roles[grub_le_to_cpu32 (sb.dev_number)]
|
(char *) (sb.dev_roles + grub_le_to_cpu32 (sb.dev_number))
|
||||||
- (char *) &sb,
|
- (char *) &sb,
|
||||||
sizeof (role), &role))
|
sizeof (role), &role))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -426,7 +426,7 @@ grub_xendisk_init (void)
|
||||||
if (!ctr)
|
if (!ctr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
virtdisks = grub_malloc (ctr * sizeof (virtdisks[0]));
|
virtdisks = grub_calloc (ctr, sizeof (virtdisks[0]));
|
||||||
if (!virtdisks)
|
if (!virtdisks)
|
||||||
return;
|
return;
|
||||||
if (grub_xenstore_dir ("device/vbd", fill, &ctr))
|
if (grub_xenstore_dir ("device/vbd", fill, &ctr))
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/acpi.h>
|
#include <grub/acpi.h>
|
||||||
|
#include <grub/smbios.h>
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_machine_efiemu_init_tables (void)
|
grub_machine_efiemu_init_tables (void)
|
||||||
{
|
{
|
||||||
grub_uint8_t *ptr;
|
|
||||||
void *table;
|
void *table;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID;
|
grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID;
|
||||||
|
@ -57,17 +57,10 @@ grub_machine_efiemu_init_tables (void)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
table = grub_smbios_get_eps ();
|
||||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
|
if (table)
|
||||||
ptr += 16)
|
|
||||||
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
|
||||||
&& grub_byte_checksum (ptr, *(ptr + 5)) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (ptr < (grub_uint8_t *) 0x100000)
|
|
||||||
{
|
{
|
||||||
grub_dprintf ("efiemu", "Registering SMBIOS\n");
|
err = grub_efiemu_register_configuration_table (smbios, 0, 0, table);
|
||||||
err = grub_efiemu_register_configuration_table (smbios, 0, 0, ptr);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e)
|
||||||
|
|
||||||
grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
|
grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
|
||||||
grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
|
grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
|
||||||
grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
|
grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym));
|
||||||
|
|
||||||
/* Relocators */
|
/* Relocators */
|
||||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||||
|
|
|
@ -554,11 +554,11 @@ grub_efiemu_mmap_sort_and_uniq (void)
|
||||||
/* Initialize variables*/
|
/* Initialize variables*/
|
||||||
grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
|
grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
|
||||||
scanline_events = (struct grub_efiemu_mmap_scan *)
|
scanline_events = (struct grub_efiemu_mmap_scan *)
|
||||||
grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
|
grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2);
|
||||||
|
|
||||||
/* Number of chunks can't increase more than by factor of 2 */
|
/* Number of chunks can't increase more than by factor of 2 */
|
||||||
result = (grub_efi_memory_descriptor_t *)
|
result = (grub_efi_memory_descriptor_t *)
|
||||||
grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
|
grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2);
|
||||||
if (!result || !scanline_events)
|
if (!result || !scanline_events)
|
||||||
{
|
{
|
||||||
grub_free (result);
|
grub_free (result);
|
||||||
|
@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void)
|
||||||
|
|
||||||
/* Preallocate mmap */
|
/* Preallocate mmap */
|
||||||
efiemu_mmap = (grub_efi_memory_descriptor_t *)
|
efiemu_mmap = (grub_efi_memory_descriptor_t *)
|
||||||
grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
|
grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t));
|
||||||
if (!efiemu_mmap)
|
if (!efiemu_mmap)
|
||||||
{
|
{
|
||||||
grub_efiemu_unload ();
|
grub_efiemu_unload ();
|
||||||
|
|
|
@ -39,7 +39,7 @@ static grub_size_t nvramsize;
|
||||||
|
|
||||||
/* Parse signed value */
|
/* Parse signed value */
|
||||||
static int
|
static int
|
||||||
grub_strtosl (const char *arg, char **end, int base)
|
grub_strtosl (const char *arg, const char ** const end, int base)
|
||||||
{
|
{
|
||||||
if (arg[0] == '-')
|
if (arg[0] == '-')
|
||||||
return -grub_strtoul (arg + 1, end, base);
|
return -grub_strtoul (arg + 1, end, base);
|
||||||
|
@ -120,7 +120,8 @@ nvram_set (void * data __attribute__ ((unused)))
|
||||||
grub_memset (nvram, 0, nvramsize);
|
grub_memset (nvram, 0, nvramsize);
|
||||||
FOR_SORTED_ENV (var)
|
FOR_SORTED_ENV (var)
|
||||||
{
|
{
|
||||||
char *guid, *attr, *name, *varname;
|
const char *guid;
|
||||||
|
char *attr, *name, *varname;
|
||||||
struct efi_variable *efivar;
|
struct efi_variable *efivar;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <grub/unicode.h>
|
#include <grub/unicode.h>
|
||||||
#include <grub/fontformat.h>
|
#include <grub/fontformat.h>
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -293,8 +294,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
||||||
font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
|
font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
|
||||||
|
|
||||||
/* Allocate the character index array. */
|
/* Allocate the character index array. */
|
||||||
font->char_index = grub_malloc (font->num_chars
|
font->char_index = grub_calloc (font->num_chars, sizeof (struct char_index_entry));
|
||||||
* sizeof (struct char_index_entry));
|
|
||||||
if (!font->char_index)
|
if (!font->char_index)
|
||||||
return 1;
|
return 1;
|
||||||
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
||||||
|
@ -361,9 +361,13 @@ static char *
|
||||||
read_section_as_string (struct font_file_section *section)
|
read_section_as_string (struct font_file_section *section)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
grub_size_t sz;
|
||||||
grub_ssize_t ret;
|
grub_ssize_t ret;
|
||||||
|
|
||||||
str = grub_malloc (section->length + 1);
|
if (grub_add (section->length, 1, &sz))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
str = grub_malloc (sz);
|
||||||
if (!str)
|
if (!str)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -528,6 +532,12 @@ grub_font_load (const char *filename)
|
||||||
if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
|
if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
|
||||||
sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
|
sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
|
||||||
{
|
{
|
||||||
|
if (font->name != NULL)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FONT, "invalid font file: too many NAME sections");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
font->name = read_section_as_string (§ion);
|
font->name = read_section_as_string (§ion);
|
||||||
if (!font->name)
|
if (!font->name)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -301,7 +301,7 @@ grub_affs_read_symlink (grub_fshelp_node_t node)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
latin1[symlink_size] = 0;
|
latin1[symlink_size] = 0;
|
||||||
utf8 = grub_malloc (symlink_size * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size);
|
||||||
if (!utf8)
|
if (!utf8)
|
||||||
{
|
{
|
||||||
grub_free (latin1);
|
grub_free (latin1);
|
||||||
|
@ -422,7 +422,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashtable = grub_zalloc (data->htsize * sizeof (*hashtable));
|
hashtable = grub_calloc (data->htsize, sizeof (*hashtable));
|
||||||
if (!hashtable)
|
if (!hashtable)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -628,7 +628,7 @@ grub_affs_label (grub_device_t device, char **label)
|
||||||
len = file.namelen;
|
len = file.namelen;
|
||||||
if (len > sizeof (file.name))
|
if (len > sizeof (file.name))
|
||||||
len = sizeof (file.name);
|
len = sizeof (file.name);
|
||||||
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
*label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len);
|
||||||
if (*label)
|
if (*label)
|
||||||
*grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0';
|
*grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0';
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <grub/btrfs.h>
|
#include <grub/btrfs.h>
|
||||||
#include <grub/crypto.h>
|
#include <grub/crypto.h>
|
||||||
#include <grub/diskfilter.h>
|
#include <grub/diskfilter.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -136,6 +137,8 @@ struct grub_btrfs_chunk_item
|
||||||
#define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40
|
#define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40
|
||||||
#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80
|
#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80
|
||||||
#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100
|
#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100
|
||||||
|
#define GRUB_BTRFS_CHUNK_TYPE_RAID1C3 0x200
|
||||||
|
#define GRUB_BTRFS_CHUNK_TYPE_RAID1C4 0x400
|
||||||
grub_uint8_t dummy2[0xc];
|
grub_uint8_t dummy2[0xc];
|
||||||
grub_uint16_t nstripes;
|
grub_uint16_t nstripes;
|
||||||
grub_uint16_t nsubstripes;
|
grub_uint16_t nsubstripes;
|
||||||
|
@ -329,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
|
||||||
if (desc->allocated < desc->depth)
|
if (desc->allocated < desc->depth)
|
||||||
{
|
{
|
||||||
void *newdata;
|
void *newdata;
|
||||||
desc->allocated *= 2;
|
grub_size_t sz;
|
||||||
newdata = grub_realloc (desc->data, sizeof (desc->data[0])
|
|
||||||
* desc->allocated);
|
if (grub_mul (desc->allocated, 2, &desc->allocated) ||
|
||||||
|
grub_mul (desc->allocated, sizeof (desc->data[0]), &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
newdata = grub_realloc (desc->data, sz);
|
||||||
if (!newdata)
|
if (!newdata)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
desc->data = newdata;
|
desc->data = newdata;
|
||||||
|
@ -413,7 +420,7 @@ lower_bound (struct grub_btrfs_data *data,
|
||||||
{
|
{
|
||||||
desc->allocated = 16;
|
desc->allocated = 16;
|
||||||
desc->depth = 0;
|
desc->depth = 0;
|
||||||
desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated);
|
desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0]));
|
||||||
if (!desc->data)
|
if (!desc->data)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
@ -622,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
|
||||||
if (data->n_devices_attached > data->n_devices_allocated)
|
if (data->n_devices_attached > data->n_devices_allocated)
|
||||||
{
|
{
|
||||||
void *tmp;
|
void *tmp;
|
||||||
data->n_devices_allocated = 2 * data->n_devices_attached + 1;
|
grub_size_t sz;
|
||||||
data->devices_attached
|
|
||||||
= grub_realloc (tmp = data->devices_attached,
|
if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
|
||||||
data->n_devices_allocated
|
grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
|
||||||
* sizeof (data->devices_attached[0]));
|
grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
|
||||||
if (!data->devices_attached)
|
if (!data->devices_attached)
|
||||||
{
|
{
|
||||||
|
data->devices_attached = tmp;
|
||||||
|
|
||||||
|
fail:
|
||||||
if (ctx.dev_found)
|
if (ctx.dev_found)
|
||||||
grub_device_close (ctx.dev_found);
|
grub_device_close (ctx.dev_found);
|
||||||
data->devices_attached = tmp;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -752,7 +764,7 @@ raid56_read_retry (struct grub_btrfs_data *data,
|
||||||
grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY;
|
grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY;
|
||||||
grub_uint64_t i, failed_devices;
|
grub_uint64_t i, failed_devices;
|
||||||
|
|
||||||
buffers = grub_zalloc (sizeof(*buffers) * nstripes);
|
buffers = grub_calloc (nstripes, sizeof (*buffers));
|
||||||
if (!buffers)
|
if (!buffers)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -964,14 +976,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
|
||||||
csize = (stripen + 1) * stripe_length - off;
|
csize = (stripen + 1) * stripe_length - off;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GRUB_BTRFS_CHUNK_TYPE_RAID1C4:
|
||||||
|
redundancy++;
|
||||||
|
/* fall through */
|
||||||
|
case GRUB_BTRFS_CHUNK_TYPE_RAID1C3:
|
||||||
|
redundancy++;
|
||||||
|
/* fall through */
|
||||||
case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED:
|
case GRUB_BTRFS_CHUNK_TYPE_DUPLICATED:
|
||||||
case GRUB_BTRFS_CHUNK_TYPE_RAID1:
|
case GRUB_BTRFS_CHUNK_TYPE_RAID1:
|
||||||
{
|
{
|
||||||
grub_dprintf ("btrfs", "RAID1\n");
|
grub_dprintf ("btrfs", "RAID1 (copies: %d)\n", ++redundancy);
|
||||||
stripen = 0;
|
stripen = 0;
|
||||||
stripe_offset = off;
|
stripe_offset = off;
|
||||||
csize = grub_le_to_cpu64 (chunk->size) - off;
|
csize = grub_le_to_cpu64 (chunk->size) - off;
|
||||||
redundancy = 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GRUB_BTRFS_CHUNK_TYPE_RAID0:
|
case GRUB_BTRFS_CHUNK_TYPE_RAID0:
|
||||||
|
@ -2160,7 +2177,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
*nsectors = 64 * 2 - 1;
|
*nsectors = 64 * 2 - 1;
|
||||||
if (*nsectors > max_nsectors)
|
if (*nsectors > max_nsectors)
|
||||||
*nsectors = max_nsectors;
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_calloc (*nsectors, sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
for (i = 0; i < *nsectors; i++)
|
for (i = 0; i < *nsectors; i++)
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
char *symlink;
|
char *symlink;
|
||||||
struct grub_fshelp_node *diro = node;
|
struct grub_fshelp_node *diro = node;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (! diro->inode_read)
|
if (! diro->inode_read)
|
||||||
{
|
{
|
||||||
|
@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
|
if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
symlink = grub_malloc (sz);
|
||||||
if (! symlink)
|
if (! symlink)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/datetime.h>
|
||||||
#ifndef MODE_EXFAT
|
#ifndef MODE_EXFAT
|
||||||
#include <grub/fat.h>
|
#include <grub/fat.h>
|
||||||
#else
|
#else
|
||||||
|
@ -596,6 +597,7 @@ struct grub_fat_iterate_context
|
||||||
{
|
{
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
struct grub_fat_dir_node dir;
|
struct grub_fat_dir_node dir;
|
||||||
|
struct grub_fat_dir_entry entry;
|
||||||
#else
|
#else
|
||||||
struct grub_fat_dir_entry dir;
|
struct grub_fat_dir_entry dir;
|
||||||
#endif
|
#endif
|
||||||
|
@ -642,27 +644,27 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
||||||
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
|
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
struct grub_fat_dir_entry dir;
|
struct grub_fat_dir_entry *dir = &ctxt->entry;
|
||||||
|
|
||||||
ctxt->offset += sizeof (dir);
|
ctxt->offset += sizeof (*dir);
|
||||||
|
|
||||||
if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir),
|
if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (*dir),
|
||||||
(char *) &dir)
|
(char *) dir)
|
||||||
!= sizeof (dir))
|
!= sizeof (*dir))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (dir.entry_type == 0)
|
if (dir->entry_type == 0)
|
||||||
break;
|
break;
|
||||||
if (!(dir.entry_type & 0x80))
|
if (!(dir->entry_type & 0x80))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (dir.entry_type == 0x85)
|
if (dir->entry_type == 0x85)
|
||||||
{
|
{
|
||||||
unsigned i, nsec, slots = 0;
|
unsigned i, nsec, slots = 0;
|
||||||
|
|
||||||
nsec = dir.type_specific.file.secondary_count;
|
nsec = dir->type_specific.file.secondary_count;
|
||||||
|
|
||||||
ctxt->dir.attr = grub_cpu_to_le16 (dir.type_specific.file.attr);
|
ctxt->dir.attr = grub_cpu_to_le16 (dir->type_specific.file.attr);
|
||||||
ctxt->dir.have_stream = 0;
|
ctxt->dir.have_stream = 0;
|
||||||
for (i = 0; i < nsec; i++)
|
for (i = 0; i < nsec; i++)
|
||||||
{
|
{
|
||||||
|
@ -705,7 +707,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
||||||
|
|
||||||
if (i != nsec)
|
if (i != nsec)
|
||||||
{
|
{
|
||||||
ctxt->offset -= sizeof (dir);
|
ctxt->offset -= sizeof (*dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,20 +717,47 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Allocation bitmap. */
|
/* Allocation bitmap. */
|
||||||
if (dir.entry_type == 0x81)
|
if (dir->entry_type == 0x81)
|
||||||
continue;
|
continue;
|
||||||
/* Upcase table. */
|
/* Upcase table. */
|
||||||
if (dir.entry_type == 0x82)
|
if (dir->entry_type == 0x82)
|
||||||
continue;
|
continue;
|
||||||
/* Volume label. */
|
/* Volume label. */
|
||||||
if (dir.entry_type == 0x83)
|
if (dir->entry_type == 0x83)
|
||||||
continue;
|
continue;
|
||||||
grub_dprintf ("exfat", "unknown primary type 0x%02x\n",
|
grub_dprintf ("exfat", "unknown primary type 0x%02x\n",
|
||||||
dir.entry_type);
|
dir->entry_type);
|
||||||
}
|
}
|
||||||
return grub_errno ? : GRUB_ERR_EOF;
|
return grub_errno ? : GRUB_ERR_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a timestamp in exFAT format to seconds since the UNIX epoch
|
||||||
|
* according to sections 7.4.8 and 7.4.9 in the exFAT specification.
|
||||||
|
* https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_exfat_timestamp (grub_uint32_t field, grub_uint8_t msec, grub_int32_t *nix) {
|
||||||
|
struct grub_datetime datetime = {
|
||||||
|
.year = (field >> 25) + 1980,
|
||||||
|
.month = (field & 0x01E00000) >> 21,
|
||||||
|
.day = (field & 0x001F0000) >> 16,
|
||||||
|
.hour = (field & 0x0000F800) >> 11,
|
||||||
|
.minute = (field & 0x000007E0) >> 5,
|
||||||
|
.second = (field & 0x0000001F) * 2 + (msec >= 100 ? 1 : 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The conversion below allows seconds=60, so don't trust its validation. */
|
||||||
|
if ((field & 0x1F) > 29)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Validate the 10-msec field even though it is rounded down to seconds. */
|
||||||
|
if (msec > 199)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return grub_datetime2unixtime (&datetime, nix);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -856,6 +885,29 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
||||||
return grub_errno ? : GRUB_ERR_EOF;
|
return grub_errno ? : GRUB_ERR_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a date and time in FAT format to seconds since the UNIX epoch
|
||||||
|
* according to sections 11.3.5 and 11.3.6 in ECMA-107.
|
||||||
|
* https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-107.pdf
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
grub_fat_timestamp (grub_uint16_t time, grub_uint16_t date, grub_int32_t *nix) {
|
||||||
|
struct grub_datetime datetime = {
|
||||||
|
.year = (date >> 9) + 1980,
|
||||||
|
.month = (date & 0x01E0) >> 5,
|
||||||
|
.day = (date & 0x001F),
|
||||||
|
.hour = (time >> 11),
|
||||||
|
.minute = (time & 0x07E0) >> 5,
|
||||||
|
.second = (time & 0x001F) * 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The conversion below allows seconds=60, so don't trust its validation. */
|
||||||
|
if ((time & 0x1F) > 29)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return grub_datetime2unixtime (&datetime, nix);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static grub_err_t lookup_file (grub_fshelp_node_t node,
|
static grub_err_t lookup_file (grub_fshelp_node_t node,
|
||||||
|
@ -965,10 +1017,19 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
||||||
#ifdef MODE_EXFAT
|
#ifdef MODE_EXFAT
|
||||||
if (!ctxt.dir.have_stream)
|
if (!ctxt.dir.have_stream)
|
||||||
continue;
|
continue;
|
||||||
|
info.mtimeset = grub_exfat_timestamp (grub_le_to_cpu32 (ctxt.entry.type_specific.file.m_time),
|
||||||
|
ctxt.entry.type_specific.file.m_time_tenth,
|
||||||
|
&info.mtime);
|
||||||
#else
|
#else
|
||||||
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||||
continue;
|
continue;
|
||||||
|
info.mtimeset = grub_fat_timestamp (grub_le_to_cpu16 (ctxt.dir.w_time),
|
||||||
|
grub_le_to_cpu16 (ctxt.dir.w_date),
|
||||||
|
&info.mtime);
|
||||||
#endif
|
#endif
|
||||||
|
if (info.mtimeset == 0)
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
"invalid modification timestamp for %s", path);
|
||||||
|
|
||||||
if (hook (ctxt.filename, &info, hook_data))
|
if (hook (ctxt.filename, &info, hook_data))
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1360,7 +1360,7 @@ grub_hfs_label (grub_device_t device, char **label)
|
||||||
grub_size_t len = data->sblock.volname[0];
|
grub_size_t len = data->sblock.volname[0];
|
||||||
if (len > sizeof (data->sblock.volname) - 1)
|
if (len > sizeof (data->sblock.volname) - 1)
|
||||||
len = sizeof (data->sblock.volname) - 1;
|
len = sizeof (data->sblock.volname) - 1;
|
||||||
*label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1);
|
*label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len);
|
||||||
if (*label)
|
if (*label)
|
||||||
macroman_to_utf8 (*label, data->sblock.volname + 1,
|
macroman_to_utf8 (*label, data->sblock.volname + 1,
|
||||||
len + 1, 0);
|
len + 1, 0);
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <grub/hfs.h>
|
#include <grub/hfs.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
#include <grub/hfsplus.h>
|
#include <grub/hfsplus.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -475,8 +476,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
char *symlink;
|
char *symlink;
|
||||||
grub_ssize_t numread;
|
grub_ssize_t numread;
|
||||||
|
grub_size_t sz = node->size;
|
||||||
|
|
||||||
symlink = grub_malloc (node->size + 1);
|
if (grub_add (sz, 1, &sz))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
symlink = grub_malloc (sz);
|
||||||
if (!symlink)
|
if (!symlink)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -715,12 +720,12 @@ list_nodes (void *record, void *hook_arg)
|
||||||
if (type == GRUB_FSHELP_UNKNOWN)
|
if (type == GRUB_FSHELP_UNKNOWN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
|
filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen),
|
||||||
* GRUB_MAX_UTF8_PER_UTF16 + 1);
|
GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (! filename)
|
if (! filename)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname));
|
keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname));
|
||||||
if (!keyname)
|
if (!keyname)
|
||||||
{
|
{
|
||||||
grub_free (filename);
|
grub_free (filename);
|
||||||
|
@ -1007,7 +1012,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
||||||
grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr);
|
grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr);
|
||||||
|
|
||||||
label_len = grub_be_to_cpu16 (catkey->namelen);
|
label_len = grub_be_to_cpu16 (catkey->namelen);
|
||||||
label_name = grub_malloc (label_len * sizeof (*label_name));
|
label_name = grub_calloc (label_len, sizeof (*label_name));
|
||||||
if (!label_name)
|
if (!label_name)
|
||||||
{
|
{
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
|
@ -1029,7 +1034,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
*label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (! *label)
|
if (! *label)
|
||||||
{
|
{
|
||||||
grub_free (label_name);
|
grub_free (label_name);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
#include <grub/datetime.h>
|
#include <grub/datetime.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -331,7 +332,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len)
|
||||||
int i;
|
int i;
|
||||||
grub_uint16_t t[MAX_NAMELEN / 2 + 1];
|
grub_uint16_t t[MAX_NAMELEN / 2 + 1];
|
||||||
|
|
||||||
p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
if (! p)
|
if (! p)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -531,11 +532,22 @@ add_part (struct iterate_dir_ctx *ctx,
|
||||||
int len2)
|
int len2)
|
||||||
{
|
{
|
||||||
int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
|
int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
|
||||||
|
grub_size_t sz;
|
||||||
|
char *new;
|
||||||
|
|
||||||
ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1);
|
if (grub_add (size, len2, &sz) ||
|
||||||
if (! ctx->symlink)
|
grub_add (sz, 1, &sz))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
new = grub_realloc (ctx->symlink, sz);
|
||||||
|
if (!new)
|
||||||
|
{
|
||||||
|
grub_free (ctx->symlink);
|
||||||
|
ctx->symlink = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx->symlink = new;
|
||||||
|
|
||||||
grub_memcpy (ctx->symlink + size, part, len2);
|
grub_memcpy (ctx->symlink + size, part, len2);
|
||||||
ctx->symlink[size + len2] = 0;
|
ctx->symlink[size + len2] = 0;
|
||||||
}
|
}
|
||||||
|
@ -560,17 +572,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
||||||
{
|
{
|
||||||
grub_size_t off = 0, csize = 1;
|
grub_size_t off = 0, csize = 1;
|
||||||
char *old;
|
char *old;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
csize = entry->len - 5;
|
csize = entry->len - 5;
|
||||||
old = ctx->filename;
|
old = ctx->filename;
|
||||||
if (ctx->filename_alloc)
|
if (ctx->filename_alloc)
|
||||||
{
|
{
|
||||||
off = grub_strlen (ctx->filename);
|
off = grub_strlen (ctx->filename);
|
||||||
ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
|
if (grub_add (csize, off, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
ctx->filename = grub_realloc (ctx->filename, sz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
off = 0;
|
off = 0;
|
||||||
ctx->filename = grub_zalloc (csize + 1);
|
if (grub_add (csize, 1, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
ctx->filename = grub_zalloc (sz);
|
||||||
}
|
}
|
||||||
if (!ctx->filename)
|
if (!ctx->filename)
|
||||||
{
|
{
|
||||||
|
@ -621,7 +640,12 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
||||||
is the length. Both are part of the `Component
|
is the length. Both are part of the `Component
|
||||||
Record'. */
|
Record'. */
|
||||||
if (ctx->symlink && !ctx->was_continue)
|
if (ctx->symlink && !ctx->was_continue)
|
||||||
|
{
|
||||||
add_part (ctx, "/", 1);
|
add_part (ctx, "/", 1);
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
add_part (ctx, (char *) &entry->data[pos + 2],
|
add_part (ctx, (char *) &entry->data[pos + 2],
|
||||||
entry->data[pos + 1]);
|
entry->data[pos + 1]);
|
||||||
ctx->was_continue = (entry->data[pos] & 1);
|
ctx->was_continue = (entry->data[pos] & 1);
|
||||||
|
@ -640,6 +664,11 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
||||||
add_part (ctx, "/", 1);
|
add_part (ctx, "/", 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if grub_realloc() failed in add_part(). */
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
/* In pos + 1 the length of the `Component Record' is
|
/* In pos + 1 the length of the `Component Record' is
|
||||||
stored. */
|
stored. */
|
||||||
pos += entry->data[pos + 1] + 2;
|
pos += entry->data[pos + 1] + 2;
|
||||||
|
@ -776,14 +805,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (node->have_dirents >= node->alloc_dirents)
|
if (node->have_dirents >= node->alloc_dirents)
|
||||||
{
|
{
|
||||||
struct grub_fshelp_node *new_node;
|
struct grub_fshelp_node *new_node;
|
||||||
node->alloc_dirents *= 2;
|
grub_size_t sz;
|
||||||
new_node = grub_realloc (node,
|
|
||||||
sizeof (struct grub_fshelp_node)
|
if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
|
||||||
+ ((node->alloc_dirents
|
grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
|
||||||
- ARRAY_SIZE (node->dirents))
|
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
|
||||||
* sizeof (node->dirents[0])));
|
grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
|
||||||
|
goto fail_0;
|
||||||
|
|
||||||
|
new_node = grub_realloc (node, sz);
|
||||||
if (!new_node)
|
if (!new_node)
|
||||||
{
|
{
|
||||||
|
fail_0:
|
||||||
if (ctx.filename_alloc)
|
if (ctx.filename_alloc)
|
||||||
grub_free (ctx.filename);
|
grub_free (ctx.filename);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
|
@ -799,14 +832,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
* sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
|
* sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
|
||||||
{
|
{
|
||||||
struct grub_fshelp_node *new_node;
|
struct grub_fshelp_node *new_node;
|
||||||
new_node = grub_realloc (node,
|
grub_size_t sz;
|
||||||
sizeof (struct grub_fshelp_node)
|
|
||||||
+ ((node->alloc_dirents
|
if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
|
||||||
- ARRAY_SIZE (node->dirents))
|
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
|
||||||
* sizeof (node->dirents[0]))
|
grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
|
||||||
+ grub_strlen (ctx.symlink) + 1);
|
grub_add (sz, grub_strlen (ctx.symlink), &sz))
|
||||||
|
goto fail_1;
|
||||||
|
|
||||||
|
new_node = grub_realloc (node, sz);
|
||||||
if (!new_node)
|
if (!new_node)
|
||||||
{
|
{
|
||||||
|
fail_1:
|
||||||
if (ctx.filename_alloc)
|
if (ctx.filename_alloc)
|
||||||
grub_free (ctx.filename);
|
grub_free (ctx.filename);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
|
|
|
@ -556,8 +556,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
|
||||||
grub_uint16_t *tmp;
|
grub_uint16_t *tmp;
|
||||||
grub_size_t i;
|
grub_size_t i;
|
||||||
|
|
||||||
buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||||
tmp = grub_malloc (len * sizeof (tmp[0]));
|
tmp = grub_calloc (len, sizeof (tmp[0]));
|
||||||
if (!buf || !tmp)
|
if (!buf || !tmp)
|
||||||
{
|
{
|
||||||
grub_free (buf);
|
grub_free (buf);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -266,7 +267,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
node->next_extent = node->block;
|
node->next_extent = node->block;
|
||||||
node->cache_size = 0;
|
node->cache_size = 0;
|
||||||
|
|
||||||
node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size);
|
node->cache = grub_calloc (cache_size, sizeof (node->cache[0]));
|
||||||
if (!node->cache)
|
if (!node->cache)
|
||||||
{
|
{
|
||||||
grub_errno = 0;
|
grub_errno = 0;
|
||||||
|
@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
if (node->cache && node->cache_size >= node->cache_allocated)
|
if (node->cache && node->cache_size >= node->cache_allocated)
|
||||||
{
|
{
|
||||||
struct cache_entry *e = node->cache;
|
struct cache_entry *e = node->cache;
|
||||||
e = grub_realloc (node->cache,node->cache_allocated * 2
|
grub_size_t sz;
|
||||||
* sizeof (e[0]));
|
|
||||||
|
if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
e = grub_realloc (node->cache, sz);
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_errno = 0;
|
grub_errno = 0;
|
||||||
grub_free (node->cache);
|
grub_free (node->cache);
|
||||||
node->cache = 0;
|
node->cache = 0;
|
||||||
|
@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
|
||||||
grub_size_t len = grub_strlen (name);
|
grub_size_t len = grub_strlen (name);
|
||||||
grub_uint8_t *name_u8;
|
grub_uint8_t *name_u8;
|
||||||
int ret;
|
int ret;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return 1;
|
||||||
|
|
||||||
*node = grub_malloc (sizeof (**node));
|
*node = grub_malloc (sizeof (**node));
|
||||||
if (!*node)
|
if (!*node)
|
||||||
return 1;
|
return 1;
|
||||||
name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
name_u8 = grub_malloc (sz);
|
||||||
if (!name_u8)
|
if (!name_u8)
|
||||||
{
|
{
|
||||||
grub_free (*node);
|
grub_free (*node);
|
||||||
|
@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
|
||||||
data = grub_sfs_mount (disk);
|
data = grub_sfs_mount (disk);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
grub_size_t len = grub_strlen (data->label);
|
grub_size_t sz, len = grub_strlen (data->label);
|
||||||
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
|
||||||
|
if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
*label = grub_malloc (sz);
|
||||||
if (*label)
|
if (*label)
|
||||||
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
|
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
|
||||||
(const grub_uint8_t *) data->label,
|
(const grub_uint8_t *) data->label,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/deflate.h>
|
#include <grub/deflate.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
#include <minilzo.h>
|
#include <minilzo.h>
|
||||||
|
|
||||||
#include "xz.h"
|
#include "xz.h"
|
||||||
|
@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
char *ret;
|
char *ret;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = grub_malloc (sz);
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
err = read_chunk (node->data, ret,
|
err = read_chunk (node->data, ret,
|
||||||
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
||||||
|
@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
{
|
{
|
||||||
grub_fshelp_node_t node;
|
grub_fshelp_node_t node;
|
||||||
node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*node), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
node = grub_malloc (sz);
|
||||||
if (!node)
|
if (!node)
|
||||||
return 0;
|
return 0;
|
||||||
grub_memcpy (node, dir,
|
grub_memcpy (node, dir, sz);
|
||||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
|
||||||
if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
|
if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*node), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
node = grub_malloc (sz);
|
||||||
if (!node)
|
if (!node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_memcpy (node, dir,
|
grub_memcpy (node, dir, sz);
|
||||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
|
||||||
|
|
||||||
node->stsize--;
|
node->stsize--;
|
||||||
err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
|
err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
|
||||||
|
@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
|
enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
|
||||||
struct grub_squash_dirent di;
|
struct grub_squash_dirent di;
|
||||||
struct grub_squash_inode ino;
|
struct grub_squash_inode ino;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
err = read_chunk (dir->data, &di, sizeof (di),
|
err = read_chunk (dir->data, &di, sizeof (di),
|
||||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
|
@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
|
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
|
||||||
filetype = GRUB_FSHELP_SYMLINK;
|
filetype = GRUB_FSHELP_SYMLINK;
|
||||||
|
|
||||||
node = grub_malloc (sizeof (*node)
|
if (grub_add (dir->stsize, 1, &sz) ||
|
||||||
+ (dir->stsize + 1) * sizeof (dir->stack[0]));
|
grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*node), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
node = grub_malloc (sz);
|
||||||
if (! node)
|
if (! node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_memcpy (node, dir,
|
grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
|
||||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
|
||||||
|
|
||||||
node->ino = ino;
|
node->ino = ino;
|
||||||
node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
|
node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
|
||||||
|
@ -746,7 +769,7 @@ direct_read (struct grub_squash_data *data,
|
||||||
struct grub_squash_cache_inode *ino,
|
struct grub_squash_cache_inode *ino,
|
||||||
grub_off_t off, char *buf, grub_size_t len)
|
grub_off_t off, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err = GRUB_ERR_NONE;
|
||||||
grub_off_t cumulated_uncompressed_size = 0;
|
grub_off_t cumulated_uncompressed_size = 0;
|
||||||
grub_uint64_t a = 0;
|
grub_uint64_t a = 0;
|
||||||
grub_size_t i;
|
grub_size_t i;
|
||||||
|
|
|
@ -120,7 +120,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
||||||
if (data->linkname_alloc < linksize + 1)
|
if (data->linkname_alloc < linksize + 1)
|
||||||
{
|
{
|
||||||
char *n;
|
char *n;
|
||||||
n = grub_malloc (2 * (linksize + 1));
|
n = grub_calloc (2, linksize + 1);
|
||||||
if (!n)
|
if (!n)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
grub_free (data->linkname);
|
grub_free (data->linkname);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
#include <grub/datetime.h>
|
#include <grub/datetime.h>
|
||||||
#include <grub/udf.h>
|
#include <grub/udf.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -873,7 +874,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
utf16len = sz - 1;
|
utf16len = sz - 1;
|
||||||
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
|
utf16 = grub_calloc (utf16len, sizeof (utf16[0]));
|
||||||
if (!utf16)
|
if (!utf16)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < utf16len; i++)
|
for (i = 0; i < utf16len; i++)
|
||||||
|
@ -883,16 +884,26 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
utf16len = (sz - 1) / 2;
|
utf16len = (sz - 1) / 2;
|
||||||
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
|
utf16 = grub_calloc (utf16len, sizeof (utf16[0]));
|
||||||
if (!utf16)
|
if (!utf16)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; i < utf16len; i++)
|
for (i = 0; i < utf16len; i++)
|
||||||
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
||||||
}
|
}
|
||||||
if (!outbuf)
|
if (!outbuf)
|
||||||
outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
{
|
||||||
|
grub_size_t size;
|
||||||
|
|
||||||
|
if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) ||
|
||||||
|
grub_add (size, 1, &size))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
outbuf = grub_malloc (size);
|
||||||
|
}
|
||||||
if (outbuf)
|
if (outbuf)
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
|
*grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
|
||||||
|
|
||||||
|
fail:
|
||||||
grub_free (utf16);
|
grub_free (utf16);
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
@ -954,8 +965,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (grub_udf_read_icb (dir->data, &dirent.icb, child))
|
if (grub_udf_read_icb (dir->data, &dirent.icb, child))
|
||||||
|
{
|
||||||
|
grub_free (child);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
|
if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
|
||||||
{
|
{
|
||||||
/* This is the parent directory. */
|
/* This is the parent directory. */
|
||||||
|
@ -977,11 +990,18 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
||||||
dirent.file_ident_length,
|
dirent.file_ident_length,
|
||||||
(char *) raw))
|
(char *) raw))
|
||||||
!= dirent.file_ident_length)
|
!= dirent.file_ident_length)
|
||||||
|
{
|
||||||
|
grub_free (child);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
filename = read_string (raw, dirent.file_ident_length, 0);
|
filename = read_string (raw, dirent.file_ident_length, 0);
|
||||||
if (!filename)
|
if (!filename)
|
||||||
|
{
|
||||||
|
/* As the hook won't get called. */
|
||||||
|
grub_free (child);
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
|
}
|
||||||
|
|
||||||
if (filename && hook (filename, type, child, hook_data))
|
if (filename && hook (filename, type, child, hook_data))
|
||||||
{
|
{
|
||||||
|
@ -1005,7 +1025,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
grub_size_t sz = U64 (node->block.fe.file_size);
|
grub_size_t sz = U64 (node->block.fe.file_size);
|
||||||
grub_uint8_t *raw;
|
grub_uint8_t *raw;
|
||||||
const grub_uint8_t *ptr;
|
const grub_uint8_t *ptr;
|
||||||
char *out, *optr;
|
char *out = NULL, *optr;
|
||||||
|
|
||||||
if (sz < 4)
|
if (sz < 4)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1013,14 +1033,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
if (!raw)
|
if (!raw)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
|
if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
|
||||||
{
|
goto fail_1;
|
||||||
grub_free (raw);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
out = grub_malloc (sz * 2 + 1);
|
if (grub_mul (sz, 2, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
goto fail_0;
|
||||||
|
|
||||||
|
out = grub_malloc (sz);
|
||||||
if (!out)
|
if (!out)
|
||||||
{
|
{
|
||||||
|
fail_0:
|
||||||
grub_free (raw);
|
grub_free (raw);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1031,17 +1053,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
grub_size_t s;
|
grub_size_t s;
|
||||||
if ((grub_size_t) (ptr - raw + 4) > sz)
|
if ((grub_size_t) (ptr - raw + 4) > sz)
|
||||||
goto fail;
|
goto fail_1;
|
||||||
if (!(ptr[2] == 0 && ptr[3] == 0))
|
if (!(ptr[2] == 0 && ptr[3] == 0))
|
||||||
goto fail;
|
goto fail_1;
|
||||||
s = 4 + ptr[1];
|
s = 4 + ptr[1];
|
||||||
if ((grub_size_t) (ptr - raw + s) > sz)
|
if ((grub_size_t) (ptr - raw + s) > sz)
|
||||||
goto fail;
|
goto fail_1;
|
||||||
switch (*ptr)
|
switch (*ptr)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
if (ptr[1])
|
if (ptr[1])
|
||||||
goto fail;
|
goto fail_1;
|
||||||
/* Fallthrough. */
|
/* Fallthrough. */
|
||||||
case 2:
|
case 2:
|
||||||
/* in 4 bytes. out: 1 byte. */
|
/* in 4 bytes. out: 1 byte. */
|
||||||
|
@ -1066,11 +1088,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
if (optr != out)
|
if (optr != out)
|
||||||
*optr++ = '/';
|
*optr++ = '/';
|
||||||
if (!read_string (ptr + 4, s - 4, optr))
|
if (!read_string (ptr + 4, s - 4, optr))
|
||||||
goto fail;
|
goto fail_1;
|
||||||
optr += grub_strlen (optr);
|
optr += grub_strlen (optr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail_1;
|
||||||
}
|
}
|
||||||
ptr += s;
|
ptr += s;
|
||||||
}
|
}
|
||||||
|
@ -1078,7 +1100,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
grub_free (raw);
|
grub_free (raw);
|
||||||
return out;
|
return out;
|
||||||
|
|
||||||
fail:
|
fail_1:
|
||||||
grub_free (raw);
|
grub_free (raw);
|
||||||
grub_free (out);
|
grub_free (out);
|
||||||
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
|
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -899,6 +900,7 @@ static struct grub_xfs_data *
|
||||||
grub_xfs_mount (grub_disk_t disk)
|
grub_xfs_mount (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
struct grub_xfs_data *data = 0;
|
struct grub_xfs_data *data = 0;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
data = grub_zalloc (sizeof (struct grub_xfs_data));
|
data = grub_zalloc (sizeof (struct grub_xfs_data));
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk)
|
||||||
if (!grub_xfs_sb_valid(data))
|
if (!grub_xfs_sb_valid(data))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data = grub_realloc (data,
|
if (grub_add (grub_xfs_inode_size (data),
|
||||||
sizeof (struct grub_xfs_data)
|
sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
|
||||||
- sizeof (struct grub_xfs_inode)
|
goto fail;
|
||||||
+ grub_xfs_inode_size(data) + 1);
|
|
||||||
|
data = grub_realloc (data, sz);
|
||||||
|
|
||||||
if (! data)
|
if (! data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include <grub/deflate.h>
|
#include <grub/deflate.h>
|
||||||
#include <grub/crypto.h>
|
#include <grub/crypto.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -141,7 +142,10 @@ ZAP_LEAF_NUMCHUNKS (int bs)
|
||||||
static inline zap_leaf_chunk_t *
|
static inline zap_leaf_chunk_t *
|
||||||
ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx)
|
ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx)
|
||||||
{
|
{
|
||||||
return &((zap_leaf_chunk_t *) (l->l_entries
|
grub_properly_aligned_t *l_entries;
|
||||||
|
|
||||||
|
l_entries = (grub_properly_aligned_t *) ALIGN_UP((grub_addr_t)l->l_hash, sizeof (grub_properly_aligned_t));
|
||||||
|
return &((zap_leaf_chunk_t *) (l_entries
|
||||||
+ (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2)
|
+ (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2)
|
||||||
/ sizeof (grub_properly_aligned_t)))[idx];
|
/ sizeof (grub_properly_aligned_t)))[idx];
|
||||||
}
|
}
|
||||||
|
@ -773,11 +777,14 @@ fill_vdev_info (struct grub_zfs_data *data,
|
||||||
if (data->n_devices_attached > data->n_devices_allocated)
|
if (data->n_devices_attached > data->n_devices_allocated)
|
||||||
{
|
{
|
||||||
void *tmp;
|
void *tmp;
|
||||||
data->n_devices_allocated = 2 * data->n_devices_attached + 1;
|
grub_size_t sz;
|
||||||
data->devices_attached
|
|
||||||
= grub_realloc (tmp = data->devices_attached,
|
if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
|
||||||
data->n_devices_allocated
|
grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
|
||||||
* sizeof (data->devices_attached[0]));
|
grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
|
||||||
if (!data->devices_attached)
|
if (!data->devices_attached)
|
||||||
{
|
{
|
||||||
data->devices_attached = tmp;
|
data->devices_attached = tmp;
|
||||||
|
@ -3325,7 +3332,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
|
||||||
}
|
}
|
||||||
subvol->nkeys = 0;
|
subvol->nkeys = 0;
|
||||||
zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data);
|
zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data);
|
||||||
subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0]));
|
subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0]));
|
||||||
if (!subvol->keyring)
|
if (!subvol->keyring)
|
||||||
{
|
{
|
||||||
grub_free (fsname);
|
grub_free (fsname);
|
||||||
|
@ -3468,14 +3475,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
|
||||||
{
|
{
|
||||||
char *nvpair;
|
char *nvpair;
|
||||||
char *ret;
|
char *ret;
|
||||||
grub_size_t size;
|
grub_size_t size, sz;
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
||||||
&size, 0);
|
&size, 0);
|
||||||
if (!found)
|
if (!found)
|
||||||
return 0;
|
return 0;
|
||||||
ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
|
|
||||||
|
if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = grub_zalloc (sz);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
||||||
|
@ -4336,7 +4347,7 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
*nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
|
*nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
|
||||||
if (*nsectors > max_nsectors)
|
if (*nsectors > max_nsectors)
|
||||||
*nsectors = max_nsectors;
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_calloc (*nsectors, sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
for (i = 0; i < *nsectors; i++)
|
for (i = 0; i < *nsectors; i++)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/zfs/zfs.h>
|
#include <grub/zfs/zfs.h>
|
||||||
|
@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in,
|
||||||
int passphrase)
|
int passphrase)
|
||||||
{
|
{
|
||||||
struct grub_zfs_wrap_key *key;
|
struct grub_zfs_wrap_key *key;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (!passphrase && keylen > 32)
|
if (!passphrase && keylen > 32)
|
||||||
keylen = 32;
|
keylen = 32;
|
||||||
key = grub_malloc (sizeof (*key) + keylen);
|
if (grub_add (sizeof (*key), keylen, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
key = grub_malloc (sz);
|
||||||
if (!key)
|
if (!key)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
key->is_passphrase = passphrase;
|
key->is_passphrase = passphrase;
|
||||||
|
|
|
@ -230,7 +230,7 @@ circprog_set_state (void *vself, int visible, int start,
|
||||||
static int
|
static int
|
||||||
parse_angle (const char *value)
|
parse_angle (const char *value)
|
||||||
{
|
{
|
||||||
char *ptr;
|
const char *ptr;
|
||||||
int angle;
|
int angle;
|
||||||
|
|
||||||
angle = grub_strtol (value, &ptr, 10);
|
angle = grub_strtol (value, &ptr, 10);
|
||||||
|
|
|
@ -195,7 +195,10 @@ load_image (grub_gui_image_t self, const char *path)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
if (self->bitmap && (self->bitmap != self->raw_bitmap))
|
if (self->bitmap && (self->bitmap != self->raw_bitmap))
|
||||||
|
{
|
||||||
grub_video_bitmap_destroy (self->bitmap);
|
grub_video_bitmap_destroy (self->bitmap);
|
||||||
|
self->bitmap = 0;
|
||||||
|
}
|
||||||
if (self->raw_bitmap)
|
if (self->raw_bitmap)
|
||||||
grub_video_bitmap_destroy (self->raw_bitmap);
|
grub_video_bitmap_destroy (self->raw_bitmap);
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ canonicalize_path (const char *path)
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
components++;
|
components++;
|
||||||
|
|
||||||
char **path_array = grub_malloc (components * sizeof (*path_array));
|
char **path_array = grub_calloc (components, sizeof (*path_array));
|
||||||
if (! path_array)
|
if (! path_array)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -484,7 +484,7 @@ parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *pr
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
num = grub_strtoul (ptr, (char **) &ptr, 0);
|
num = grub_strtoul (ptr, &ptr, 0);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
if (sig)
|
if (sig)
|
||||||
|
|
|
@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix,
|
||||||
box->content_height = 0;
|
box->content_height = 0;
|
||||||
box->raw_pixmaps =
|
box->raw_pixmaps =
|
||||||
(struct grub_video_bitmap **)
|
(struct grub_video_bitmap **)
|
||||||
grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
|
grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *));
|
||||||
box->scaled_pixmaps =
|
box->scaled_pixmaps =
|
||||||
(struct grub_video_bitmap **)
|
(struct grub_video_bitmap **)
|
||||||
grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
|
grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *));
|
||||||
|
|
||||||
/* Initialize all pixmap pointers to NULL so that proper destruction can
|
/* Initialize all pixmap pointers to NULL so that proper destruction can
|
||||||
be performed if an error is encountered partway through construction. */
|
be performed if an error is encountered partway through construction. */
|
||||||
|
|
|
@ -554,7 +554,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
|
||||||
z = 1 << j; /* table entries for j-bit table */
|
z = 1 << j; /* table entries for j-bit table */
|
||||||
|
|
||||||
/* allocate and link in new table */
|
/* allocate and link in new table */
|
||||||
q = (struct huft *) grub_zalloc ((z + 1) * sizeof (struct huft));
|
q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft));
|
||||||
if (! q)
|
if (! q)
|
||||||
{
|
{
|
||||||
if (h)
|
if (h)
|
||||||
|
|
|
@ -93,13 +93,16 @@ probe_caches (void)
|
||||||
grub_arch_cache_ilinesz = 8 << (cache_type & 3);
|
grub_arch_cache_ilinesz = 8 << (cache_type & 3);
|
||||||
type = ARCH_ARMV6;
|
type = ARCH_ARMV6;
|
||||||
break;
|
break;
|
||||||
case 0x80 ... 0x8f:
|
default:
|
||||||
|
/*
|
||||||
|
* The CTR register is pretty much unchanged from v7 onwards,
|
||||||
|
* and is guaranteed to be backward compatible (the IDC/DIC bits
|
||||||
|
* allow certain CMOs to be elided, but performing them is never
|
||||||
|
* wrong), hence handling it like its AArch64 equivalent.
|
||||||
|
*/
|
||||||
grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf);
|
grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf);
|
||||||
grub_arch_cache_ilinesz = 4 << (cache_type & 0xf);
|
grub_arch_cache_ilinesz = 4 << (cache_type & 0xf);
|
||||||
type = ARCH_ARMV7;
|
type = ARCH_ARMV7;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
grub_fatal ("Unsupported cache type 0x%x", cache_type);
|
|
||||||
}
|
}
|
||||||
if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz)
|
if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz)
|
||||||
grub_arch_cache_max_linesz = grub_arch_cache_dlinesz;
|
grub_arch_cache_max_linesz = grub_arch_cache_dlinesz;
|
||||||
|
|
|
@ -71,4 +71,7 @@ grub_machine_fini (int flags)
|
||||||
efi_call_1 (b->close_event, tmr_evt);
|
efi_call_1 (b->close_event, tmr_evt);
|
||||||
|
|
||||||
grub_efi_fini ();
|
grub_efi_fini ();
|
||||||
|
|
||||||
|
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||||
|
grub_efi_memory_fini ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,4 +57,7 @@ grub_machine_fini (int flags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
grub_efi_fini ();
|
grub_efi_fini ();
|
||||||
|
|
||||||
|
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||||
|
grub_efi_memory_fini ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
|
||||||
void
|
void
|
||||||
grub_reboot (void)
|
grub_reboot (void)
|
||||||
{
|
{
|
||||||
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
|
||||||
|
GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
|
||||||
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||||
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
|
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
|
||||||
for (;;) ;
|
for (;;) ;
|
||||||
|
@ -202,7 +203,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||||
|
|
||||||
len = grub_strlen (var);
|
len = grub_strlen (var);
|
||||||
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
||||||
var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
|
var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
|
||||||
if (!var16)
|
if (!var16)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
||||||
|
@ -237,7 +238,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||||
|
|
||||||
len = grub_strlen (var);
|
len = grub_strlen (var);
|
||||||
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
||||||
var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
|
var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
|
||||||
if (!var16)
|
if (!var16)
|
||||||
return NULL;
|
return NULL;
|
||||||
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
||||||
|
@ -308,13 +309,23 @@ grub_efi_modules_addr (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == coff_header->num_sections)
|
if (i == coff_header->num_sections)
|
||||||
|
{
|
||||||
|
grub_dprintf("sections", "section %d is last section; invalid.\n", i);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
info = (struct grub_module_info *) ((char *) image->image_base
|
info = (struct grub_module_info *) ((char *) image->image_base
|
||||||
+ section->virtual_address);
|
+ section->virtual_address);
|
||||||
if (info->magic != GRUB_MODULE_MAGIC)
|
if (section->name[0] != '.' && info->magic != GRUB_MODULE_MAGIC)
|
||||||
|
{
|
||||||
|
grub_dprintf("sections",
|
||||||
|
"section %d has bad magic %08x, should be %08x\n",
|
||||||
|
i, info->magic, GRUB_MODULE_MAGIC);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_dprintf("sections", "returning section info for section %d: \"%s\"\n",
|
||||||
|
i, section->name);
|
||||||
return (grub_addr_t) info;
|
return (grub_addr_t) info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +343,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||||
|
|
||||||
dp = dp0;
|
dp = dp0;
|
||||||
|
|
||||||
while (1)
|
while (dp)
|
||||||
{
|
{
|
||||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||||
|
@ -342,9 +353,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||||
if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
||||||
&& subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
&& subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||||
{
|
{
|
||||||
grub_efi_uint16_t len;
|
grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
|
||||||
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
|
||||||
/ sizeof (grub_efi_char16_t));
|
if (len < 4)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
"malformed EFI Device Path node has length=%d", len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len = (len - 4) / sizeof (grub_efi_char16_t);
|
||||||
filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
|
filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +377,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while (1)
|
while (dp)
|
||||||
{
|
{
|
||||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||||
|
@ -376,14 +393,21 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
||||||
|
|
||||||
*p++ = '/';
|
*p++ = '/';
|
||||||
|
|
||||||
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
|
||||||
/ sizeof (grub_efi_char16_t));
|
if (len < 4)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
"malformed EFI Device Path node has length=%d", len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = (len - 4) / sizeof (grub_efi_char16_t);
|
||||||
fp = (grub_efi_file_path_device_path_t *) dp;
|
fp = (grub_efi_file_path_device_path_t *) dp;
|
||||||
/* According to EFI spec Path Name is NULL terminated */
|
/* According to EFI spec Path Name is NULL terminated */
|
||||||
while (len > 0 && fp->path_name[len - 1] == 0)
|
while (len > 0 && fp->path_name[len - 1] == 0)
|
||||||
len--;
|
len--;
|
||||||
|
|
||||||
dup_name = grub_malloc (len * sizeof (*dup_name));
|
dup_name = grub_calloc (len, sizeof (*dup_name));
|
||||||
if (!dup_name)
|
if (!dup_name)
|
||||||
{
|
{
|
||||||
grub_free (name);
|
grub_free (name);
|
||||||
|
@ -452,7 +476,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
|
||||||
;
|
;
|
||||||
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
||||||
{
|
{
|
||||||
total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In the event that we find a node that's completely garbage, for
|
||||||
|
* example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size
|
||||||
|
* of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and
|
||||||
|
* GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue,
|
||||||
|
* and neither should our consumers, but there won't be any error raised
|
||||||
|
* even though the device path is junk.
|
||||||
|
*
|
||||||
|
* This keeps us from passing junk down back to our caller.
|
||||||
|
*/
|
||||||
|
if (len < 4)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
"malformed EFI Device Path node has length=%d", len);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_size += len;
|
||||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -497,7 +540,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
||||||
void
|
void
|
||||||
grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||||
{
|
{
|
||||||
while (1)
|
while (GRUB_EFI_DEVICE_PATH_VALID (dp))
|
||||||
{
|
{
|
||||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||||
|
@ -909,7 +952,10 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
|
||||||
/* Return non-zero. */
|
/* Return non-zero. */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
while (1)
|
if (dp1 == dp2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (GRUB_EFI_DEVICE_PATH_VALID (dp1) && GRUB_EFI_DEVICE_PATH_VALID (dp2))
|
||||||
{
|
{
|
||||||
grub_efi_uint8_t type1, type2;
|
grub_efi_uint8_t type1, type2;
|
||||||
grub_efi_uint8_t subtype1, subtype2;
|
grub_efi_uint8_t subtype1, subtype2;
|
||||||
|
@ -945,5 +991,14 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
|
||||||
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
|
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There's no "right" answer here, but we probably don't want to call a valid
|
||||||
|
* dp and an invalid dp equal, so pick one way or the other.
|
||||||
|
*/
|
||||||
|
if (GRUB_EFI_DEVICE_PATH_VALID (dp1) && !GRUB_EFI_DEVICE_PATH_VALID (dp2))
|
||||||
|
return 1;
|
||||||
|
else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) && GRUB_EFI_DEVICE_PATH_VALID (dp2))
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,5 +80,4 @@ grub_efi_fini (void)
|
||||||
{
|
{
|
||||||
grub_efidisk_fini ();
|
grub_efidisk_fini ();
|
||||||
grub_console_fini ();
|
grub_console_fini ();
|
||||||
grub_efi_memory_fini ();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,12 +125,20 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
|
||||||
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||||
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
return 0;
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
N_("invalid memory address (0x%llx > 0x%llx)"),
|
||||||
|
address, GRUB_EFI_MAX_USABLE_ADDRESS);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
b = grub_efi_system_table->boot_services;
|
b = grub_efi_system_table->boot_services;
|
||||||
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
return 0;
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (address == 0)
|
if (address == 0)
|
||||||
{
|
{
|
||||||
|
@ -140,7 +148,10 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
grub_efi_free_pages (0, pages);
|
grub_efi_free_pages (0, pages);
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
return 0;
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_efi_store_alloc (address, pages);
|
grub_efi_store_alloc (address, pages);
|
||||||
|
|
|
@ -615,7 +615,7 @@ static char *
|
||||||
grub_util_path_concat_real (size_t n, int ext, va_list ap)
|
grub_util_path_concat_real (size_t n, int ext, va_list ap)
|
||||||
{
|
{
|
||||||
size_t totlen = 0;
|
size_t totlen = 0;
|
||||||
char **l = xmalloc ((n + ext) * sizeof (l[0]));
|
char **l = xcalloc (n + ext, sizeof (l[0]));
|
||||||
char *r, *p, *pi;
|
char *r, *p, *pi;
|
||||||
size_t i;
|
size_t i;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
|
|
|
@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xcalloc (grub_size_t nmemb, grub_size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = calloc (nmemb, size);
|
||||||
|
if (!p)
|
||||||
|
grub_util_error ("%s", _("out of memory"));
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
xmalloc (grub_size_t size)
|
xmalloc (grub_size_t size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,16 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
void *
|
||||||
|
grub_calloc (grub_size_t nmemb, grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
ret = calloc (nmemb, size);
|
||||||
|
if (!ret)
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
grub_malloc (grub_size_t size)
|
grub_malloc (grub_size_t size)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +60,7 @@ grub_zalloc (grub_size_t size)
|
||||||
void
|
void
|
||||||
grub_free (void *ptr)
|
grub_free (void *ptr)
|
||||||
{
|
{
|
||||||
|
if (ptr)
|
||||||
free (ptr);
|
free (ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ struct grub_fs_block
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_fs_blocklist_open (grub_file_t file, const char *name)
|
grub_fs_blocklist_open (grub_file_t file, const char *name)
|
||||||
{
|
{
|
||||||
char *p = (char *) name;
|
const char *p = name;
|
||||||
unsigned num = 0;
|
unsigned num = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
grub_disk_t disk = file->device->disk;
|
grub_disk_t disk = file->device->disk;
|
||||||
|
@ -151,7 +151,7 @@ grub_fs_blocklist_open (grub_file_t file, const char *name)
|
||||||
while (p);
|
while (p);
|
||||||
|
|
||||||
/* Allocate a block list. */
|
/* Allocate a block list. */
|
||||||
blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1));
|
blocks = grub_calloc (num + 1, sizeof (struct grub_fs_block));
|
||||||
if (! blocks)
|
if (! blocks)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <grub/efi/efi.h>
|
#include <grub/efi/efi.h>
|
||||||
#include <grub/i386/tsc.h>
|
#include <grub/i386/tsc.h>
|
||||||
#include <grub/loader.h>
|
#include <grub/loader.h>
|
||||||
#include <grub/tpm.h>
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_machine_init (void)
|
grub_machine_init (void)
|
||||||
|
@ -39,6 +38,11 @@ grub_machine_init (void)
|
||||||
void
|
void
|
||||||
grub_machine_fini (int flags)
|
grub_machine_fini (int flags)
|
||||||
{
|
{
|
||||||
if (flags & GRUB_LOADER_FLAG_NORETURN)
|
if (!(flags & GRUB_LOADER_FLAG_NORETURN))
|
||||||
|
return;
|
||||||
|
|
||||||
grub_efi_fini ();
|
grub_efi_fini ();
|
||||||
|
|
||||||
|
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||||
|
grub_efi_memory_fini ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,11 @@ grub_machine_init (void)
|
||||||
void
|
void
|
||||||
grub_machine_fini (int flags)
|
grub_machine_fini (int flags)
|
||||||
{
|
{
|
||||||
if (flags & GRUB_LOADER_FLAG_NORETURN)
|
if (!(flags & GRUB_LOADER_FLAG_NORETURN))
|
||||||
|
return;
|
||||||
|
|
||||||
grub_efi_fini ();
|
grub_efi_fini ();
|
||||||
|
|
||||||
|
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||||
|
grub_efi_memory_fini ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
FUNCTION (grub_arch_sync_caches)
|
FUNCTION (grub_arch_sync_caches)
|
||||||
#include "cache_flush.S"
|
#include "cache_flush.S"
|
||||||
j $ra
|
j $ra
|
||||||
|
nop
|
||||||
|
|
||||||
FUNCTION (grub_arch_sync_dma_caches)
|
FUNCTION (grub_arch_sync_dma_caches)
|
||||||
move $t2, $a0
|
move $t2, $a0
|
||||||
|
@ -66,3 +67,4 @@ FUNCTION (grub_arch_sync_dma_caches)
|
||||||
sync_op
|
sync_op
|
||||||
|
|
||||||
jr $ra
|
jr $ra
|
||||||
|
nop
|
||||||
|
|
|
@ -158,17 +158,28 @@ int grub_err_printf (const char *fmt, ...)
|
||||||
__attribute__ ((alias("grub_printf")));
|
__attribute__ ((alias("grub_printf")));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_debug_enabled (const char * condition)
|
||||||
|
{
|
||||||
|
const char *debug;
|
||||||
|
|
||||||
|
debug = grub_env_get ("debug");
|
||||||
|
if (!debug)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (grub_strword (debug, "all") || grub_strword (debug, condition))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_real_dprintf (const char *file, const int line, const char *condition,
|
grub_real_dprintf (const char *file, const int line, const char *condition,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
const char *debug = grub_env_get ("debug");
|
|
||||||
|
|
||||||
if (! debug)
|
if (grub_debug_enabled (condition))
|
||||||
return;
|
|
||||||
|
|
||||||
if (grub_strword (debug, "all") || grub_strword (debug, condition))
|
|
||||||
{
|
{
|
||||||
grub_printf ("%s:%d: ", file, line);
|
grub_printf ("%s:%d: ", file, line);
|
||||||
va_start (args, fmt);
|
va_start (args, fmt);
|
||||||
|
@ -340,7 +351,8 @@ grub_isspace (int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
grub_strtoul (const char *str, char **end, int base)
|
grub_strtoul (const char * restrict str, const char ** const restrict end,
|
||||||
|
int base)
|
||||||
{
|
{
|
||||||
unsigned long long num;
|
unsigned long long num;
|
||||||
|
|
||||||
|
@ -357,7 +369,8 @@ grub_strtoul (const char *str, char **end, int base)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long
|
unsigned long long
|
||||||
grub_strtoull (const char *str, char **end, int base)
|
grub_strtoull (const char * restrict str, const char ** const restrict end,
|
||||||
|
int base)
|
||||||
{
|
{
|
||||||
unsigned long long num = 0;
|
unsigned long long num = 0;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
@ -588,7 +601,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
|
||||||
static inline char *
|
static inline char *
|
||||||
grub_lltoa (char *str, int c, unsigned long long n)
|
grub_lltoa (char *str, int c, unsigned long long n)
|
||||||
{
|
{
|
||||||
unsigned base = (c == 'x') ? 16 : 10;
|
unsigned base = ((c == 'x') || (c == 'X')) ? 16 : 10;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if ((long long) n < 0 && c == 'd')
|
if ((long long) n < 0 && c == 'd')
|
||||||
|
@ -603,7 +616,7 @@ grub_lltoa (char *str, int c, unsigned long long n)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned d = (unsigned) (n & 0xf);
|
unsigned d = (unsigned) (n & 0xf);
|
||||||
*p++ = (d > 9) ? d + 'a' - 10 : d + '0';
|
*p++ = (d > 9) ? d + ((c == 'x') ? 'a' : 'A') - 10 : d + '0';
|
||||||
}
|
}
|
||||||
while (n >>= 4);
|
while (n >>= 4);
|
||||||
else
|
else
|
||||||
|
@ -676,6 +689,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
|
||||||
{
|
{
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'x':
|
case 'x':
|
||||||
|
case 'X':
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'c':
|
case 'c':
|
||||||
|
@ -690,7 +704,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
|
||||||
args->ptr = args->prealloc;
|
args->ptr = args->prealloc;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
args->ptr = grub_malloc (args->count * sizeof (args->ptr[0]));
|
args->ptr = grub_calloc (args->count, sizeof (args->ptr[0]));
|
||||||
if (!args->ptr)
|
if (!args->ptr)
|
||||||
{
|
{
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
@ -762,6 +776,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'x':
|
case 'x':
|
||||||
|
case 'X':
|
||||||
case 'u':
|
case 'u':
|
||||||
args->ptr[curn].type = UNSIGNED_INT + longfmt;
|
args->ptr[curn].type = UNSIGNED_INT + longfmt;
|
||||||
break;
|
break;
|
||||||
|
@ -853,14 +868,14 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
|
||||||
{
|
{
|
||||||
if (fmt[0] == '0')
|
if (fmt[0] == '0')
|
||||||
zerofill = '0';
|
zerofill = '0';
|
||||||
format1 = grub_strtoul (fmt, (char **) &fmt, 10);
|
format1 = grub_strtoul (fmt, &fmt, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*fmt == '.')
|
if (*fmt == '.')
|
||||||
fmt++;
|
fmt++;
|
||||||
|
|
||||||
if (grub_isdigit (*fmt))
|
if (grub_isdigit (*fmt))
|
||||||
format2 = grub_strtoul (fmt, (char **) &fmt, 10);
|
format2 = grub_strtoul (fmt, &fmt, 10);
|
||||||
|
|
||||||
if (*fmt == '$')
|
if (*fmt == '$')
|
||||||
{
|
{
|
||||||
|
@ -900,6 +915,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
|
||||||
c = 'x';
|
c = 'x';
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case 'x':
|
case 'x':
|
||||||
|
case 'X':
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,8 +67,10 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/mm_private.h>
|
#include <grub/mm_private.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
|
# undef grub_calloc
|
||||||
# undef grub_malloc
|
# undef grub_malloc
|
||||||
# undef grub_zalloc
|
# undef grub_zalloc
|
||||||
# undef grub_realloc
|
# undef grub_realloc
|
||||||
|
@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_size_t size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
|
||||||
|
* integer overflow.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
grub_calloc (grub_size_t nmemb, grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
grub_size_t sz = 0;
|
||||||
|
|
||||||
|
if (grub_mul (nmemb, size, &sz))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = grub_memalign (0, sz);
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
grub_memset (ret, 0, sz);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate SIZE bytes and return the pointer. */
|
/* Allocate SIZE bytes and return the pointer. */
|
||||||
void *
|
void *
|
||||||
grub_malloc (grub_size_t size)
|
grub_malloc (grub_size_t size)
|
||||||
|
@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno)
|
||||||
grub_printf ("\n");
|
grub_printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (grub_mm_debug)
|
||||||
|
grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ",
|
||||||
|
file, line, size);
|
||||||
|
ptr = grub_calloc (nmemb, size);
|
||||||
|
if (grub_mm_debug)
|
||||||
|
grub_printf ("%p\n", ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
grub_debug_malloc (const char *file, int line, grub_size_t size)
|
grub_debug_malloc (const char *file, int line, grub_size_t size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,7 +213,7 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
grub_memcpy (args, buffer, bp - buffer);
|
grub_memcpy (args, buffer, bp - buffer);
|
||||||
|
|
||||||
*argv = grub_malloc (sizeof (char *) * (*argc + 1));
|
*argv = grub_calloc (*argc + 1, sizeof (char *));
|
||||||
if (!*argv)
|
if (!*argv)
|
||||||
{
|
{
|
||||||
grub_free (args);
|
grub_free (args);
|
||||||
|
|
|
@ -126,7 +126,7 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
|
||||||
while (*ptr && grub_isalpha (*ptr))
|
while (*ptr && grub_isalpha (*ptr))
|
||||||
ptr++;
|
ptr++;
|
||||||
partname_end = ptr;
|
partname_end = ptr;
|
||||||
num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;
|
num = grub_strtoul (ptr, &ptr, 0) - 1;
|
||||||
|
|
||||||
curpart = 0;
|
curpart = 0;
|
||||||
/* Use the first partition map type found. */
|
/* Use the first partition map type found. */
|
||||||
|
|
|
@ -73,4 +73,7 @@ grub_machine_fini (int flags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
grub_efi_fini ();
|
grub_efi_fini ();
|
||||||
|
|
||||||
|
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||||
|
grub_efi_memory_fini ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,45 @@ grub_getkey (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_getkeystatus (void)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
grub_term_input_t term;
|
||||||
|
|
||||||
|
if (grub_term_poll_usb)
|
||||||
|
grub_term_poll_usb (0);
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_INPUTS(term)
|
||||||
|
{
|
||||||
|
if (term->getkeystatus)
|
||||||
|
status |= term->getkeystatus (term);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
grub_key_is_interrupt (int key)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ESC sometimes is the BIOS setup hotkey and may be hard to discover, also
|
||||||
|
* check F4, which was chosen because is not used as a hotkey to enter the
|
||||||
|
* BIOS setup by any vendor.
|
||||||
|
*/
|
||||||
|
if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F4)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pressing keys at the right time during boot is hard to time, also allow
|
||||||
|
* interrupting sleeps / the menu countdown by keeping shift pressed.
|
||||||
|
*/
|
||||||
|
if (grub_getkeystatus() & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_refresh (void)
|
grub_refresh (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -133,7 +133,7 @@ grub_uboot_dev_enum (void)
|
||||||
return num_devices;
|
return num_devices;
|
||||||
|
|
||||||
max_devices = 2;
|
max_devices = 2;
|
||||||
enum_devices = grub_malloc (sizeof(struct device_info) * max_devices);
|
enum_devices = grub_calloc (max_devices, sizeof(struct device_info));
|
||||||
if (!enum_devices)
|
if (!enum_devices)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 posSlot;
|
UInt32 posSlot, lenToPosState;
|
||||||
RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
|
RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
|
||||||
p->state = kMatchNextStates[p->state];
|
p->state = kMatchNextStates[p->state];
|
||||||
LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
|
LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
|
||||||
pos -= LZMA_NUM_REPS;
|
pos -= LZMA_NUM_REPS;
|
||||||
GetPosSlot(pos, posSlot);
|
GetPosSlot(pos, posSlot);
|
||||||
RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
|
lenToPosState = GetLenToPosState(len);
|
||||||
|
if (lenToPosState >= kNumLenToPosStates)
|
||||||
|
{
|
||||||
|
p->result = SZ_ERROR_DATA;
|
||||||
|
return CheckErrors(p);
|
||||||
|
}
|
||||||
|
RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot);
|
||||||
|
|
||||||
if (posSlot >= kStartPosModelIndex)
|
if (posSlot >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
/* Built-in parser for default options. */
|
/* Built-in parser for default options. */
|
||||||
static const struct grub_arg_option help_options[] =
|
static const struct grub_arg_option help_options[] =
|
||||||
|
@ -216,7 +217,13 @@ static inline grub_err_t
|
||||||
add_arg (char ***argl, int *num, char *s)
|
add_arg (char ***argl, int *num, char *s)
|
||||||
{
|
{
|
||||||
char **p = *argl;
|
char **p = *argl;
|
||||||
*argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *));
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (++(*num), 1, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
|
||||||
|
*argl = grub_realloc (*argl, sz);
|
||||||
if (! *argl)
|
if (! *argl)
|
||||||
{
|
{
|
||||||
grub_free (p);
|
grub_free (p);
|
||||||
|
@ -375,7 +382,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
|
||||||
|
|
||||||
case ARG_TYPE_INT:
|
case ARG_TYPE_INT:
|
||||||
{
|
{
|
||||||
char *tail;
|
const char * tail;
|
||||||
|
|
||||||
grub_strtoull (option, &tail, 0);
|
grub_strtoull (option, &tail, 0);
|
||||||
if (tail == 0 || tail == option || *tail != '\0' || grub_errno)
|
if (tail == 0 || tail == option || *tail != '\0' || grub_errno)
|
||||||
|
@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
|
||||||
grub_size_t argcnt;
|
grub_size_t argcnt;
|
||||||
struct grub_arg_list *list;
|
struct grub_arg_list *list;
|
||||||
const struct grub_arg_option *options;
|
const struct grub_arg_option *options;
|
||||||
|
grub_size_t sz0, sz1;
|
||||||
|
|
||||||
options = extcmd->options;
|
options = extcmd->options;
|
||||||
if (! options)
|
if (! options)
|
||||||
|
@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
|
||||||
argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */
|
argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */
|
||||||
}
|
}
|
||||||
|
|
||||||
list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt);
|
if (grub_mul (sizeof (*list), i, &sz0) ||
|
||||||
|
grub_mul (sizeof (char *), argcnt, &sz1) ||
|
||||||
|
grub_add (sz0, sz1, &sz0))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = grub_zalloc (sz0);
|
||||||
if (! list)
|
if (! list)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue