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 |
281 changed files with 9943 additions and 8025 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
po/exclude.pot binary
|
469
.gitignore
vendored
469
.gitignore
vendored
|
@ -1,238 +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
|
|
||||||
gpt_unit_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;
|
||||||
|
@ -1175,18 +1194,6 @@ script = {
|
||||||
common = tests/grub_cmd_tr.in;
|
common = tests/grub_cmd_tr.in;
|
||||||
};
|
};
|
||||||
|
|
||||||
script = {
|
|
||||||
testcase;
|
|
||||||
name = gptrepair_test;
|
|
||||||
common = tests/gptrepair_test.in;
|
|
||||||
};
|
|
||||||
|
|
||||||
script = {
|
|
||||||
testcase;
|
|
||||||
name = gptprio_test;
|
|
||||||
common = tests/gptprio_test.in;
|
|
||||||
};
|
|
||||||
|
|
||||||
script = {
|
script = {
|
||||||
testcase;
|
testcase;
|
||||||
name = file_filter_test;
|
name = file_filter_test;
|
||||||
|
@ -1282,25 +1289,6 @@ program = {
|
||||||
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||||
};
|
};
|
||||||
|
|
||||||
program = {
|
|
||||||
testcase;
|
|
||||||
name = gpt_unit_test;
|
|
||||||
common = tests/gpt_unit_test.c;
|
|
||||||
common = tests/lib/unit_test.c;
|
|
||||||
common = grub-core/commands/search_part_label.c;
|
|
||||||
common = grub-core/commands/search_part_uuid.c;
|
|
||||||
common = grub-core/commands/search_disk_uuid.c;
|
|
||||||
common = grub-core/disk/host.c;
|
|
||||||
common = grub-core/kern/emu/hostfs.c;
|
|
||||||
common = grub-core/lib/gpt.c;
|
|
||||||
common = grub-core/tests/lib/test.c;
|
|
||||||
ldadd = libgrubmods.a;
|
|
||||||
ldadd = libgrubgcry.a;
|
|
||||||
ldadd = libgrubkern.a;
|
|
||||||
ldadd = grub-core/gnulib/libgnu.a;
|
|
||||||
ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
|
||||||
};
|
|
||||||
|
|
||||||
program = {
|
program = {
|
||||||
name = grub-menulst2cfg;
|
name = grub-menulst2cfg;
|
||||||
mansection = 1;
|
mansection = 1;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
252
docs/grub.texi
252
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
|
||||||
|
@ -3950,7 +4024,6 @@ you forget a command, you can run the command @command{help}
|
||||||
* 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
|
||||||
|
@ -4202,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
|
||||||
|
|
||||||
|
|
||||||
|
@ -4221,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
|
||||||
|
@ -4424,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
|
||||||
|
@ -4647,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.
|
||||||
|
|
||||||
|
@ -4772,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
|
||||||
|
|
||||||
|
|
||||||
|
@ -5078,9 +5143,10 @@ 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
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -5122,21 +5188,27 @@ return. Only one of these options may be specified at a time.
|
||||||
@item
|
@item
|
||||||
When given @option{--get-byte}, return the value of the byte
|
When given @option{--get-byte}, return the value of the byte
|
||||||
at @var{offset} bytes into the selected SMBIOS structure.
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
@item
|
@item
|
||||||
When given @option{--get-word}, return the value of the word (two bytes)
|
When given @option{--get-word}, return the value of the word (two bytes)
|
||||||
at @var{offset} bytes into the selected SMBIOS structure.
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
@item
|
@item
|
||||||
When given @option{--get-dword}, return the value of the dword (four bytes)
|
When given @option{--get-dword}, return the value of the dword (four bytes)
|
||||||
at @var{offset} bytes into the selected SMBIOS structure.
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
@item
|
@item
|
||||||
When given @option{--get-qword}, return the value of the qword (eight bytes)
|
When given @option{--get-qword}, return the value of the qword (eight bytes)
|
||||||
at @var{offset} bytes into the selected SMBIOS structure.
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
|
It will be formatted as an unsigned decimal integer.
|
||||||
@item
|
@item
|
||||||
When given @option{--get-string}, return the string with its index found
|
When given @option{--get-string}, return the string with its index found
|
||||||
at @var{offset} bytes into the selected SMBIOS structure.
|
at @var{offset} bytes into the selected SMBIOS structure.
|
||||||
@item
|
@item
|
||||||
When given @option{--get-uuid}, return the value of the UUID (sixteen bytes)
|
When given @option{--get-uuid}, return the value of the UUID (sixteen bytes)
|
||||||
at @var{offset} bytes into the selected SMBIOS structure.
|
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
|
@end itemize
|
||||||
|
|
||||||
The default action is to print the value of the requested field to the console,
|
The default action is to print the value of the requested field to the console,
|
||||||
|
@ -5268,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
|
||||||
|
@ -5357,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
|
||||||
|
@ -5407,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
|
||||||
|
@ -5435,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
|
||||||
|
|
||||||
|
@ -5681,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
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/tpm.h
|
|
||||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
||||||
|
|
||||||
if COND_i386_pc
|
if COND_i386_pc
|
||||||
|
|
|
@ -140,7 +140,6 @@ kernel = {
|
||||||
common = kern/rescue_parser.c;
|
common = kern/rescue_parser.c;
|
||||||
common = kern/rescue_reader.c;
|
common = kern/rescue_reader.c;
|
||||||
common = kern/term.c;
|
common = kern/term.c;
|
||||||
common = kern/tpm.c;
|
|
||||||
|
|
||||||
noemu = kern/compiler-rt.c;
|
noemu = kern/compiler-rt.c;
|
||||||
noemu = kern/mm.c;
|
noemu = kern/mm.c;
|
||||||
|
@ -204,7 +203,6 @@ kernel = {
|
||||||
efi = term/efi/console.c;
|
efi = term/efi/console.c;
|
||||||
efi = kern/acpi.c;
|
efi = kern/acpi.c;
|
||||||
efi = kern/efi/acpi.c;
|
efi = kern/efi/acpi.c;
|
||||||
efi = kern/efi/tpm.c;
|
|
||||||
i386_coreboot = kern/i386/pc/acpi.c;
|
i386_coreboot = kern/i386/pc/acpi.c;
|
||||||
i386_multiboot = kern/i386/pc/acpi.c;
|
i386_multiboot = kern/i386/pc/acpi.c;
|
||||||
i386_coreboot = kern/acpi.c;
|
i386_coreboot = kern/acpi.c;
|
||||||
|
@ -264,7 +262,6 @@ kernel = {
|
||||||
|
|
||||||
i386_pc = kern/i386/pc/init.c;
|
i386_pc = kern/i386/pc/init.c;
|
||||||
i386_pc = kern/i386/pc/mmap.c;
|
i386_pc = kern/i386/pc/mmap.c;
|
||||||
i386_pc = kern/i386/pc/tpm.c;
|
|
||||||
i386_pc = term/i386/pc/console.c;
|
i386_pc = term/i386/pc/console.c;
|
||||||
|
|
||||||
i386_qemu = bus/pci.c;
|
i386_qemu = bus/pci.c;
|
||||||
|
@ -891,32 +888,11 @@ module = {
|
||||||
enable = x86_64_efi;
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
|
||||||
name = getenv;
|
|
||||||
common = commands/efi/getenv.c;
|
|
||||||
enable = efi;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = gptsync;
|
name = gptsync;
|
||||||
common = commands/gptsync.c;
|
common = commands/gptsync.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
|
||||||
name = gptrepair;
|
|
||||||
common = commands/gptrepair.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
|
||||||
name = gptprio;
|
|
||||||
common = commands/gptprio.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
|
||||||
name = gpt;
|
|
||||||
common = lib/gpt.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = halt;
|
name = halt;
|
||||||
nopc = commands/halt.c;
|
nopc = commands/halt.c;
|
||||||
|
@ -974,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 = {
|
||||||
|
@ -1104,21 +1080,6 @@ module = {
|
||||||
common = commands/search_label.c;
|
common = commands/search_label.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
|
||||||
name = search_part_uuid;
|
|
||||||
common = commands/search_part_uuid.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
|
||||||
name = search_part_label;
|
|
||||||
common = commands/search_part_label.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
|
||||||
name = search_disk_uuid;
|
|
||||||
common = commands/search_disk_uuid.c;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = setpci;
|
name = setpci;
|
||||||
common = commands/setpci.c;
|
common = commands/setpci.c;
|
||||||
|
@ -1215,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 = {
|
||||||
|
@ -1709,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;
|
||||||
|
@ -1721,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 = {
|
||||||
|
@ -1903,14 +1881,6 @@ module = {
|
||||||
enable = x86_64_efi;
|
enable = x86_64_efi;
|
||||||
};
|
};
|
||||||
|
|
||||||
module = {
|
|
||||||
name = linuxefi;
|
|
||||||
efi = loader/i386/efi/linux.c;
|
|
||||||
efi = lib/cmdline.c;
|
|
||||||
enable = i386_efi;
|
|
||||||
enable = x86_64_efi;
|
|
||||||
};
|
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = chain;
|
name = chain;
|
||||||
efi = loader/efi/chainloader.c;
|
efi = loader/efi/chainloader.c;
|
||||||
|
@ -1956,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;
|
||||||
|
@ -2531,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 = {
|
||||||
|
@ -2565,8 +2534,3 @@ module = {
|
||||||
common = commands/i386/wrmsr.c;
|
common = commands/i386/wrmsr.c;
|
||||||
enable = x86;
|
enable = x86;
|
||||||
};
|
};
|
||||||
module = {
|
|
||||||
name = fwconfig;
|
|
||||||
common = commands/fwconfig.c;
|
|
||||||
enable = x86;
|
|
||||||
};
|
|
||||||
|
|
|
@ -24,14 +24,11 @@
|
||||||
* defines for the code go here
|
* defines for the code go here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TPM 1
|
|
||||||
|
|
||||||
/* Print message string */
|
/* Print message string */
|
||||||
#define MSG(x) movw $x, %si; call LOCAL(message)
|
#define MSG(x) movw $x, %si; call LOCAL(message)
|
||||||
#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
|
#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
|
||||||
|
|
||||||
.macro floppy
|
.macro floppy
|
||||||
#ifndef TPM
|
|
||||||
part_start:
|
part_start:
|
||||||
|
|
||||||
LOCAL(probe_values):
|
LOCAL(probe_values):
|
||||||
|
@ -88,7 +85,6 @@ fd_probe_error_string: .asciz "Floppy"
|
||||||
movb MACRO_DOLLAR(79), %ch
|
movb MACRO_DOLLAR(79), %ch
|
||||||
|
|
||||||
jmp LOCAL(final_init)
|
jmp LOCAL(final_init)
|
||||||
#endif
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro scratch
|
.macro scratch
|
||||||
|
@ -259,7 +255,6 @@ real_start:
|
||||||
/* set %si to the disk address packet */
|
/* set %si to the disk address packet */
|
||||||
movw $disk_address_packet, %si
|
movw $disk_address_packet, %si
|
||||||
|
|
||||||
#ifndef TPM
|
|
||||||
/* check if LBA is supported */
|
/* check if LBA is supported */
|
||||||
movb $0x41, %ah
|
movb $0x41, %ah
|
||||||
movw $0x55aa, %bx
|
movw $0x55aa, %bx
|
||||||
|
@ -279,7 +274,6 @@ real_start:
|
||||||
|
|
||||||
andw $1, %cx
|
andw $1, %cx
|
||||||
jz LOCAL(chs_mode)
|
jz LOCAL(chs_mode)
|
||||||
#endif
|
|
||||||
|
|
||||||
LOCAL(lba_mode):
|
LOCAL(lba_mode):
|
||||||
xorw %ax, %ax
|
xorw %ax, %ax
|
||||||
|
@ -323,9 +317,6 @@ LOCAL(lba_mode):
|
||||||
jmp LOCAL(copy_buffer)
|
jmp LOCAL(copy_buffer)
|
||||||
|
|
||||||
LOCAL(chs_mode):
|
LOCAL(chs_mode):
|
||||||
#ifdef TPM
|
|
||||||
jmp LOCAL(general_error)
|
|
||||||
#else
|
|
||||||
/*
|
/*
|
||||||
* Determine the hard disk geometry from the BIOS!
|
* Determine the hard disk geometry from the BIOS!
|
||||||
* We do this first, so that LS-120 IDE floppies work correctly.
|
* We do this first, so that LS-120 IDE floppies work correctly.
|
||||||
|
@ -437,7 +428,7 @@ setup_sectors:
|
||||||
jc LOCAL(read_error)
|
jc LOCAL(read_error)
|
||||||
|
|
||||||
movw %es, %bx
|
movw %es, %bx
|
||||||
#endif /* TPM */
|
|
||||||
LOCAL(copy_buffer):
|
LOCAL(copy_buffer):
|
||||||
/*
|
/*
|
||||||
* We need to save %cx and %si because the startup code in
|
* We need to save %cx and %si because the startup code in
|
||||||
|
@ -460,25 +451,6 @@ LOCAL(copy_buffer):
|
||||||
popw %ds
|
popw %ds
|
||||||
popa
|
popa
|
||||||
|
|
||||||
#ifdef TPM
|
|
||||||
pusha
|
|
||||||
|
|
||||||
movw $0xBB00, %ax /* TCG_StatusCheck */
|
|
||||||
int $0x1A
|
|
||||||
test %eax, %eax
|
|
||||||
jnz boot /* No TPM or TPM deactivated */
|
|
||||||
|
|
||||||
movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */
|
|
||||||
movw $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di
|
|
||||||
xorl %esi, %esi
|
|
||||||
movl $0x41504354, %ebx /* TCPA */
|
|
||||||
movl $0x200, %ecx /* Measure 512 bytes */
|
|
||||||
movl $0x8, %edx /* PCR 8 */
|
|
||||||
int $0x1A
|
|
||||||
|
|
||||||
boot:
|
|
||||||
popa
|
|
||||||
#endif
|
|
||||||
/* boot kernel */
|
/* boot kernel */
|
||||||
jmp *(LOCAL(kernel_address))
|
jmp *(LOCAL(kernel_address))
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
#include <grub/symbol.h>
|
#include <grub/symbol.h>
|
||||||
#include <grub/machine/boot.h>
|
#include <grub/machine/boot.h>
|
||||||
|
|
||||||
#define TPM 1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* defines for the code go here
|
* defines for the code go here
|
||||||
*/
|
*/
|
||||||
|
@ -60,21 +58,6 @@ _start:
|
||||||
/* this sets up for the first run through "bootloop" */
|
/* this sets up for the first run through "bootloop" */
|
||||||
movw $LOCAL(firstlist), %di
|
movw $LOCAL(firstlist), %di
|
||||||
|
|
||||||
#ifdef TPM
|
|
||||||
/* clear EAX to remove potential garbage */
|
|
||||||
xorl %eax, %eax
|
|
||||||
/* 8(%di) = number of sectors to read */
|
|
||||||
movw 8(%di), %ax
|
|
||||||
|
|
||||||
/* Multiply number of sectors to read with 512 bytes. EAX is 32bit
|
|
||||||
* which is large enough to hold values of up to 4GB. I doubt there
|
|
||||||
* will ever be a core.img larger than that. ;-) */
|
|
||||||
shll $9, %eax
|
|
||||||
|
|
||||||
/* write result to bytes_to_measure var */
|
|
||||||
movl %eax, bytes_to_measure
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* save the sector number of the second sector in %ebp */
|
/* save the sector number of the second sector in %ebp */
|
||||||
movl (%di), %ebp
|
movl (%di), %ebp
|
||||||
|
|
||||||
|
@ -312,29 +295,6 @@ LOCAL(copy_buffer):
|
||||||
/* END OF MAIN LOOP */
|
/* END OF MAIN LOOP */
|
||||||
|
|
||||||
LOCAL(bootit):
|
LOCAL(bootit):
|
||||||
#ifdef TPM
|
|
||||||
pusha
|
|
||||||
movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */
|
|
||||||
|
|
||||||
movw $0x0, %bx
|
|
||||||
movw %bx, %es
|
|
||||||
|
|
||||||
/* We've already measured the first 512 bytes, now measure the rest */
|
|
||||||
xorl %edi, %edi
|
|
||||||
movw $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200), %di
|
|
||||||
|
|
||||||
movl $0x41504354, %ebx /* EBX = "TCPA" */
|
|
||||||
|
|
||||||
/* %ecx = The length, in bytes, of the buffer to measure */
|
|
||||||
movl $bytes_to_measure, %esi
|
|
||||||
movl (%esi), %ecx
|
|
||||||
xorl %esi, %esi
|
|
||||||
movl $0x9, %edx /* PCR 9 */
|
|
||||||
|
|
||||||
int $0x1A
|
|
||||||
|
|
||||||
popa
|
|
||||||
#endif
|
|
||||||
/* print a newline */
|
/* print a newline */
|
||||||
MSG(notification_done)
|
MSG(notification_done)
|
||||||
popw %dx /* this makes sure %dl is our "boot" drive */
|
popw %dx /* this makes sure %dl is our "boot" drive */
|
||||||
|
@ -369,10 +329,6 @@ geometry_error_string: .asciz "Geom"
|
||||||
read_error_string: .asciz "Read"
|
read_error_string: .asciz "Read"
|
||||||
general_error_string: .asciz " Error"
|
general_error_string: .asciz " Error"
|
||||||
|
|
||||||
#ifdef TPM
|
|
||||||
bytes_to_measure: .long 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* message: write the string pointed to by %si
|
* message: write the string pointed to by %si
|
||||||
*
|
*
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -1,153 +0,0 @@
|
||||||
/* getenv.c - retrieve EFI variables. */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
|
||||||
* Copyright (C) 2014 CoreOS, 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/efi/efi.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/extcmd.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
static const struct grub_arg_option options_getenv[] = {
|
|
||||||
{"var-name", 'e', 0,
|
|
||||||
N_("Environment variable to query"),
|
|
||||||
N_("VARNAME"), ARG_TYPE_STRING},
|
|
||||||
{"var-guid", 'g', 0,
|
|
||||||
N_("GUID of environment variable to query"),
|
|
||||||
N_("GUID"), ARG_TYPE_STRING},
|
|
||||||
{"binary", 'b', 0,
|
|
||||||
N_("Read binary data and represent it as hex"),
|
|
||||||
0, ARG_TYPE_NONE},
|
|
||||||
{0, 0, 0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum options_getenv
|
|
||||||
{
|
|
||||||
GETENV_VAR_NAME,
|
|
||||||
GETENV_VAR_GUID,
|
|
||||||
GETENV_BINARY,
|
|
||||||
};
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_getenv (grub_extcmd_context_t ctxt, int argc, char **args)
|
|
||||||
{
|
|
||||||
struct grub_arg_list *state = ctxt->state;
|
|
||||||
char *envvar = NULL, *guid = NULL, *bindata = NULL, *data = NULL;
|
|
||||||
grub_size_t datasize;
|
|
||||||
grub_efi_guid_t efi_var_guid;
|
|
||||||
grub_efi_boolean_t binary = state[GETENV_BINARY].set;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (!state[GETENV_VAR_NAME].set || !state[GETENV_VAR_GUID].set)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_INVALID_COMMAND, N_("-e and -g are required"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc != 1)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
envvar = state[GETENV_VAR_NAME].arg;
|
|
||||||
guid = state[GETENV_VAR_GUID].arg;
|
|
||||||
|
|
||||||
if (grub_strlen(guid) != 36 ||
|
|
||||||
guid[8] != '-' ||
|
|
||||||
guid[13] != '-' ||
|
|
||||||
guid[18] != '-' ||
|
|
||||||
guid[23] != '-')
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid GUID"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Forgive me father for I have sinned */
|
|
||||||
guid[8] = 0;
|
|
||||||
efi_var_guid.data1 = grub_strtoul(guid, NULL, 16);
|
|
||||||
guid[13] = 0;
|
|
||||||
efi_var_guid.data2 = grub_strtoul(guid + 9, NULL, 16);
|
|
||||||
guid[18] = 0;
|
|
||||||
efi_var_guid.data3 = grub_strtoul(guid + 14, NULL, 16);
|
|
||||||
efi_var_guid.data4[7] = grub_strtoul(guid + 34, NULL, 16);
|
|
||||||
guid[34] = 0;
|
|
||||||
efi_var_guid.data4[6] = grub_strtoul(guid + 32, NULL, 16);
|
|
||||||
guid[32] = 0;
|
|
||||||
efi_var_guid.data4[5] = grub_strtoul(guid + 30, NULL, 16);
|
|
||||||
guid[30] = 0;
|
|
||||||
efi_var_guid.data4[4] = grub_strtoul(guid + 28, NULL, 16);
|
|
||||||
guid[28] = 0;
|
|
||||||
efi_var_guid.data4[3] = grub_strtoul(guid + 26, NULL, 16);
|
|
||||||
guid[26] = 0;
|
|
||||||
efi_var_guid.data4[2] = grub_strtoul(guid + 24, NULL, 16);
|
|
||||||
guid[23] = 0;
|
|
||||||
efi_var_guid.data4[1] = grub_strtoul(guid + 21, NULL, 16);
|
|
||||||
guid[21] = 0;
|
|
||||||
efi_var_guid.data4[0] = grub_strtoul(guid + 19, NULL, 16);
|
|
||||||
|
|
||||||
data = grub_efi_get_variable(envvar, &efi_var_guid, &datasize);
|
|
||||||
|
|
||||||
if (!data || !datasize)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binary)
|
|
||||||
{
|
|
||||||
bindata = grub_zalloc(datasize * 2 + 1);
|
|
||||||
for (i=0; i<datasize; i++)
|
|
||||||
grub_snprintf(bindata + i*2, 3, "%02x", data[i] & 0xff);
|
|
||||||
|
|
||||||
if (grub_env_set (args[0], bindata))
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
else if (grub_env_set (args[0], data))
|
|
||||||
{
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
|
|
||||||
done:
|
|
||||||
grub_free(bindata);
|
|
||||||
grub_free(data);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_extcmd_t cmd_getenv;
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(getenv)
|
|
||||||
{
|
|
||||||
cmd_getenv = grub_register_extcmd ("getenv", grub_cmd_getenv, 0,
|
|
||||||
N_("-e envvar -g guidenv setvar"),
|
|
||||||
N_("Read a firmware environment variable"),
|
|
||||||
options_getenv);
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(getenv)
|
|
||||||
{
|
|
||||||
grub_unregister_extcmd (cmd_getenv);
|
|
||||||
}
|
|
|
@ -30,7 +30,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
|
static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID;
|
||||||
static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
|
static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID;
|
||||||
static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
|
static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID;
|
||||||
static grub_efi_guid_t smbios3_guid = GRUB_EFI_SMBIOS3_TABLE_GUID;
|
|
||||||
|
|
||||||
#define EBDA_SEG_ADDR 0x40e
|
#define EBDA_SEG_ADDR 0x40e
|
||||||
#define LOW_MEM_ADDR 0x413
|
#define LOW_MEM_ADDR 0x413
|
||||||
|
@ -94,7 +93,7 @@ static void
|
||||||
fake_bios_data (int use_rom)
|
fake_bios_data (int use_rom)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
void *acpi, *smbios, *smbios3;
|
void *acpi, *smbios;
|
||||||
grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
|
grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
|
||||||
|
|
||||||
ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
|
ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
|
||||||
|
@ -104,7 +103,6 @@ fake_bios_data (int use_rom)
|
||||||
|
|
||||||
acpi = 0;
|
acpi = 0;
|
||||||
smbios = 0;
|
smbios = 0;
|
||||||
smbios3 = 0;
|
|
||||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||||
{
|
{
|
||||||
grub_efi_packed_guid_t *guid =
|
grub_efi_packed_guid_t *guid =
|
||||||
|
@ -129,11 +127,6 @@ fake_bios_data (int use_rom)
|
||||||
smbios = grub_efi_system_table->configuration_table[i].vendor_table;
|
smbios = grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
grub_dprintf ("efi", "SMBIOS: %p\n", smbios);
|
grub_dprintf ("efi", "SMBIOS: %p\n", smbios);
|
||||||
}
|
}
|
||||||
else if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_guid_t)))
|
|
||||||
{
|
|
||||||
smbios3 = grub_efi_system_table->configuration_table[i].vendor_table;
|
|
||||||
grub_dprintf ("efi", "SMBIOS3: %p\n", smbios3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ebda_seg_ptr = FAKE_EBDA_SEG;
|
*ebda_seg_ptr = FAKE_EBDA_SEG;
|
||||||
|
@ -144,13 +137,8 @@ fake_bios_data (int use_rom)
|
||||||
if (acpi)
|
if (acpi)
|
||||||
grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
|
grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
|
||||||
|
|
||||||
if (use_rom)
|
if ((use_rom) && (smbios))
|
||||||
{
|
grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
|
||||||
if (smbios)
|
|
||||||
grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios, 31);
|
|
||||||
if (smbios3)
|
|
||||||
grub_memcpy ((char *) SBIOS_ADDR + 32, (char *) smbios3, 24);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
|
|
@ -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"},
|
||||||
|
@ -72,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,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* smbios.c - get smbios tables. */
|
/* smbios.c - get smbios tables. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2015 Free Software Foundation, Inc.
|
* Copyright (C) 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
|
||||||
|
@ -37,6 +37,7 @@ grub_machine_smbios_get_eps (void)
|
||||||
return (struct grub_smbios_eps *)
|
return (struct grub_smbios_eps *)
|
||||||
grub_efi_system_table->configuration_table[i].vendor_table;
|
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,5 +56,6 @@ grub_machine_smbios_get_eps3 (void)
|
||||||
return (struct grub_smbios_eps3 *)
|
return (struct grub_smbios_eps3 *)
|
||||||
grub_efi_system_table->configuration_table[i].vendor_table;
|
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
/* fwconfig.c - command to read config from qemu fwconfig */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2015 CoreOS, 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/misc.h>
|
|
||||||
#include <grub/extcmd.h>
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/cpu/io.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
#define SELECTOR 0x510
|
|
||||||
#define DATA 0x511
|
|
||||||
|
|
||||||
#define SIGNATURE_INDEX 0x00
|
|
||||||
#define DIRECTORY_INDEX 0x19
|
|
||||||
|
|
||||||
static grub_extcmd_t cmd_read_fwconfig;
|
|
||||||
|
|
||||||
struct grub_qemu_fwcfgfile {
|
|
||||||
grub_uint32_t size;
|
|
||||||
grub_uint16_t select;
|
|
||||||
grub_uint16_t reserved;
|
|
||||||
char name[56];
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct grub_arg_option options[] =
|
|
||||||
{
|
|
||||||
{0, 'v', 0, N_("Save read value into variable VARNAME."),
|
|
||||||
N_("VARNAME"), ARG_TYPE_STRING},
|
|
||||||
{0, 0, 0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_fwconfig (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
|
||||||
int argc, char **argv)
|
|
||||||
{
|
|
||||||
grub_uint32_t i, j, value = 0;
|
|
||||||
struct grub_qemu_fwcfgfile file;
|
|
||||||
char fwsig[4], signature[4] = { 'Q', 'E', 'M', 'U' };
|
|
||||||
|
|
||||||
if (argc != 2)
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
|
|
||||||
|
|
||||||
/* Verify that we have meaningful hardware here */
|
|
||||||
grub_outw(SIGNATURE_INDEX, SELECTOR);
|
|
||||||
for (i=0; i<sizeof(fwsig); i++)
|
|
||||||
fwsig[i] = grub_inb(DATA);
|
|
||||||
|
|
||||||
if (grub_memcmp(fwsig, signature, sizeof(signature)) != 0)
|
|
||||||
return grub_error (GRUB_ERR_BAD_DEVICE, N_("invalid fwconfig hardware signature: got 0x%x%x%x%x"), fwsig[0], fwsig[1], fwsig[2], fwsig[3]);
|
|
||||||
|
|
||||||
/* Find out how many file entries we have */
|
|
||||||
grub_outw(DIRECTORY_INDEX, SELECTOR);
|
|
||||||
value = grub_inb(DATA) | grub_inb(DATA) << 8 | grub_inb(DATA) << 16 | grub_inb(DATA) << 24;
|
|
||||||
value = grub_be_to_cpu32(value);
|
|
||||||
/* Read the file description for each file */
|
|
||||||
for (i=0; i<value; i++)
|
|
||||||
{
|
|
||||||
for (j=0; j<sizeof(file); j++)
|
|
||||||
{
|
|
||||||
((char *)&file)[j] = grub_inb(DATA);
|
|
||||||
}
|
|
||||||
/* Check whether it matches what we're looking for, and if so read the file */
|
|
||||||
if (grub_strncmp(file.name, argv[0], sizeof(file.name)) == 0)
|
|
||||||
{
|
|
||||||
grub_uint32_t filesize = grub_be_to_cpu32(file.size);
|
|
||||||
grub_uint16_t location = grub_be_to_cpu16(file.select);
|
|
||||||
char *data = grub_malloc(filesize+1);
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate buffer for data"));
|
|
||||||
|
|
||||||
grub_outw(location, SELECTOR);
|
|
||||||
for (j=0; j<filesize; j++)
|
|
||||||
{
|
|
||||||
data[j] = grub_inb(DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
data[filesize] = '\0';
|
|
||||||
|
|
||||||
grub_env_set (argv[1], data);
|
|
||||||
|
|
||||||
grub_free(data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("couldn't find entry %s"), argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(fwconfig)
|
|
||||||
{
|
|
||||||
cmd_read_fwconfig =
|
|
||||||
grub_register_extcmd ("fwconfig", grub_cmd_fwconfig, 0,
|
|
||||||
N_("PATH VAR"),
|
|
||||||
N_("Set VAR to the contents of fwconfig PATH"),
|
|
||||||
options);
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(fwconfig)
|
|
||||||
{
|
|
||||||
grub_unregister_extcmd (cmd_read_fwconfig);
|
|
||||||
}
|
|
|
@ -1,223 +0,0 @@
|
||||||
/* gptprio.c - manage priority based partition selection. */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
|
||||||
* Copyright (C) 2014 CoreOS, 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/device.h>
|
|
||||||
#include <grub/env.h>
|
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/extcmd.h>
|
|
||||||
#include <grub/gpt_partition.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
static const struct grub_arg_option options_next[] = {
|
|
||||||
{"set-device", 'd', 0,
|
|
||||||
N_("Set a variable to the name of selected partition."),
|
|
||||||
N_("VARNAME"), ARG_TYPE_STRING},
|
|
||||||
{"set-uuid", 'u', 0,
|
|
||||||
N_("Set a variable to the GPT UUID of selected partition."),
|
|
||||||
N_("VARNAME"), ARG_TYPE_STRING},
|
|
||||||
{0, 0, 0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum options_next
|
|
||||||
{
|
|
||||||
NEXT_SET_DEVICE,
|
|
||||||
NEXT_SET_UUID,
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
grub_gptprio_priority (struct grub_gpt_partentry *entry)
|
|
||||||
{
|
|
||||||
return (unsigned int) grub_gpt_entry_attribute
|
|
||||||
(entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
grub_gptprio_tries_left (struct grub_gpt_partentry *entry)
|
|
||||||
{
|
|
||||||
return (unsigned int) grub_gpt_entry_attribute
|
|
||||||
(entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_gptprio_set_tries_left (struct grub_gpt_partentry *entry,
|
|
||||||
unsigned int tries_left)
|
|
||||||
{
|
|
||||||
grub_gpt_entry_set_attribute
|
|
||||||
(entry, tries_left, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
grub_gptprio_successful (struct grub_gpt_partentry *entry)
|
|
||||||
{
|
|
||||||
return (unsigned int) grub_gpt_entry_attribute
|
|
||||||
(entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_find_next (const char *disk_name,
|
|
||||||
const grub_gpt_part_guid_t *part_type,
|
|
||||||
char **part_name, char **part_guid)
|
|
||||||
{
|
|
||||||
struct grub_gpt_partentry *part, *part_found = NULL;
|
|
||||||
grub_device_t dev = NULL;
|
|
||||||
grub_gpt_t gpt = NULL;
|
|
||||||
grub_uint32_t i, part_index;
|
|
||||||
|
|
||||||
dev = grub_device_open (disk_name);
|
|
||||||
if (!dev)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
gpt = grub_gpt_read (dev->disk);
|
|
||||||
if (!gpt)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (grub_gpt_repair (dev->disk, gpt))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
for (i = 0; (part = grub_gpt_get_partentry (gpt, i)) != NULL; i++)
|
|
||||||
{
|
|
||||||
if (grub_memcmp (part_type, &part->type, sizeof (*part_type)) == 0)
|
|
||||||
{
|
|
||||||
unsigned int priority, tries_left, successful, old_priority = 0;
|
|
||||||
|
|
||||||
priority = grub_gptprio_priority (part);
|
|
||||||
tries_left = grub_gptprio_tries_left (part);
|
|
||||||
successful = grub_gptprio_successful (part);
|
|
||||||
|
|
||||||
if (part_found)
|
|
||||||
old_priority = grub_gptprio_priority (part_found);
|
|
||||||
|
|
||||||
if ((tries_left || successful) && priority > old_priority)
|
|
||||||
{
|
|
||||||
part_index = i;
|
|
||||||
part_found = part;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!part_found)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such partition"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grub_gptprio_tries_left (part_found))
|
|
||||||
{
|
|
||||||
unsigned int tries_left = grub_gptprio_tries_left (part_found);
|
|
||||||
|
|
||||||
grub_gptprio_set_tries_left (part_found, tries_left - 1);
|
|
||||||
|
|
||||||
if (grub_gpt_update (gpt))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (grub_gpt_write (dev->disk, gpt))
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
*part_name = grub_xasprintf ("%s,gpt%u", disk_name, part_index + 1);
|
|
||||||
if (!*part_name)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
*part_guid = grub_gpt_guid_to_str (&part_found->guid);
|
|
||||||
if (!*part_guid)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
|
|
||||||
done:
|
|
||||||
grub_gpt_free (gpt);
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
grub_device_close (dev);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_next (grub_extcmd_context_t ctxt, int argc, char **args)
|
|
||||||
{
|
|
||||||
struct grub_arg_list *state = ctxt->state;
|
|
||||||
char *p, *root = NULL, *part_name = NULL, *part_guid = NULL;
|
|
||||||
|
|
||||||
/* TODO: Add a uuid parser and a command line flag for providing type. */
|
|
||||||
grub_gpt_part_guid_t part_type = GRUB_GPT_PARTITION_TYPE_USR_X86_64;
|
|
||||||
|
|
||||||
if (!state[NEXT_SET_DEVICE].set || !state[NEXT_SET_UUID].set)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_INVALID_COMMAND, N_("-d and -u are required"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
root = grub_strdup (grub_env_get ("root"));
|
|
||||||
else if (argc == 1)
|
|
||||||
root = grub_strdup (args[0]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!root)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* To make using $root practical strip off the partition name. */
|
|
||||||
p = grub_strchr (root, ',');
|
|
||||||
if (p)
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
if (grub_find_next (root, &part_type, &part_name, &part_guid))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (grub_env_set (state[NEXT_SET_DEVICE].arg, part_name))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (grub_env_set (state[NEXT_SET_UUID].arg, part_guid))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
|
|
||||||
done:
|
|
||||||
grub_free (root);
|
|
||||||
grub_free (part_name);
|
|
||||||
grub_free (part_guid);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_extcmd_t cmd_next;
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(gptprio)
|
|
||||||
{
|
|
||||||
cmd_next = grub_register_extcmd ("gptprio.next", grub_cmd_next, 0,
|
|
||||||
N_("-d VARNAME -u VARNAME [DEVICE]"),
|
|
||||||
N_("Select next partition to boot."),
|
|
||||||
options_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(gptprio)
|
|
||||||
{
|
|
||||||
grub_unregister_extcmd (cmd_next);
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
/* gptrepair.c - verify and restore GPT info from alternate location. */
|
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
|
||||||
* Copyright (C) 2014 CoreOS, 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/command.h>
|
|
||||||
#include <grub/device.h>
|
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/gpt_partition.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
static char *
|
|
||||||
trim_dev_name (char *name)
|
|
||||||
{
|
|
||||||
grub_size_t len = grub_strlen (name);
|
|
||||||
if (len && name[0] == '(' && name[len - 1] == ')')
|
|
||||||
{
|
|
||||||
name[len - 1] = '\0';
|
|
||||||
name = name + 1;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_gptrepair (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char **args)
|
|
||||||
{
|
|
||||||
grub_device_t dev = NULL;
|
|
||||||
grub_gpt_t gpt = NULL;
|
|
||||||
char *dev_name;
|
|
||||||
|
|
||||||
if (argc != 1 || !grub_strlen(args[0]))
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
|
||||||
|
|
||||||
dev_name = trim_dev_name (args[0]);
|
|
||||||
dev = grub_device_open (dev_name);
|
|
||||||
if (!dev)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (!dev->disk)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpt = grub_gpt_read (dev->disk);
|
|
||||||
if (!gpt)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (grub_gpt_both_valid (gpt))
|
|
||||||
{
|
|
||||||
grub_printf_ (N_("GPT already valid, %s unmodified.\n"), dev_name);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!grub_gpt_primary_valid (gpt))
|
|
||||||
grub_printf_ (N_("Found invalid primary GPT on %s\n"), dev_name);
|
|
||||||
|
|
||||||
if (!grub_gpt_backup_valid (gpt))
|
|
||||||
grub_printf_ (N_("Found invalid backup GPT on %s\n"), dev_name);
|
|
||||||
|
|
||||||
if (grub_gpt_repair (dev->disk, gpt))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (grub_gpt_write (dev->disk, gpt))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
grub_printf_ (N_("Repaired GPT on %s\n"), dev_name);
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (gpt)
|
|
||||||
grub_gpt_free (gpt);
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
grub_device_close (dev);
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_command_t cmd;
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(gptrepair)
|
|
||||||
{
|
|
||||||
cmd = grub_register_command ("gptrepair", grub_cmd_gptrepair,
|
|
||||||
N_("DEVICE"),
|
|
||||||
N_("Verify and repair GPT on drive DEVICE."));
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(gptrepair)
|
|
||||||
{
|
|
||||||
grub_unregister_command (cmd);
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* smbios.c - get smbios tables. */
|
/* smbios.c - get smbios tables. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2015 Free Software Foundation, Inc.
|
* Copyright (C) 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
|
||||||
|
@ -27,11 +27,12 @@ grub_machine_smbios_get_eps (void)
|
||||||
grub_uint8_t *ptr;
|
grub_uint8_t *ptr;
|
||||||
|
|
||||||
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
|
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
|
||||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
|
|
||||||
ptr += 16)
|
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||||
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
||||||
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
|
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
|
||||||
return (struct grub_smbios_eps *) ptr;
|
return (struct grub_smbios_eps *) ptr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +42,11 @@ grub_machine_smbios_get_eps3 (void)
|
||||||
grub_uint8_t *ptr;
|
grub_uint8_t *ptr;
|
||||||
|
|
||||||
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
|
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
|
||||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
|
|
||||||
ptr += 16)
|
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||||
if (grub_memcmp (ptr, "_SM3_", 5) == 0
|
if (grub_memcmp (ptr, "_SM3_", 5) == 0
|
||||||
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
|
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
|
||||||
return (struct grub_smbios_eps3 *) ptr;
|
return (struct grub_smbios_eps3 *) ptr;
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
|
|
@ -759,78 +759,6 @@ grub_cmd_trust (grub_extcmd_context_t ctxt,
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_ssize_t
|
|
||||||
pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
|
|
||||||
{
|
|
||||||
grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Filesystem descriptor. */
|
|
||||||
struct grub_fs pseudo_fs =
|
|
||||||
{
|
|
||||||
.name = "pseudo",
|
|
||||||
.fs_read = pseudo_read
|
|
||||||
};
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_cmd_trust_var (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char **args)
|
|
||||||
{
|
|
||||||
struct grub_file pseudo_file;
|
|
||||||
const char *var;
|
|
||||||
char *data;
|
|
||||||
struct grub_public_key *pk = NULL;
|
|
||||||
unsigned int i, idx0, idx1;
|
|
||||||
|
|
||||||
if (argc < 1)
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
|
||||||
|
|
||||||
var = grub_env_get (args[0]);
|
|
||||||
if (!var)
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown variable"));
|
|
||||||
|
|
||||||
data = grub_zalloc (grub_strlen (var) / 2);
|
|
||||||
if (!data)
|
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate memory for key"));
|
|
||||||
|
|
||||||
/* For the want of sscanf() */
|
|
||||||
for (i = 0; i < grub_strlen (var); i += 2)
|
|
||||||
{
|
|
||||||
if (var[i] < 0x40)
|
|
||||||
idx0 = var[i] - 0x30;
|
|
||||||
else
|
|
||||||
idx0 = var[i] - 0x57;
|
|
||||||
|
|
||||||
if (var[i+1] < 0x40)
|
|
||||||
idx1 = var[i+1] - 0x30;
|
|
||||||
else
|
|
||||||
idx1 = var[i+1] - 0x57;
|
|
||||||
|
|
||||||
data[i/2] = ((idx0 << 4) & 0xf0) | (idx1 & 0x0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
|
||||||
|
|
||||||
pseudo_file.fs = &pseudo_fs;
|
|
||||||
pseudo_file.size = grub_strlen (var) / 2;
|
|
||||||
pseudo_file.data = data;
|
|
||||||
|
|
||||||
pk = grub_load_public_key (&pseudo_file);
|
|
||||||
if (!pk)
|
|
||||||
{
|
|
||||||
grub_free(data);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
pk->next = grub_pk_trusted;
|
|
||||||
grub_pk_trusted = pk;
|
|
||||||
|
|
||||||
grub_free(data);
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
|
grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
|
@ -994,6 +922,21 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
|
||||||
return grub_strdup (sec ? "enforce" : "no");
|
return grub_strdup (sec ? "enforce" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_ssize_t
|
||||||
|
pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
|
||||||
|
{
|
||||||
|
grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Filesystem descriptor. */
|
||||||
|
struct grub_fs pseudo_fs =
|
||||||
|
{
|
||||||
|
.name = "pseudo",
|
||||||
|
.fs_read = pseudo_read
|
||||||
|
};
|
||||||
|
|
||||||
struct grub_file_verifier grub_pubkey_verifier =
|
struct grub_file_verifier grub_pubkey_verifier =
|
||||||
{
|
{
|
||||||
.name = "pgp",
|
.name = "pgp",
|
||||||
|
@ -1004,7 +947,7 @@ struct grub_file_verifier grub_pubkey_verifier =
|
||||||
};
|
};
|
||||||
|
|
||||||
static grub_extcmd_t cmd, cmd_trust;
|
static grub_extcmd_t cmd, cmd_trust;
|
||||||
static grub_command_t cmd_trust_var, cmd_distrust, cmd_list;
|
static grub_command_t cmd_distrust, cmd_list;
|
||||||
|
|
||||||
GRUB_MOD_INIT(pgp)
|
GRUB_MOD_INIT(pgp)
|
||||||
{
|
{
|
||||||
|
@ -1055,9 +998,6 @@ GRUB_MOD_INIT(pgp)
|
||||||
N_("[-s|--skip-sig] PUBKEY_FILE"),
|
N_("[-s|--skip-sig] PUBKEY_FILE"),
|
||||||
N_("Add PUBKEY_FILE to trusted keys."),
|
N_("Add PUBKEY_FILE to trusted keys."),
|
||||||
options);
|
options);
|
||||||
cmd_trust_var = grub_register_command ("trust_var", grub_cmd_trust_var,
|
|
||||||
N_("PUBKEY_VAR"),
|
|
||||||
N_("Add the contents of PUBKEY_VAR to trusted keys."));
|
|
||||||
cmd_list = grub_register_command ("list_trusted", grub_cmd_list,
|
cmd_list = grub_register_command ("list_trusted", grub_cmd_list,
|
||||||
0,
|
0,
|
||||||
N_("Show the list of trusted keys."));
|
N_("Show the list of trusted keys."));
|
||||||
|
@ -1073,7 +1013,6 @@ GRUB_MOD_FINI(pgp)
|
||||||
grub_verifier_unregister (&grub_pubkey_verifier);
|
grub_verifier_unregister (&grub_pubkey_verifier);
|
||||||
grub_unregister_extcmd (cmd);
|
grub_unregister_extcmd (cmd);
|
||||||
grub_unregister_extcmd (cmd_trust);
|
grub_unregister_extcmd (cmd_trust);
|
||||||
grub_unregister_command (cmd_trust_var);
|
|
||||||
grub_unregister_command (cmd_list);
|
grub_unregister_command (cmd_list);
|
||||||
grub_unregister_command (cmd_distrust);
|
grub_unregister_command (cmd_distrust);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,6 @@
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
#if defined(DO_SEARCH_PART_UUID) || defined(DO_SEARCH_PART_LABEL) || \
|
|
||||||
defined(DO_SEARCH_DISK_UUID)
|
|
||||||
#include <grub/gpt_partition.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -70,7 +66,7 @@ iterate_device (const char *name, void *data)
|
||||||
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#if defined(DO_SEARCH_FS_UUID) || defined(DO_SEARCH_DISK_UUID)
|
#ifdef DO_SEARCH_FS_UUID
|
||||||
#define compare_fn grub_strcasecmp
|
#define compare_fn grub_strcasecmp
|
||||||
#else
|
#else
|
||||||
#define compare_fn grub_strcmp
|
#define compare_fn grub_strcmp
|
||||||
|
@ -94,63 +90,6 @@ iterate_device (const char *name, void *data)
|
||||||
}
|
}
|
||||||
grub_free (buf);
|
grub_free (buf);
|
||||||
}
|
}
|
||||||
#elif defined(DO_SEARCH_PART_UUID)
|
|
||||||
{
|
|
||||||
grub_device_t dev;
|
|
||||||
char *quid;
|
|
||||||
|
|
||||||
dev = grub_device_open (name);
|
|
||||||
if (dev)
|
|
||||||
{
|
|
||||||
if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
if (grub_strcasecmp (quid, ctx->key) == 0)
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
grub_free (quid);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_device_close (dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif defined(DO_SEARCH_PART_LABEL)
|
|
||||||
{
|
|
||||||
grub_device_t dev;
|
|
||||||
char *quid;
|
|
||||||
|
|
||||||
dev = grub_device_open (name);
|
|
||||||
if (dev)
|
|
||||||
{
|
|
||||||
if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
if (grub_strcmp (quid, ctx->key) == 0)
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
grub_free (quid);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_device_close (dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif defined(DO_SEARCH_DISK_UUID)
|
|
||||||
{
|
|
||||||
grub_device_t dev;
|
|
||||||
char *quid;
|
|
||||||
|
|
||||||
dev = grub_device_open (name);
|
|
||||||
if (dev)
|
|
||||||
{
|
|
||||||
if (grub_gpt_disk_uuid (dev, &quid) == GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
if (grub_strcmp (quid, ctx->key) == 0)
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
grub_free (quid);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_device_close (dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
/* SEARCH_FS_UUID or SEARCH_LABEL */
|
/* SEARCH_FS_UUID or SEARCH_LABEL */
|
||||||
|
@ -374,14 +313,8 @@ static grub_command_t cmd;
|
||||||
|
|
||||||
#ifdef DO_SEARCH_FILE
|
#ifdef DO_SEARCH_FILE
|
||||||
GRUB_MOD_INIT(search_fs_file)
|
GRUB_MOD_INIT(search_fs_file)
|
||||||
#elif defined(DO_SEARCH_PART_UUID)
|
|
||||||
GRUB_MOD_INIT(search_part_uuid)
|
|
||||||
#elif defined(DO_SEARCH_PART_LABEL)
|
|
||||||
GRUB_MOD_INIT(search_part_label)
|
|
||||||
#elif defined (DO_SEARCH_FS_UUID)
|
#elif defined (DO_SEARCH_FS_UUID)
|
||||||
GRUB_MOD_INIT(search_fs_uuid)
|
GRUB_MOD_INIT(search_fs_uuid)
|
||||||
#elif defined (DO_SEARCH_DISK_UUID)
|
|
||||||
GRUB_MOD_INIT(search_disk_uuid)
|
|
||||||
#else
|
#else
|
||||||
GRUB_MOD_INIT(search_label)
|
GRUB_MOD_INIT(search_label)
|
||||||
#endif
|
#endif
|
||||||
|
@ -394,14 +327,8 @@ GRUB_MOD_INIT(search_label)
|
||||||
|
|
||||||
#ifdef DO_SEARCH_FILE
|
#ifdef DO_SEARCH_FILE
|
||||||
GRUB_MOD_FINI(search_fs_file)
|
GRUB_MOD_FINI(search_fs_file)
|
||||||
#elif defined(DO_SEARCH_PART_UUID)
|
|
||||||
GRUB_MOD_FINI(search_part_uuid)
|
|
||||||
#elif defined(DO_SEARCH_PART_LABEL)
|
|
||||||
GRUB_MOD_FINI(search_part_label)
|
|
||||||
#elif defined (DO_SEARCH_FS_UUID)
|
#elif defined (DO_SEARCH_FS_UUID)
|
||||||
GRUB_MOD_FINI(search_fs_uuid)
|
GRUB_MOD_FINI(search_fs_uuid)
|
||||||
#elif defined (DO_SEARCH_DISK_UUID)
|
|
||||||
GRUB_MOD_FINI(search_disk_uuid)
|
|
||||||
#else
|
#else
|
||||||
GRUB_MOD_FINI(search_label)
|
GRUB_MOD_FINI(search_label)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#define DO_SEARCH_DISK_UUID 1
|
|
||||||
#define FUNC_NAME grub_search_disk_uuid
|
|
||||||
#define COMMAND_NAME "search.disk_uuid"
|
|
||||||
#define HELP_MESSAGE N_("Search devices by disk UUID. If VARIABLE is specified, the first device found is set to a variable.")
|
|
||||||
#include "search.c"
|
|
|
@ -1,5 +0,0 @@
|
||||||
#define DO_SEARCH_PART_LABEL 1
|
|
||||||
#define FUNC_NAME grub_search_part_label
|
|
||||||
#define COMMAND_NAME "search.part_label"
|
|
||||||
#define HELP_MESSAGE N_("Search devices by partition label. If VARIABLE is specified, the first device found is set to a variable.")
|
|
||||||
#include "search.c"
|
|
|
@ -1,5 +0,0 @@
|
||||||
#define DO_SEARCH_PART_UUID 1
|
|
||||||
#define FUNC_NAME grub_search_part_uuid
|
|
||||||
#define COMMAND_NAME "search.part_uuid"
|
|
||||||
#define HELP_MESSAGE N_("Search devices by partition UUID. If VARIABLE is specified, the first device found is set to a variable.")
|
|
||||||
#include "search.c"
|
|
|
@ -36,12 +36,6 @@ static const struct grub_arg_option options[] =
|
||||||
0, 0},
|
0, 0},
|
||||||
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
|
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
|
||||||
0, 0},
|
0, 0},
|
||||||
{"part-label", 'L', 0, N_("Search devices by a partition label."),
|
|
||||||
0, 0},
|
|
||||||
{"part-uuid", 'U', 0, N_("Search devices by a partition UUID."),
|
|
||||||
0, 0},
|
|
||||||
{"disk-uuid", 'U', 0, N_("Search devices by a disk UUID."),
|
|
||||||
0, 0},
|
|
||||||
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
|
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
|
||||||
N_("Set a variable to the first device found."), N_("VARNAME"),
|
N_("Set a variable to the first device found."), N_("VARNAME"),
|
||||||
ARG_TYPE_STRING},
|
ARG_TYPE_STRING},
|
||||||
|
@ -77,9 +71,6 @@ enum options
|
||||||
SEARCH_FILE,
|
SEARCH_FILE,
|
||||||
SEARCH_LABEL,
|
SEARCH_LABEL,
|
||||||
SEARCH_FS_UUID,
|
SEARCH_FS_UUID,
|
||||||
SEARCH_PART_LABEL,
|
|
||||||
SEARCH_PART_UUID,
|
|
||||||
SEARCH_DISK_UUID,
|
|
||||||
SEARCH_SET,
|
SEARCH_SET,
|
||||||
SEARCH_NO_FLOPPY,
|
SEARCH_NO_FLOPPY,
|
||||||
SEARCH_HINT,
|
SEARCH_HINT,
|
||||||
|
@ -131,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;
|
||||||
|
@ -195,15 +186,6 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||||
else if (state[SEARCH_FS_UUID].set)
|
else if (state[SEARCH_FS_UUID].set)
|
||||||
grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
|
grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
|
||||||
hints, nhints);
|
hints, nhints);
|
||||||
else if (state[SEARCH_PART_LABEL].set)
|
|
||||||
grub_search_part_label (id, var, state[SEARCH_NO_FLOPPY].set,
|
|
||||||
hints, nhints);
|
|
||||||
else if (state[SEARCH_PART_UUID].set)
|
|
||||||
grub_search_part_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
|
|
||||||
hints, nhints);
|
|
||||||
else if (state[SEARCH_DISK_UUID].set)
|
|
||||||
grub_search_disk_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
|
|
||||||
hints, nhints);
|
|
||||||
else if (state[SEARCH_FILE].set)
|
else if (state[SEARCH_FILE].set)
|
||||||
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
|
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
|
||||||
hints, nhints);
|
hints, nhints);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* smbios.c - retrieve smbios information. */
|
/* smbios.c - retrieve smbios information. */
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2013,2014,2015 Free Software Foundation, Inc.
|
* Copyright (C) 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
|
||||||
|
@ -27,86 +27,111 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
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. */
|
/* Locate the SMBIOS entry point structure depending on the hardware. */
|
||||||
struct grub_smbios_eps *
|
struct grub_smbios_eps *
|
||||||
grub_smbios_get_eps (void)
|
grub_smbios_get_eps (void)
|
||||||
{
|
{
|
||||||
static struct grub_smbios_eps *eps = NULL;
|
static struct grub_smbios_eps *eps = NULL;
|
||||||
|
|
||||||
if (eps != NULL)
|
if (eps != NULL)
|
||||||
return eps;
|
return eps;
|
||||||
|
|
||||||
eps = grub_machine_smbios_get_eps ();
|
eps = grub_machine_smbios_get_eps ();
|
||||||
|
|
||||||
return eps;
|
return eps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
|
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
|
||||||
struct grub_smbios_eps3 *
|
static struct grub_smbios_eps3 *
|
||||||
grub_smbios_get_eps3 (void)
|
grub_smbios_get_eps3 (void)
|
||||||
{
|
{
|
||||||
static struct grub_smbios_eps3 *eps = NULL;
|
static struct grub_smbios_eps3 *eps = NULL;
|
||||||
|
|
||||||
if (eps != NULL)
|
if (eps != NULL)
|
||||||
return eps;
|
return eps;
|
||||||
|
|
||||||
eps = grub_machine_smbios_get_eps3 ();
|
eps = grub_machine_smbios_get_eps3 ();
|
||||||
|
|
||||||
return eps;
|
return eps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
|
static char *
|
||||||
static struct {
|
linux_string (const char *value)
|
||||||
grub_addr_t start;
|
{
|
||||||
grub_addr_t end;
|
char *out = grub_malloc( grub_strlen (value) + 1);
|
||||||
grub_uint16_t structures;
|
const char *src = value;
|
||||||
} table_desc = {0, 0, 0};
|
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
|
* 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
|
* into a string formatted to be returned to the user. They expect that the
|
||||||
* structure and offset were already validated. The given buffer stores the
|
* structure and offset were already validated. When the requested data is
|
||||||
* newly formatted string if needed. When the requested data is successfully
|
* successfully retrieved and formatted, the pointer to the string is returned;
|
||||||
* retrieved and formatted, the pointer to the string is returned; otherwise,
|
* otherwise, NULL is returned on failure. Don't free the result.
|
||||||
* NULL is returned on failure.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
grub_smbios_format_byte (char *buffer, grub_size_t size,
|
grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
|
||||||
{
|
{
|
||||||
grub_snprintf (buffer, size, "%u", structure[offset]);
|
static char buffer[sizeof ("255")];
|
||||||
|
|
||||||
|
grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]);
|
||||||
|
|
||||||
return (const char *)buffer;
|
return (const char *)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
grub_smbios_format_word (char *buffer, grub_size_t size,
|
grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
|
||||||
{
|
{
|
||||||
|
static char buffer[sizeof ("65535")];
|
||||||
|
|
||||||
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
|
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
|
||||||
grub_snprintf (buffer, size, "%u", value);
|
grub_snprintf (buffer, sizeof (buffer), "%u", value);
|
||||||
|
|
||||||
return (const char *)buffer;
|
return (const char *)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
grub_smbios_format_dword (char *buffer, grub_size_t size,
|
grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
|
||||||
{
|
{
|
||||||
|
static char buffer[sizeof ("4294967295")];
|
||||||
|
|
||||||
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
|
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
|
||||||
grub_snprintf (buffer, size, "%" PRIuGRUB_UINT32_T, value);
|
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value);
|
||||||
|
|
||||||
return (const char *)buffer;
|
return (const char *)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
grub_smbios_format_qword (char *buffer, grub_size_t size,
|
grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
|
||||||
{
|
{
|
||||||
|
static char buffer[sizeof ("18446744073709551615")];
|
||||||
|
|
||||||
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
|
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
|
||||||
grub_snprintf (buffer, size, "%" PRIuGRUB_UINT64_T, value);
|
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value);
|
||||||
|
|
||||||
return (const char *)buffer;
|
return (const char *)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The matching string pointer is returned directly to avoid extra copying. */
|
|
||||||
static const char *
|
static const char *
|
||||||
grub_smbios_get_string (char *buffer __attribute__ ((unused)),
|
grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
grub_size_t size __attribute__ ((unused)),
|
|
||||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
|
||||||
{
|
{
|
||||||
const grub_uint8_t *ptr = structure + structure[1];
|
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 *table_end = (const grub_uint8_t *)table_desc.end;
|
||||||
|
@ -135,25 +160,24 @@ grub_smbios_get_string (char *buffer __attribute__ ((unused)),
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
grub_smbios_format_uuid (char *buffer, grub_size_t size,
|
grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||||
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 *f = structure + offset; /* little-endian fields */
|
||||||
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
|
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
|
||||||
grub_snprintf (buffer, size,
|
|
||||||
|
grub_snprintf (buffer, sizeof (buffer),
|
||||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||||
"%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],
|
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]);
|
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
|
||||||
|
|
||||||
return (const char *)buffer;
|
return (const char *)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* List the field formatting functions and the number of bytes they need. */
|
/* List the field formatting functions and the number of bytes they need. */
|
||||||
#define MAXIMUM_FORMAT_LENGTH (sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff"))
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *(*format) (char *buffer, grub_size_t size,
|
const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset);
|
||||||
const grub_uint8_t *structure, grub_uint8_t offset);
|
|
||||||
grub_uint8_t field_length;
|
grub_uint8_t field_length;
|
||||||
} field_extractors[] = {
|
} field_extractors[] = {
|
||||||
{grub_smbios_format_byte, 1},
|
{grub_smbios_format_byte, 1},
|
||||||
|
@ -167,10 +191,12 @@ static const struct {
|
||||||
/* List command options, with structure field getters ordered as above. */
|
/* List command options, with structure field getters ordered as above. */
|
||||||
#define FIRST_GETTER_OPT (3)
|
#define FIRST_GETTER_OPT (3)
|
||||||
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
|
#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[] = {
|
static const struct grub_arg_option options[] = {
|
||||||
{"type", 't', 0, N_("Match entries with the given type."),
|
{"type", 't', 0, N_("Match structures with the given type."),
|
||||||
N_("type"), ARG_TYPE_INT},
|
N_("type"), ARG_TYPE_INT},
|
||||||
{"handle", 'h', 0, N_("Match entries with the given handle."),
|
{"handle", 'h', 0, N_("Match structures with the given handle."),
|
||||||
N_("handle"), ARG_TYPE_INT},
|
N_("handle"), ARG_TYPE_INT},
|
||||||
{"match", 'm', 0, N_("Select a structure when several match."),
|
{"match", 'm', 0, N_("Select a structure when several match."),
|
||||||
N_("match"), ARG_TYPE_INT},
|
N_("match"), ARG_TYPE_INT},
|
||||||
|
@ -188,10 +214,11 @@ static const struct grub_arg_option options[] = {
|
||||||
N_("offset"), ARG_TYPE_INT},
|
N_("offset"), ARG_TYPE_INT},
|
||||||
{"set", '\0', 0, N_("Store the value in the given variable name."),
|
{"set", '\0', 0, N_("Store the value in the given variable name."),
|
||||||
N_("variable"), ARG_TYPE_STRING},
|
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}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a matching SMBIOS structure.
|
* Return a matching SMBIOS structure.
|
||||||
*
|
*
|
||||||
|
@ -225,7 +252,6 @@ grub_smbios_match_structure (const grub_int16_t type,
|
||||||
&& (type < 0 || type == structure_type)
|
&& (type < 0 || type == structure_type)
|
||||||
&& (match == 0 || match == ++matches))
|
&& (match == 0 || match == ++matches))
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ptr += ptr[1];
|
ptr += ptr[1];
|
||||||
|
@ -239,7 +265,6 @@ grub_smbios_match_structure (const grub_int16_t type,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||||
int argc __attribute__ ((unused)),
|
int argc __attribute__ ((unused)),
|
||||||
|
@ -254,7 +279,7 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||||
|
|
||||||
const grub_uint8_t *structure;
|
const grub_uint8_t *structure;
|
||||||
const char *value;
|
const char *value;
|
||||||
char buffer[MAXIMUM_FORMAT_LENGTH];
|
char *modified_value = NULL;
|
||||||
grub_int32_t option;
|
grub_int32_t option;
|
||||||
grub_int8_t field_type = -1;
|
grub_int8_t field_type = -1;
|
||||||
grub_uint8_t i;
|
grub_uint8_t i;
|
||||||
|
@ -283,7 +308,7 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||||
if (state[2].set)
|
if (state[2].set)
|
||||||
{
|
{
|
||||||
option = grub_strtol (state[2].arg, NULL, 0);
|
option = grub_strtol (state[2].arg, NULL, 0);
|
||||||
if (option <= 0)
|
if (option <= 0 || option > 65535)
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
N_("the match must be a positive integer"));
|
N_("the match must be a positive integer"));
|
||||||
match = (grub_uint16_t)option;
|
match = (grub_uint16_t)option;
|
||||||
|
@ -323,24 +348,25 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||||
N_("the field ends outside the structure"));
|
N_("the field ends outside the structure"));
|
||||||
|
|
||||||
/* Format the requested structure field into a readable string. */
|
/* Format the requested structure field into a readable string. */
|
||||||
value = field_extractors[field_type].format (buffer, sizeof (buffer),
|
value = field_extractors[field_type].format (structure, offset);
|
||||||
structure, offset);
|
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
return grub_error (GRUB_ERR_IO,
|
return grub_error (GRUB_ERR_IO,
|
||||||
N_("failed to retrieve the structure field"));
|
N_("failed to retrieve the structure field"));
|
||||||
|
|
||||||
|
if (state[LINUX_OPT].set)
|
||||||
|
value = modified_value = linux_string (value);
|
||||||
|
|
||||||
/* Store or print the formatted value. */
|
/* Store or print the formatted value. */
|
||||||
if (state[SETTER_OPT].set)
|
if (state[SETTER_OPT].set)
|
||||||
grub_env_set (state[SETTER_OPT].arg, value);
|
grub_env_set (state[SETTER_OPT].arg, value);
|
||||||
else
|
else
|
||||||
grub_printf ("%s\n", value);
|
grub_printf ("%s\n", value);
|
||||||
|
|
||||||
|
grub_free(modified_value);
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static grub_extcmd_t cmd;
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(smbios)
|
GRUB_MOD_INIT(smbios)
|
||||||
{
|
{
|
||||||
struct grub_smbios_eps3 *eps3;
|
struct grub_smbios_eps3 *eps3;
|
||||||
|
|
|
@ -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) ||
|
||||||
if (! t)
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
t = grub_realloc (ctx->files, sz);
|
||||||
|
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);
|
||||||
|
|
|
@ -278,14 +278,10 @@ grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
||||||
char name[10];
|
char name[10];
|
||||||
|
|
||||||
if (cd_drive && drive == cd_drive)
|
if (cd_drive && drive == cd_drive)
|
||||||
{
|
|
||||||
grub_dprintf ("biosdisk", "iterating cd\n");
|
|
||||||
return hook ("cd", hook_data);
|
return hook ("cd", hook_data);
|
||||||
}
|
|
||||||
|
|
||||||
grub_snprintf (name, sizeof (name),
|
grub_snprintf (name, sizeof (name),
|
||||||
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
|
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
|
||||||
grub_dprintf ("biosdisk", "iterating %s\n", name);
|
|
||||||
return hook (name, hook_data);
|
return hook (name, hook_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +301,7 @@ grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
||||||
if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
|
if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
|
||||||
GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
|
GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
|
||||||
{
|
{
|
||||||
grub_dprintf ("biosdisk", "Read error when probing drive 0x%2x\n", drive);
|
grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,8 +336,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
int drive;
|
int drive;
|
||||||
struct grub_biosdisk_data *data;
|
struct grub_biosdisk_data *data;
|
||||||
|
|
||||||
grub_dprintf ("biosdisk", "opening %s\n", name);
|
|
||||||
|
|
||||||
drive = grub_biosdisk_get_drive (name);
|
drive = grub_biosdisk_get_drive (name);
|
||||||
if (drive < 0)
|
if (drive < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -399,11 +393,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
(1 << disk->log_sector_size) < drp->bytes_per_sector;
|
(1 << disk->log_sector_size) < drp->bytes_per_sector;
|
||||||
disk->log_sector_size++);
|
disk->log_sector_size++);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_dprintf ("biosdisk",
|
|
||||||
"LBA total = 0x%llx block size = 0x%lx\n",
|
|
||||||
(unsigned long long) total_sectors,
|
|
||||||
1L << disk->log_sector_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,9 +428,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
if (! total_sectors)
|
if (! total_sectors)
|
||||||
total_sectors = ((grub_uint64_t) data->cylinders)
|
total_sectors = ((grub_uint64_t) data->cylinders)
|
||||||
* data->heads * data->sectors;
|
* data->heads * data->sectors;
|
||||||
|
|
||||||
grub_dprintf ("biosdisk", "C/H/S %lu/%lu/%lu\n",
|
|
||||||
data->cylinders, data->heads, data->sectors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disk->total_sectors = total_sectors;
|
disk->total_sectors = total_sectors;
|
||||||
|
@ -454,15 +440,12 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
||||||
|
|
||||||
disk->data = data;
|
disk->data = data;
|
||||||
|
|
||||||
grub_dprintf ("biosdisk", "opening %s succeeded\n", name);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_biosdisk_close (grub_disk_t disk)
|
grub_biosdisk_close (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
grub_dprintf ("biosdisk", "closing %s\n", disk->name);
|
|
||||||
grub_free (disk->data);
|
grub_free (disk->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,9 +577,6 @@ static grub_err_t
|
||||||
grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
grub_size_t size, char *buf)
|
grub_size_t size, char *buf)
|
||||||
{
|
{
|
||||||
grub_dprintf ("biosdisk", "reading 0x%lx sectors at 0x%llx from %s\n",
|
|
||||||
(unsigned long) size, (unsigned long long) sector, disk->name);
|
|
||||||
|
|
||||||
while (size)
|
while (size)
|
||||||
{
|
{
|
||||||
grub_size_t len;
|
grub_size_t len;
|
||||||
|
@ -627,9 +607,6 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
{
|
{
|
||||||
struct grub_biosdisk_data *data = disk->data;
|
struct grub_biosdisk_data *data = disk->data;
|
||||||
|
|
||||||
grub_dprintf ("biosdisk", "writing 0x%lx sectors at 0x%llx to %s\n",
|
|
||||||
(unsigned long) size, (unsigned long long) sector, disk->name);
|
|
||||||
|
|
||||||
if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
|
if (data->flags & GRUB_BIOSDISK_FLAG_CDROM)
|
||||||
return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
|
return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM"));
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -30,14 +30,10 @@ grub_machine_efiemu_init_tables (void)
|
||||||
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;
|
||||||
grub_efi_guid_t smbios3 = GRUB_EFI_SMBIOS3_TABLE_GUID;
|
|
||||||
grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
|
grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
|
||||||
grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID;
|
grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID;
|
||||||
|
|
||||||
err = grub_efiemu_unregister_configuration_table (smbios);
|
err = grub_efiemu_unregister_configuration_table (smbios);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
err = grub_efiemu_unregister_configuration_table (smbios3);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
err = grub_efiemu_unregister_configuration_table (acpi);
|
err = grub_efiemu_unregister_configuration_table (acpi);
|
||||||
|
@ -47,20 +43,6 @@ grub_machine_efiemu_init_tables (void)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
table = grub_smbios_get_eps ();
|
|
||||||
if (table)
|
|
||||||
{
|
|
||||||
err = grub_efiemu_register_configuration_table (smbios, 0, 0, table);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
table = grub_smbios_get_eps3 ();
|
|
||||||
if (table)
|
|
||||||
{
|
|
||||||
err = grub_efiemu_register_configuration_table (smbios3, 0, 0, table);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
table = grub_acpi_get_rsdpv1 ();
|
table = grub_acpi_get_rsdpv1 ();
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
|
@ -75,6 +57,13 @@ grub_machine_efiemu_init_tables (void)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
table = grub_smbios_get_eps ();
|
||||||
|
if (table)
|
||||||
|
{
|
||||||
|
err = grub_efiemu_register_configuration_table (smbios, 0, 0, table);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,21 +32,12 @@
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
#include <grub/cache.h>
|
#include <grub/cache.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/tpm.h>
|
|
||||||
|
|
||||||
/* Platforms where modules are in a readonly area of memory. */
|
/* Platforms where modules are in a readonly area of memory. */
|
||||||
#if defined(GRUB_MACHINE_QEMU)
|
#if defined(GRUB_MACHINE_QEMU)
|
||||||
#define GRUB_MODULES_MACHINE_READONLY
|
#define GRUB_MODULES_MACHINE_READONLY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EMU
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
|
||||||
#include <grub/efi/efi.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||||
|
@ -695,15 +686,6 @@ grub_dl_load_file (const char *filename)
|
||||||
void *core = 0;
|
void *core = 0;
|
||||||
grub_dl_t mod = 0;
|
grub_dl_t mod = 0;
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
|
||||||
if (grub_efi_secure_boot ())
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_ACCESS_DENIED,
|
|
||||||
"Secure Boot forbids loading module from %s", filename);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
grub_boot_time ("Loading module %s", filename);
|
grub_boot_time ("Loading module %s", filename);
|
||||||
|
|
||||||
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
|
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
|
||||||
|
@ -730,9 +712,6 @@ grub_dl_load_file (const char *filename)
|
||||||
opens of the same device. */
|
opens of the same device. */
|
||||||
grub_file_close (file);
|
grub_file_close (file);
|
||||||
|
|
||||||
grub_tpm_measure(core, size, GRUB_BINARY_PCR, filename);
|
|
||||||
grub_print_error();
|
|
||||||
|
|
||||||
mod = grub_dl_load_core (core, size);
|
mod = grub_dl_load_core (core, size);
|
||||||
grub_free (core);
|
grub_free (core);
|
||||||
if (! mod)
|
if (! mod)
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -273,34 +274,6 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_efi_boolean_t
|
|
||||||
grub_efi_secure_boot (void)
|
|
||||||
{
|
|
||||||
grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
|
||||||
grub_size_t datasize;
|
|
||||||
char *secure_boot = NULL;
|
|
||||||
char *setup_mode = NULL;
|
|
||||||
grub_efi_boolean_t ret = 0;
|
|
||||||
|
|
||||||
secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
|
|
||||||
|
|
||||||
if (datasize != 1 || !secure_boot)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
|
|
||||||
|
|
||||||
if (datasize != 1 || !setup_mode)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (*secure_boot && !*setup_mode)
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
grub_free (secure_boot);
|
|
||||||
grub_free (setup_mode);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||||
|
|
||||||
/* Search the mods section from the PE32/PE32+ image. This code uses
|
/* Search the mods section from the PE32/PE32+ image. This code uses
|
||||||
|
@ -336,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,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);
|
||||||
|
@ -370,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,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);
|
||||||
|
@ -404,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);
|
||||||
|
@ -480,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;
|
||||||
}
|
}
|
||||||
|
@ -525,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);
|
||||||
|
@ -937,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;
|
||||||
|
@ -973,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 ();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,38 +49,6 @@ static grub_efi_uintn_t finish_desc_size;
|
||||||
static grub_efi_uint32_t finish_desc_version;
|
static grub_efi_uint32_t finish_desc_version;
|
||||||
int grub_efi_is_finished = 0;
|
int grub_efi_is_finished = 0;
|
||||||
|
|
||||||
/* Allocate pages below a specified address */
|
|
||||||
void *
|
|
||||||
grub_efi_allocate_pages_max (grub_efi_physical_address_t max,
|
|
||||||
grub_efi_uintn_t pages)
|
|
||||||
{
|
|
||||||
grub_efi_status_t status;
|
|
||||||
grub_efi_boot_services_t *b;
|
|
||||||
grub_efi_physical_address_t address = max;
|
|
||||||
|
|
||||||
if (max > 0xffffffff)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
b = grub_efi_system_table->boot_services;
|
|
||||||
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
|
|
||||||
|
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (address == 0)
|
|
||||||
{
|
|
||||||
/* Uggh, the address 0 was allocated... This is too annoying,
|
|
||||||
so reallocate another one. */
|
|
||||||
address = max;
|
|
||||||
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address);
|
|
||||||
grub_efi_free_pages (0, pages);
|
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (void *) ((grub_addr_t) address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to roll back EFI allocations on exit. Remember allocations that
|
* We need to roll back EFI allocations on exit. Remember allocations that
|
||||||
* we'll free on exit.
|
* we'll free on exit.
|
||||||
|
@ -157,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)
|
||||||
{
|
{
|
||||||
|
@ -172,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);
|
||||||
|
|
|
@ -1,273 +0,0 @@
|
||||||
#include <grub/err.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/efi/api.h>
|
|
||||||
#include <grub/efi/efi.h>
|
|
||||||
#include <grub/efi/tpm.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/tpm.h>
|
|
||||||
#include <grub/term.h>
|
|
||||||
|
|
||||||
static grub_efi_guid_t tpm_guid = EFI_TPM_GUID;
|
|
||||||
static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID;
|
|
||||||
|
|
||||||
static grub_efi_boolean_t grub_tpm_present(grub_efi_tpm_protocol_t *tpm)
|
|
||||||
{
|
|
||||||
grub_efi_status_t status;
|
|
||||||
TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
|
|
||||||
grub_uint32_t flags;
|
|
||||||
grub_efi_physical_address_t eventlog, lastevent;
|
|
||||||
|
|
||||||
caps.Size = (grub_uint8_t)sizeof(caps);
|
|
||||||
|
|
||||||
status = efi_call_5(tpm->status_check, tpm, &caps, &flags, &eventlog,
|
|
||||||
&lastevent);
|
|
||||||
|
|
||||||
if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag
|
|
||||||
|| !caps.TPMPresentFlag)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_efi_boolean_t grub_tpm2_present(grub_efi_tpm2_protocol_t *tpm)
|
|
||||||
{
|
|
||||||
grub_efi_status_t status;
|
|
||||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
|
|
||||||
|
|
||||||
caps.Size = (grub_uint8_t)sizeof(caps);
|
|
||||||
|
|
||||||
status = efi_call_2(tpm->get_capability, tpm, &caps);
|
|
||||||
|
|
||||||
if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_efi_boolean_t grub_tpm_handle_find(grub_efi_handle_t *tpm_handle,
|
|
||||||
grub_efi_uint8_t *protocol_version)
|
|
||||||
{
|
|
||||||
grub_efi_handle_t *handles;
|
|
||||||
grub_efi_uintn_t num_handles;
|
|
||||||
|
|
||||||
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL,
|
|
||||||
&num_handles);
|
|
||||||
if (handles && num_handles > 0) {
|
|
||||||
*tpm_handle = handles[0];
|
|
||||||
*protocol_version = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
|
|
||||||
&num_handles);
|
|
||||||
if (handles && num_handles > 0) {
|
|
||||||
*tpm_handle = handles[0];
|
|
||||||
*protocol_version = 2;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_tpm_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;
|
|
||||||
|
|
||||||
/* It's not a hard failure for there to be no TPM */
|
|
||||||
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
|
|
||||||
grub_tpm1_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf,
|
|
||||||
grub_size_t size, grub_uint8_t pcr,
|
|
||||||
const char *description)
|
|
||||||
{
|
|
||||||
TCG_PCR_EVENT *event;
|
|
||||||
grub_efi_status_t status;
|
|
||||||
grub_efi_tpm_protocol_t *tpm;
|
|
||||||
grub_efi_physical_address_t lastevent;
|
|
||||||
grub_uint32_t algorithm;
|
|
||||||
grub_uint32_t eventnum = 0;
|
|
||||||
|
|
||||||
tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
||||||
|
|
||||||
if (!grub_tpm_present(tpm))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
event = grub_zalloc(sizeof (TCG_PCR_EVENT) + grub_strlen(description) + 1);
|
|
||||||
if (!event)
|
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
||||||
N_("cannot allocate TPM event buffer"));
|
|
||||||
|
|
||||||
event->PCRIndex = pcr;
|
|
||||||
event->EventType = EV_IPL;
|
|
||||||
event->EventSize = grub_strlen(description) + 1;
|
|
||||||
grub_memcpy(event->Event, description, event->EventSize);
|
|
||||||
|
|
||||||
algorithm = TCG_ALG_SHA;
|
|
||||||
status = efi_call_7 (tpm->log_extend_event, tpm, (grub_efi_physical_address_t)buf, (grub_uint64_t) size,
|
|
||||||
algorithm, event, &eventnum, &lastevent);
|
|
||||||
|
|
||||||
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_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf,
|
|
||||||
grub_size_t size, grub_uint8_t pcr,
|
|
||||||
const char *description)
|
|
||||||
{
|
|
||||||
EFI_TCG2_EVENT *event;
|
|
||||||
grub_efi_status_t status;
|
|
||||||
grub_efi_tpm2_protocol_t *tpm;
|
|
||||||
|
|
||||||
tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
|
||||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
||||||
|
|
||||||
if (!grub_tpm2_present(tpm))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
event = grub_zalloc(sizeof (EFI_TCG2_EVENT) + grub_strlen(description) + 1);
|
|
||||||
if (!event)
|
|
||||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
||||||
N_("cannot allocate TPM event buffer"));
|
|
||||||
|
|
||||||
event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
|
|
||||||
event->Header.HeaderVersion = 1;
|
|
||||||
event->Header.PCRIndex = pcr;
|
|
||||||
event->Header.EventType = EV_IPL;
|
|
||||||
event->Size = sizeof(*event) - sizeof(event->Event) + grub_strlen(description) + 1;
|
|
||||||
grub_memcpy(event->Event, description, grub_strlen(description) + 1);
|
|
||||||
|
|
||||||
status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_efi_physical_address_t)buf,
|
|
||||||
(grub_uint64_t) size, event);
|
|
||||||
|
|
||||||
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_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
|
||||||
const char *description)
|
|
||||||
{
|
|
||||||
grub_efi_handle_t tpm_handle;
|
|
||||||
grub_efi_uint8_t protocol_version;
|
|
||||||
|
|
||||||
if (!grub_tpm_handle_find(&tpm_handle, &protocol_version))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (protocol_version == 1) {
|
|
||||||
return grub_tpm1_log_event(tpm_handle, buf, size, pcr, description);
|
|
||||||
} else {
|
|
||||||
return grub_tpm2_log_event(tpm_handle, buf, size, pcr, description);
|
|
||||||
}
|
|
||||||
}
|
|
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