Compare commits
1 Commits
master
...
coreos-one
Author | SHA1 | Date |
---|---|---|
Vincent Batts | 1b24dcf433 |
|
@ -1 +0,0 @@
|
|||
po/exclude.pot binary
|
|
@ -1,277 +1,238 @@
|
|||
#
|
||||
# Ignore patterns in this directory and all subdirectories.
|
||||
#
|
||||
*~
|
||||
00_header
|
||||
10_*
|
||||
20_linux_xen
|
||||
30_os-prober
|
||||
40_custom
|
||||
41_custom
|
||||
*.1
|
||||
*.8
|
||||
*.a
|
||||
ABOUT-NLS
|
||||
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.exe
|
||||
*.image
|
||||
*.image.exe
|
||||
*.img
|
||||
*.log
|
||||
*.lst
|
||||
*.marker
|
||||
*.mod
|
||||
*.o
|
||||
*.pf2
|
||||
*.pp
|
||||
*.trs
|
||||
*~
|
||||
.deps-core/
|
||||
.deps-util/
|
||||
.deps/
|
||||
.dirstamp
|
||||
DISTLIST
|
||||
GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
Makefile
|
||||
Makefile.in
|
||||
ascii.bitmaps
|
||||
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-lite.exe
|
||||
grub-emu.exe
|
||||
grub-macho2img
|
||||
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_script_check_init.c
|
||||
grub_script_check_init.h
|
||||
grub-set-default
|
||||
grub_setup_init.c
|
||||
grub_setup_init.h
|
||||
mdate-sh
|
||||
mod-*.c
|
||||
update-grub_lib
|
||||
widthspec.bin
|
||||
|
||||
#
|
||||
# Ignore patterns relative to this .gitignore file's directory.
|
||||
#
|
||||
/00_header
|
||||
/10_*
|
||||
/20_linux_xen
|
||||
/30_os-prober
|
||||
/30_uefi-firmware
|
||||
/40_custom
|
||||
/41_custom
|
||||
/ABOUT-NLS
|
||||
/ChangeLog
|
||||
/INSTALL.grub
|
||||
/Makefile.util.am
|
||||
/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.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-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-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
|
||||
gzcompress_test
|
||||
hddboot_test
|
||||
help_test
|
||||
*.img
|
||||
*.image
|
||||
*.image.exe
|
||||
include/grub/cpu
|
||||
include/grub/machine
|
||||
INSTALL.grub
|
||||
install-sh
|
||||
lib/libgcrypt-grub
|
||||
libgrub_a_init.c
|
||||
*.log
|
||||
*.lst
|
||||
lzocompress_test
|
||||
*.marker
|
||||
Makefile
|
||||
/m4
|
||||
*.mod
|
||||
mod-*.c
|
||||
missing
|
||||
netboot_test
|
||||
*.o
|
||||
*.a
|
||||
ohci_test
|
||||
partmap_test
|
||||
pata_test
|
||||
*.pf2
|
||||
*.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
|
||||
uhci_test
|
||||
update-grub_lib
|
||||
unidata.c
|
||||
xzcompress_test
|
||||
Makefile.in
|
||||
GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
compile
|
||||
depcomp
|
||||
mdate-sh
|
||||
texinfo.tex
|
||||
grub-core/lib/libgcrypt-grub
|
||||
.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.h
|
||||
docs/stamp-1
|
||||
docs/version-dev.texi
|
||||
Makefile.utilgcry.def
|
||||
po/*.po
|
||||
po/*.gmo
|
||||
po/LINGUAS
|
||||
po/remove-potcdate.sed
|
||||
include/grub/gcrypt/gcrypt.h
|
||||
include/grub/gcrypt/g10lib.h
|
||||
po/POTFILES.in
|
||||
po/POTFILES-shell.in
|
||||
/grub-glue-efi
|
||||
/grub-render-label
|
||||
/grub-glue-efi.exe
|
||||
/grub-render-label.exe
|
||||
/garbage-gen
|
||||
/garbage-gen.exe
|
||||
/grub-fs-tester
|
||||
grub-core/build-grub-module-verifier
|
||||
|
|
|
@ -12,7 +12,6 @@ language: c
|
|||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- autopoint
|
||||
- libsdl1.2-dev
|
||||
- lzop
|
||||
- ovmf
|
||||
|
@ -36,7 +35,7 @@ before_script:
|
|||
script:
|
||||
# Comments must be outside the command strings below, or the Travis parser
|
||||
# will get confused.
|
||||
- ./bootstrap
|
||||
- ./autogen.sh
|
||||
|
||||
# Build all selected GRUB targets.
|
||||
- for target in $GRUB_TARGETS; do
|
||||
|
|
69
INSTALL
69
INSTALL
|
@ -11,9 +11,27 @@ GRUB depends on some software packages installed into your system. If
|
|||
you don't have any of them, please obtain and install them before
|
||||
configuring the GRUB.
|
||||
|
||||
* GCC 5.1.0 or later
|
||||
Experimental support for clang 3.8.0 or later (results in much bigger binaries)
|
||||
* GCC 4.1.3 or later
|
||||
Note: older versions may work but support is limited
|
||||
|
||||
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
|
||||
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 Bison 2.3 or later
|
||||
* GNU gettext 0.17 or later
|
||||
|
@ -142,20 +160,12 @@ For this example the configure line might look like (more details below)
|
|||
(some options are optional and included here for completeness but some rarely
|
||||
used options are omitted):
|
||||
|
||||
./configure --host=x86_64-linux-gnu --target=arm-linux-gnueabihf \
|
||||
--with-platform=efi BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config \
|
||||
HOST_CC=x86_64-linux-gnu-gcc HOST_CFLAGS='-g -O2' \
|
||||
PKG_CONFIG=x86_64-linux-gnu-pkg-config TARGET_CC=arm-linux-gnueabihf-gcc \
|
||||
TARGET_CFLAGS='-Os -march=armv8.3-a' TARGET_CCASFLAGS='-march=armv8.3-a' \
|
||||
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
|
||||
./configure BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config --host=amd64-linux-gnu
|
||||
CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" PKG_CONFIG=amd64-linux-gnu-pkg-config
|
||||
--target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc
|
||||
TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6"
|
||||
TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip"
|
||||
TARGET_NM=arm-elf-nm TARGET_RANLIB=arm-elf-ranlib LEX=gflex
|
||||
|
||||
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
|
||||
|
@ -172,23 +182,20 @@ corresponding platform are not needed for the platform in question.
|
|||
|
||||
- For host
|
||||
1. --host= to autoconf name of host.
|
||||
2. CC= for gcc able to compile for host.
|
||||
3. CFLAGS= for C options for host.
|
||||
4. HOST_CC= for gcc able to compile for host.
|
||||
5. HOST_CFLAGS= for C options for host.
|
||||
6. HOST_CPPFLAGS= for C preprocessor options for host.
|
||||
7. HOST_LDFLAGS= for linker options for host.
|
||||
8. PKG_CONFIG= for pkg-config for host (optional).
|
||||
9. Libdevmapper if any must be in standard linker folders (-ldevmapper) (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.
|
||||
2. CC= for gcc able to compile for host
|
||||
3. HOST_CFLAGS= for C options for host.
|
||||
4. HOST_CPPFLAGS= for C preprocessor options for host.
|
||||
5. HOST_LDFLAGS= for linker options for host.
|
||||
6. PKG_CONFIG= for pkg-config for host (optional).
|
||||
7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional).
|
||||
8. Libfuse if any must be in standard linker folders (-lfuse) (optional).
|
||||
9. Libzfs if any must be in standard linker folders (-lzfs) (optional).
|
||||
10. Liblzma if any must be in standard linker folders (-llzma) (optional).
|
||||
|
||||
- For target
|
||||
1. --target= to autoconf cpu name of target.
|
||||
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.
|
||||
5. TARGET_CPPFLAGS= for C preprocessor options for target.
|
||||
6. TARGET_CCASFLAGS= for assembler options for target.
|
||||
|
@ -197,10 +204,6 @@ corresponding platform are not needed for the platform in question.
|
|||
9. TARGET_STRIP= for strip for target.
|
||||
10. TARGET_NM= for nm 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.
|
||||
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
|
||||
|
||||
# For libgrub.a
|
||||
libgrub.pp: config-util.h grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES)
|
||||
libgrub.pp: 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) \
|
||||
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libgrub.pp
|
||||
|
|
|
@ -3,7 +3,7 @@ AutoGen definitions Makefile.tpl;
|
|||
library = {
|
||||
name = libgrubkern.a;
|
||||
cflags = '$(CFLAGS_GNULIB)';
|
||||
cppflags = '$(CPPFLAGS_GNULIB) -I$(srcdir)/grub-core/lib/json';
|
||||
cppflags = '$(CPPFLAGS_GNULIB)';
|
||||
|
||||
common = util/misc.c;
|
||||
common = grub-core/kern/command.c;
|
||||
|
@ -36,9 +36,7 @@ library = {
|
|||
common = grub-core/kern/misc.c;
|
||||
common = grub-core/kern/partition.c;
|
||||
common = grub-core/lib/crypto.c;
|
||||
common = grub-core/lib/json/json.c;
|
||||
common = grub-core/disk/luks.c;
|
||||
common = grub-core/disk/luks2.c;
|
||||
common = grub-core/disk/geli.c;
|
||||
common = grub-core/disk/cryptodisk.c;
|
||||
common = grub-core/disk/AFSplitter.c;
|
||||
|
@ -141,7 +139,7 @@ library = {
|
|||
common = grub-core/lib/crc.c;
|
||||
common = grub-core/lib/adler32.c;
|
||||
common = grub-core/lib/crc64.c;
|
||||
common = grub-core/lib/datetime.c;
|
||||
common = grub-core/normal/datetime.c;
|
||||
common = grub-core/normal/misc.c;
|
||||
common = grub-core/partmap/acorn.c;
|
||||
common = grub-core/partmap/amiga.c;
|
||||
|
@ -242,19 +240,8 @@ program = {
|
|||
|
||||
common = util/grub-editenv.c;
|
||||
common = util/editenv.c;
|
||||
common = util/grub-install-common.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 = libgrubgcry.a;
|
||||
ldadd = libgrubkern.a;
|
||||
|
@ -515,12 +502,6 @@ script = {
|
|||
installdir = grubconf;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = '30_uefi-firmware';
|
||||
common = util/grub.d/30_uefi-firmware.in;
|
||||
installdir = grubconf;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = '40_custom';
|
||||
common = util/grub.d/40_custom.in;
|
||||
|
@ -1194,6 +1175,18 @@ script = {
|
|||
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 = {
|
||||
testcase;
|
||||
name = file_filter_test;
|
||||
|
@ -1289,6 +1282,25 @@ program = {
|
|||
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 = {
|
||||
name = grub-menulst2cfg;
|
||||
mansection = 1;
|
||||
|
|
|
@ -13,7 +13,7 @@ fi
|
|||
export LC_COLLATE=C
|
||||
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/*' ! -ipath './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/*' ! -iname './grub-core/lib/gnulib/*' |sort > po/POTFILES.in
|
||||
find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in
|
||||
|
||||
echo "Importing unicode..."
|
||||
|
|
|
@ -23,7 +23,6 @@ GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263
|
|||
# directly.
|
||||
gnulib_modules="
|
||||
argp
|
||||
base64
|
||||
error
|
||||
fnmatch
|
||||
getdelim
|
||||
|
@ -79,18 +78,10 @@ cp -a INSTALL INSTALL.grub
|
|||
|
||||
bootstrap_post_import_hook () {
|
||||
set -e
|
||||
for patchname in fix-base64 fix-null-deref fix-width no-abort; do
|
||||
for patchname in fix-null-deref fix-width no-abort; do
|
||||
patch -d grub-core/lib/gnulib -p2 \
|
||||
< "grub-core/lib/gnulib-patches/$patchname.patch"
|
||||
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
|
||||
set +e # bootstrap expects this
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ EXTRA_DIST += grub-core/gensymlist.sh
|
|||
EXTRA_DIST += grub-core/genemuinit.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-width.patch
|
||||
EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch
|
||||
|
@ -111,21 +110,6 @@ EXTRA_DIST += grub-core/osdep/windows/password.c
|
|||
EXTRA_DIST += grub-core/osdep/windows/random.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.dfly.img.gz
|
||||
|
||||
|
|
87
configure.ac
87
configure.ac
|
@ -26,15 +26,12 @@ dnl This is necessary because the target type in autoconf does not
|
|||
dnl describe such a system very well.
|
||||
dnl
|
||||
dnl The current strategy is to use variables with no prefix (such as
|
||||
dnl CC, CFLAGS, etc.) for the host and target type, variables with
|
||||
dnl prefix "BUILD_" (such as BUILD_CC, BUILD_CFLAGS, etc.) for the
|
||||
dnl build type, variables with prefix "HOST_" (such as HOST_CC,
|
||||
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.
|
||||
dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_"
|
||||
dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables
|
||||
dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are
|
||||
dnl used for the target type. See INSTALL for full list of variables.
|
||||
|
||||
AC_INIT([GRUB],[2.05],[bug-grub@gnu.org])
|
||||
AC_INIT([GRUB],[2.04],[bug-grub@gnu.org])
|
||||
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
|
@ -80,15 +77,9 @@ grub_TRANSFORM([grub-file])
|
|||
|
||||
# Optimization flag. Allow user to override.
|
||||
if test "x$TARGET_CFLAGS" = x; then
|
||||
TARGET_CFLAGS=-Os
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -Os"
|
||||
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
|
||||
HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W"
|
||||
HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1"
|
||||
|
@ -571,24 +562,6 @@ CPPFLAGS="$TARGET_CPPFLAGS"
|
|||
LDFLAGS="$TARGET_LDFLAGS"
|
||||
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.
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations"
|
||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g"
|
||||
|
@ -777,6 +750,24 @@ if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then
|
|||
TARGET_CFLAGS="$TARGET_CFLAGS -march=i386"
|
||||
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
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3"
|
||||
fi
|
||||
|
@ -863,11 +854,6 @@ if test x"$platform" != xemu ; then
|
|||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], [])
|
||||
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" \
|
||||
"-Xclang -msoft-float -Xclang -no-implicit-float" \
|
||||
"-Xclang -msoft-float" "-msoft-float"; do
|
||||
|
@ -1013,17 +999,6 @@ if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then
|
|||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables"
|
||||
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"
|
||||
|
||||
|
@ -1223,8 +1198,7 @@ if test "x$target_cpu" = xarm; then
|
|||
AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [
|
||||
grub_cv_target_cc_mno_movt=no
|
||||
for cand in "-mno-movt" \
|
||||
"-mllvm -arm-use-movt=0" \
|
||||
"-mword-relocations"; do
|
||||
"-mllvm -arm-use-movt=0"; do
|
||||
if test x"$grub_cv_target_cc_mno_movt" != xno ; then
|
||||
break
|
||||
fi
|
||||
|
@ -1277,7 +1251,6 @@ grub_CHECK_LINK_PIE
|
|||
# `-fPIE' or '-fpie' and '-pie' in the default specs.
|
||||
if [ x"$pie_possible" = xyes ]; then
|
||||
TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie"
|
||||
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -fno-PIE -fno-pie"
|
||||
fi
|
||||
|
||||
if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then
|
||||
|
@ -1385,7 +1358,7 @@ fi
|
|||
|
||||
# Check for libgcc symbols
|
||||
if test x"$platform" = xemu; then
|
||||
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)
|
||||
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)
|
||||
fi
|
||||
|
||||
if test "x$TARGET_APPLE_LINKER" = x1 ; then
|
||||
|
@ -1462,11 +1435,9 @@ LIBS="$tmp_LIBS"
|
|||
# Memory manager debugging.
|
||||
AC_ARG_ENABLE([mm-debug],
|
||||
AS_HELP_STRING([--enable-mm-debug],
|
||||
[include memory manager debugging]))
|
||||
if test x$enable_mm_debug = xyes; then
|
||||
AC_DEFINE([MM_DEBUG], [1],
|
||||
[Define to 1 if you enable memory manager debugging.])
|
||||
fi
|
||||
[include memory manager debugging]),
|
||||
[AC_DEFINE([MM_DEBUG], [1],
|
||||
[Define to 1 if you enable memory manager debugging.])])
|
||||
|
||||
AC_ARG_ENABLE([cache-stats],
|
||||
AS_HELP_STRING([--enable-cache-stats],
|
||||
|
|
|
@ -490,8 +490,6 @@ to update it.
|
|||
|
||||
@menu
|
||||
* Gnulib::
|
||||
* jsmn::
|
||||
* minilzo::
|
||||
@end menu
|
||||
|
||||
@node Gnulib
|
||||
|
@ -547,41 +545,6 @@ AC_SYS_LARGEFILE
|
|||
|
||||
@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
|
||||
@chapter Porting
|
||||
|
||||
|
|
252
docs/grub.texi
252
docs/grub.texi
|
@ -894,7 +894,6 @@ magic.
|
|||
@menu
|
||||
* General boot methods:: How to boot OSes with GRUB generally
|
||||
* 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
|
||||
@end menu
|
||||
|
||||
|
@ -992,26 +991,6 @@ way. Please consider alternative boot methods like copying all files
|
|||
from the image to actual partition. Consult your OS documentation for
|
||||
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
|
||||
@section Some caveats on OS-specific issues
|
||||
|
||||
|
@ -1114,6 +1093,12 @@ grub> @kbd{initrd16 /initrd}
|
|||
Finally, run the command @command{boot} (@pxref{boot}).
|
||||
@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
|
||||
@subsection NetBSD
|
||||
|
@ -1324,12 +1309,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.
|
||||
|
||||
If this option is set to @samp{countdown} or @samp{hidden}, then, before
|
||||
displaying the menu, GRUB will wait for the timeout set by @samp{GRUB_TIMEOUT}
|
||||
to expire. If @key{ESC} or @key{F4} are pressed, or @key{SHIFT} is held down
|
||||
during that time, it will display the menu and wait for input. If a hotkey
|
||||
associated with a menu entry is pressed, it will boot the associated menu entry
|
||||
immediately. If the timeout expires before either of these happens, it will
|
||||
boot the default entry. In the @samp{countdown} case, it will show a one-line
|
||||
displaying the menu, GRUB will wait for the timeout set by
|
||||
@samp{GRUB_TIMEOUT} to expire. If @key{ESC} is pressed during that time, it
|
||||
will display the menu and wait for input. If a hotkey associated with a
|
||||
menu entry is pressed, it will boot the associated menu entry immediately.
|
||||
If the timeout expires before either of these happens, it will boot the
|
||||
default entry. In the @samp{countdown} case, it will show a one-line
|
||||
indication of the remaining time.
|
||||
|
||||
@item GRUB_DEFAULT_BUTTON
|
||||
|
@ -1456,15 +1441,6 @@ 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
|
||||
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
|
||||
If graphical video support is required, either because the @samp{gfxterm}
|
||||
graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set,
|
||||
|
@ -1519,7 +1495,7 @@ Normally, @command{grub-mkconfig} will generate top level menu entry for
|
|||
the kernel with highest version number and put all other found kernels
|
||||
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
|
||||
in submenu. If this option is set to @samp{true}, flat menu with all entries
|
||||
in submenu. If this option is set to @samp{y}, flat menu with all entries
|
||||
on top level will be generated instead. Changing this option will require
|
||||
changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback})
|
||||
and @samp{default} (@pxref{default}) environment variables as well as saved
|
||||
|
@ -1553,16 +1529,16 @@ configurations, but have better replacements:
|
|||
|
||||
@table @samp
|
||||
@item GRUB_HIDDEN_TIMEOUT
|
||||
Wait this many seconds before displaying the menu. If @key{ESC} or @key{F4} are
|
||||
pressed, or @key{SHIFT} is held down during that time, display the menu and wait
|
||||
for input according to @samp{GRUB_TIMEOUT}. If a hotkey associated with a menu
|
||||
entry is pressed, boot the associated menu entry immediately. If the timeout
|
||||
expires before either of these happens, display the menu for the number of
|
||||
seconds specified in @samp{GRUB_TIMEOUT} before booting the default entry.
|
||||
Wait this many seconds before displaying the menu. If @key{ESC} is pressed
|
||||
during that time, display the menu and wait for input according to
|
||||
@samp{GRUB_TIMEOUT}. If a hotkey associated with a menu entry is pressed,
|
||||
boot the associated menu entry immediately. If the timeout expires before
|
||||
either of these happens, display the menu for the number of seconds
|
||||
specified in @samp{GRUB_TIMEOUT} before booting the default entry.
|
||||
|
||||
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
|
||||
@key{ESC} or @key{F4} are pressed, or @key{SHIFT} is held down.
|
||||
@key{ESC} is pressed.
|
||||
|
||||
This option is unset by default, and is deprecated in favour of the less
|
||||
confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or
|
||||
|
@ -2510,57 +2486,6 @@ 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
|
||||
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
|
||||
@samp{(tftp)} device.
|
||||
|
||||
|
@ -4005,6 +3930,7 @@ you forget a command, you can run the command @command{help}
|
|||
* password_pbkdf2:: Set a hashed password
|
||||
* play:: Play a tune
|
||||
* probe:: Retrieve device info
|
||||
* pxe_unload:: Unload the PXE environment
|
||||
* rdmsr:: Read values from model-specific registers
|
||||
* read:: Read user input
|
||||
* reboot:: Reboot your computer
|
||||
|
@ -4024,6 +3950,7 @@ you forget a command, you can run the command @command{help}
|
|||
* true:: Do nothing, successfully
|
||||
* trust:: Add public key to list of trusted keys
|
||||
* unset:: Unset an environment variable
|
||||
* uppermem:: Set the upper memory size
|
||||
@comment * vbeinfo:: List available video modes
|
||||
* verify_detached:: Verify detached digital signature
|
||||
* videoinfo:: List available video modes
|
||||
|
@ -4275,9 +4202,8 @@ is requested interactively. Option @var{device} configures specific grub device
|
|||
with specified @var{uuid}; option @option{-a} configures all detected encrypted
|
||||
devices; option @option{-b} configures all geli containers that have boot flag set.
|
||||
|
||||
GRUB suports devices encrypted using LUKS, LUKS2 and geli. Note that necessary
|
||||
modules (@var{luks}, @var{luks2} and @var{geli}) have to be loaded manually
|
||||
before this command can be used.
|
||||
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
|
||||
be used.
|
||||
@end deffn
|
||||
|
||||
|
||||
|
@ -4295,12 +4221,13 @@ hour, minute, and second unchanged.
|
|||
|
||||
|
||||
@node devicetree
|
||||
@subsection devicetree
|
||||
@subsection linux
|
||||
|
||||
@deffn Command devicetree file
|
||||
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,
|
||||
but rather replaces it completely.
|
||||
@ref{GNU/Linux}.
|
||||
@end deffn
|
||||
|
||||
@node distrust
|
||||
|
@ -4497,22 +4424,22 @@ about each of the commands whose names begin with those @var{patterns}.
|
|||
@node initrd
|
||||
@subsection initrd
|
||||
|
||||
@deffn Command initrd file [file @dots{}]
|
||||
Load, in order, all initial ramdisks for a Linux kernel image, and set
|
||||
the appropriate parameters in the Linux setup area in memory. This may only
|
||||
be used after the @command{linux} command (@pxref{linux}) has been run. See
|
||||
also @ref{GNU/Linux}.
|
||||
@deffn Command initrd file
|
||||
Load an initial ramdisk for a Linux kernel image, and set the appropriate
|
||||
parameters in the Linux setup area in memory. This may only be used after
|
||||
the @command{linux} command (@pxref{linux}) has been run. See also
|
||||
@ref{GNU/Linux}.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node initrd16
|
||||
@subsection initrd16
|
||||
|
||||
@deffn Command initrd16 file [file @dots{}]
|
||||
Load, in order, all initial ramdisks for a Linux kernel image to be booted in
|
||||
16-bit mode, and set the appropriate parameters in the Linux setup area in
|
||||
memory. This may only be used after the @command{linux16} command
|
||||
(@pxref{linux16}) has been run. See also @ref{GNU/Linux}.
|
||||
@deffn Command initrd16 file
|
||||
Load an initial ramdisk for a Linux kernel image to be booted in 16-bit
|
||||
mode, and set the appropriate parameters in the Linux setup area in memory.
|
||||
This may only be used after the @command{linux16} command (@pxref{linux16})
|
||||
has been run. See also @ref{GNU/Linux}.
|
||||
|
||||
This command is only available on x86 systems.
|
||||
@end deffn
|
||||
|
@ -4720,7 +4647,7 @@ be reloaded after using this command (@pxref{module}).
|
|||
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
|
||||
loading kludge information with invalid data in ELF file. GRUB prior to 0.97
|
||||
and some custom builds preferred ELF information while 0.97 and GRUB 2
|
||||
and some custom builds prefered ELF information while 0.97 and GRUB 2
|
||||
use kludge. Use this option to ignore kludge.
|
||||
Known affected systems: old Solaris, SkyOS.
|
||||
|
||||
|
@ -4845,11 +4772,19 @@ a rest.
|
|||
@node probe
|
||||
@subsection probe
|
||||
|
||||
@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label}|@option{--part-uuid} device
|
||||
@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label} device
|
||||
Retrieve device information. If option @option{--set} is given, assign result
|
||||
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
|
||||
|
||||
|
||||
|
@ -5143,10 +5078,9 @@ Alias for @code{hashsum --hash sha512 arg @dots{}}. See command @command{hashsum
|
|||
|
||||
@deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count
|
||||
Sleep for @var{count} seconds. If option @option{--interruptible} is given,
|
||||
allow pressing @key{ESC}, @key{F4} or holding down @key{SHIFT} to interrupt
|
||||
sleep. With @option{--verbose} show countdown of remaining seconds. Exit code
|
||||
is set to 0 if timeout expired and to 1 if timeout was interrupted using any
|
||||
of the mentioned keys.
|
||||
allow @key{ESC} to interrupt sleep. With @option{--verbose} show countdown
|
||||
of remaining seconds. Exit code is set to 0 if timeout expired and to 1
|
||||
if timeout was interrupted by @key{ESC}.
|
||||
@end deffn
|
||||
|
||||
|
||||
|
@ -5188,27 +5122,21 @@ return. Only one of these options may be specified at a time.
|
|||
@item
|
||||
When given @option{--get-byte}, return the value of the byte
|
||||
at @var{offset} bytes into the selected SMBIOS structure.
|
||||
It will be formatted as an unsigned decimal integer.
|
||||
@item
|
||||
When given @option{--get-word}, return the value of the word (two bytes)
|
||||
at @var{offset} bytes into the selected SMBIOS structure.
|
||||
It will be formatted as an unsigned decimal integer.
|
||||
@item
|
||||
When given @option{--get-dword}, return the value of the dword (four bytes)
|
||||
at @var{offset} bytes into the selected SMBIOS structure.
|
||||
It will be formatted as an unsigned decimal integer.
|
||||
@item
|
||||
When given @option{--get-qword}, return the value of the qword (eight bytes)
|
||||
at @var{offset} bytes into the selected SMBIOS structure.
|
||||
It will be formatted as an unsigned decimal integer.
|
||||
@item
|
||||
When given @option{--get-string}, return the string with its index found
|
||||
at @var{offset} bytes into the selected SMBIOS structure.
|
||||
@item
|
||||
When given @option{--get-uuid}, return the value of the UUID (sixteen bytes)
|
||||
at @var{offset} bytes into the selected SMBIOS structure.
|
||||
It will be formatted as lower-case hyphenated hexadecimal digits, with the
|
||||
first three fields as little-endian, and the rest printed byte-by-byte.
|
||||
@end itemize
|
||||
|
||||
The default action is to print the value of the requested field to the console,
|
||||
|
@ -5340,6 +5268,12 @@ Unset the environment variable @var{envvar}.
|
|||
@end deffn
|
||||
|
||||
|
||||
@node uppermem
|
||||
@subsection uppermem
|
||||
|
||||
This command is not yet implemented for GRUB 2, although it is planned.
|
||||
|
||||
|
||||
@ignore
|
||||
@node vbeinfo
|
||||
@subsection vbeinfo
|
||||
|
@ -5423,11 +5357,10 @@ This command is only available on AArch64 systems.
|
|||
* net_add_addr:: Add a network address
|
||||
* net_add_dns:: Add a DNS server
|
||||
* net_add_route:: Add routing entry
|
||||
* net_bootp:: Perform a bootp/DHCP autoconfiguration
|
||||
* net_bootp:: Perform a bootp autoconfiguration
|
||||
* net_del_addr:: Remove IP address from interface
|
||||
* net_del_dns:: Remove a DNS server
|
||||
* net_del_route:: Remove a route entry
|
||||
* net_dhcp:: Perform a DHCP autoconfiguration
|
||||
* net_get_dhcp_option:: Retrieve DHCP options
|
||||
* net_ipv6_autoconf:: Perform IPv6 autoconfiguration
|
||||
* net_ls_addr:: List interfaces
|
||||
|
@ -5474,44 +5407,8 @@ by @var{shortname} which can be used to remove it (@pxref{net_del_route}).
|
|||
@subsection net_bootp
|
||||
|
||||
@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
|
||||
is specified, try to configure all existing cards.
|
||||
Falls back to the BOOTP protocol, if needed. If configuration was
|
||||
is specified, try to configure all existing cards. If configuration was
|
||||
successful, interface with name @var{card}@samp{:dhcp} and configured
|
||||
address is added to @var{card}.
|
||||
@comment If server provided gateway information in
|
||||
|
@ -5538,17 +5435,35 @@ Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_rootpath}
|
|||
@item 18 (Extensions Path)
|
||||
Sets environment variable @samp{net_}@var{<card>}@samp{_dhcp_extensionspath}
|
||||
(@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 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
|
||||
@subsection net_get_dhcp_option
|
||||
|
||||
|
@ -5766,8 +5681,7 @@ 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
|
||||
entries are automatically restricted to superusers. Setting @samp{superusers}
|
||||
to empty string effectively disables both access to CLI and editing of menu
|
||||
entries. Note: The environment variable needs to be exported to also affect
|
||||
the section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
entries.
|
||||
|
||||
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
|
||||
|
|
|
@ -766,7 +766,7 @@ def image(defn, platform):
|
|||
if test x$(TARGET_APPLE_LINKER) = x1; then \
|
||||
$(MACHO2IMG) $< $@; \
|
||||
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 .note.gnu.property -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 .ARM.exidx $< $@; \
|
||||
fi
|
||||
""")
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ 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/mm_private.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
|
||||
|
||||
if COND_i386_pc
|
||||
|
|
|
@ -140,6 +140,7 @@ kernel = {
|
|||
common = kern/rescue_parser.c;
|
||||
common = kern/rescue_reader.c;
|
||||
common = kern/term.c;
|
||||
common = kern/tpm.c;
|
||||
|
||||
noemu = kern/compiler-rt.c;
|
||||
noemu = kern/mm.c;
|
||||
|
@ -203,6 +204,7 @@ kernel = {
|
|||
efi = term/efi/console.c;
|
||||
efi = kern/acpi.c;
|
||||
efi = kern/efi/acpi.c;
|
||||
efi = kern/efi/tpm.c;
|
||||
i386_coreboot = kern/i386/pc/acpi.c;
|
||||
i386_multiboot = kern/i386/pc/acpi.c;
|
||||
i386_coreboot = kern/acpi.c;
|
||||
|
@ -262,6 +264,7 @@ kernel = {
|
|||
|
||||
i386_pc = kern/i386/pc/init.c;
|
||||
i386_pc = kern/i386/pc/mmap.c;
|
||||
i386_pc = kern/i386/pc/tpm.c;
|
||||
i386_pc = term/i386/pc/console.c;
|
||||
|
||||
i386_qemu = bus/pci.c;
|
||||
|
@ -888,11 +891,32 @@ module = {
|
|||
enable = x86_64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = getenv;
|
||||
common = commands/efi/getenv.c;
|
||||
enable = efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = gptsync;
|
||||
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 = {
|
||||
name = halt;
|
||||
nopc = commands/halt.c;
|
||||
|
@ -950,7 +974,7 @@ module = {
|
|||
module = {
|
||||
name = shim_lock;
|
||||
common = commands/efi/shim_lock.c;
|
||||
enable = efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -1080,6 +1104,21 @@ module = {
|
|||
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 = {
|
||||
name = setpci;
|
||||
common = commands/setpci.c;
|
||||
|
@ -1176,27 +1215,10 @@ module = {
|
|||
common = disk/cryptodisk.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = json;
|
||||
common = lib/json/json.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = afsplitter;
|
||||
common = disk/AFSplitter.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = luks;
|
||||
common = disk/luks.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';
|
||||
common = disk/AFSplitter.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -1687,7 +1709,6 @@ module = {
|
|||
|
||||
module = {
|
||||
name = datetime;
|
||||
common = lib/datetime.c;
|
||||
cmos = lib/cmos_datetime.c;
|
||||
efi = lib/efi/datetime.c;
|
||||
uboot = lib/dummy/datetime.c;
|
||||
|
@ -1700,6 +1721,7 @@ module = {
|
|||
i386_xen_pvh = lib/xen/datetime.c;
|
||||
|
||||
mips_arc = lib/arc/datetime.c;
|
||||
enable = noemu;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -1881,6 +1903,14 @@ module = {
|
|||
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 = {
|
||||
name = chain;
|
||||
efi = loader/efi/chainloader.c;
|
||||
|
@ -1926,6 +1956,7 @@ module = {
|
|||
common = normal/autofs.c;
|
||||
common = normal/color.c;
|
||||
common = normal/completion.c;
|
||||
common = normal/datetime.c;
|
||||
common = normal/menu.c;
|
||||
common = normal/menu_entry.c;
|
||||
common = normal/menu_text.c;
|
||||
|
@ -2500,7 +2531,7 @@ module = {
|
|||
name = tpm;
|
||||
common = commands/tpm.c;
|
||||
efi = commands/efi/tpm.c;
|
||||
enable = efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -2534,3 +2565,8 @@ module = {
|
|||
common = commands/i386/wrmsr.c;
|
||||
enable = x86;
|
||||
};
|
||||
module = {
|
||||
name = fwconfig;
|
||||
common = commands/fwconfig.c;
|
||||
enable = x86;
|
||||
};
|
||||
|
|
|
@ -24,11 +24,14 @@
|
|||
* defines for the code go here
|
||||
*/
|
||||
|
||||
#define TPM 1
|
||||
|
||||
/* Print message string */
|
||||
#define MSG(x) movw $x, %si; call LOCAL(message)
|
||||
#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
|
||||
|
||||
.macro floppy
|
||||
#ifndef TPM
|
||||
part_start:
|
||||
|
||||
LOCAL(probe_values):
|
||||
|
@ -85,6 +88,7 @@ fd_probe_error_string: .asciz "Floppy"
|
|||
movb MACRO_DOLLAR(79), %ch
|
||||
|
||||
jmp LOCAL(final_init)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro scratch
|
||||
|
@ -255,6 +259,7 @@ real_start:
|
|||
/* set %si to the disk address packet */
|
||||
movw $disk_address_packet, %si
|
||||
|
||||
#ifndef TPM
|
||||
/* check if LBA is supported */
|
||||
movb $0x41, %ah
|
||||
movw $0x55aa, %bx
|
||||
|
@ -274,6 +279,7 @@ real_start:
|
|||
|
||||
andw $1, %cx
|
||||
jz LOCAL(chs_mode)
|
||||
#endif
|
||||
|
||||
LOCAL(lba_mode):
|
||||
xorw %ax, %ax
|
||||
|
@ -317,6 +323,9 @@ LOCAL(lba_mode):
|
|||
jmp LOCAL(copy_buffer)
|
||||
|
||||
LOCAL(chs_mode):
|
||||
#ifdef TPM
|
||||
jmp LOCAL(general_error)
|
||||
#else
|
||||
/*
|
||||
* Determine the hard disk geometry from the BIOS!
|
||||
* We do this first, so that LS-120 IDE floppies work correctly.
|
||||
|
@ -428,7 +437,7 @@ setup_sectors:
|
|||
jc LOCAL(read_error)
|
||||
|
||||
movw %es, %bx
|
||||
|
||||
#endif /* TPM */
|
||||
LOCAL(copy_buffer):
|
||||
/*
|
||||
* We need to save %cx and %si because the startup code in
|
||||
|
@ -451,6 +460,25 @@ LOCAL(copy_buffer):
|
|||
popw %ds
|
||||
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 */
|
||||
jmp *(LOCAL(kernel_address))
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <grub/symbol.h>
|
||||
#include <grub/machine/boot.h>
|
||||
|
||||
#define TPM 1
|
||||
|
||||
/*
|
||||
* defines for the code go here
|
||||
*/
|
||||
|
@ -58,6 +60,21 @@ _start:
|
|||
/* this sets up for the first run through "bootloop" */
|
||||
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 */
|
||||
movl (%di), %ebp
|
||||
|
||||
|
@ -295,6 +312,29 @@ LOCAL(copy_buffer):
|
|||
/* END OF MAIN LOOP */
|
||||
|
||||
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 */
|
||||
MSG(notification_done)
|
||||
popw %dx /* this makes sure %dl is our "boot" drive */
|
||||
|
@ -329,6 +369,10 @@ geometry_error_string: .asciz "Geom"
|
|||
read_error_string: .asciz "Read"
|
||||
general_error_string: .asciz " Error"
|
||||
|
||||
#ifdef TPM
|
||||
bytes_to_measure: .long 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
dev->nports = hubdesc.portcnt;
|
||||
dev->children = grub_calloc (hubdesc.portcnt, sizeof (dev->children[0]));
|
||||
dev->ports = grub_calloc (dev->nports, sizeof (dev->ports[0]));
|
||||
dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
|
||||
dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0]));
|
||||
if (!dev->children || !dev->ports)
|
||||
{
|
||||
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. */
|
||||
hub->nports = controller->dev->hubports (controller);
|
||||
hub->devices = grub_calloc (hub->nports, sizeof (hub->devices[0]));
|
||||
hub->ports = grub_calloc (hub->nports, sizeof (hub->ports[0]));
|
||||
hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports);
|
||||
hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports);
|
||||
if (!hub->devices || !hub->ports)
|
||||
{
|
||||
grub_free (hub->devices);
|
||||
|
|
|
@ -59,8 +59,7 @@ grub_cmd_date (grub_command_t cmd __attribute__ ((unused)),
|
|||
|
||||
for (; argc; argc--, args++)
|
||||
{
|
||||
const char *p;
|
||||
char c;
|
||||
char *p, c;
|
||||
int m1, ofs, n, cur_mask;
|
||||
|
||||
p = args[0];
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
/* 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,6 +30,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||
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 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 LOW_MEM_ADDR 0x413
|
||||
|
@ -93,7 +94,7 @@ static void
|
|||
fake_bios_data (int use_rom)
|
||||
{
|
||||
unsigned i;
|
||||
void *acpi, *smbios;
|
||||
void *acpi, *smbios, *smbios3;
|
||||
grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
|
||||
|
||||
ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
|
||||
|
@ -103,6 +104,7 @@ fake_bios_data (int use_rom)
|
|||
|
||||
acpi = 0;
|
||||
smbios = 0;
|
||||
smbios3 = 0;
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
{
|
||||
grub_efi_packed_guid_t *guid =
|
||||
|
@ -127,6 +129,11 @@ fake_bios_data (int use_rom)
|
|||
smbios = grub_efi_system_table->configuration_table[i].vendor_table;
|
||||
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;
|
||||
|
@ -137,8 +144,13 @@ fake_bios_data (int use_rom)
|
|||
if (acpi)
|
||||
grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
|
||||
|
||||
if ((use_rom) && (smbios))
|
||||
grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
|
||||
if (use_rom)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -40,7 +40,6 @@ static const struct guid_mapping guid_mappings[] =
|
|||
{ GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID,
|
||||
"CRC32 GUIDED SECTION EXTRACTION"},
|
||||
{ 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_HCDP_TABLE_GUID, "HCDP"},
|
||||
{ GRUB_EFI_HOB_LIST_GUID, "HOB LIST"},
|
||||
|
@ -73,8 +72,7 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)),
|
|||
grub_printf ("Vendor: ");
|
||||
|
||||
for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
|
||||
/* Allocate extra 3 bytes to simplify math. */
|
||||
vendor = grub_calloc (4, vendor_utf16 - st->firmware_vendor + 1);
|
||||
vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1);
|
||||
if (!vendor)
|
||||
return grub_errno;
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* smbios.c - get smbios tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2015 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
|
||||
|
@ -37,7 +37,6 @@ grub_machine_smbios_get_eps (void)
|
|||
return (struct grub_smbios_eps *)
|
||||
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -56,6 +55,5 @@ grub_machine_smbios_get_eps3 (void)
|
|||
return (struct grub_smbios_eps3 *)
|
||||
grub_efi_system_table->configuration_table[i].vendor_table;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,103 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle,
|
|||
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
|
||||
grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
||||
grub_size_t size, grub_uint8_t pcr,
|
||||
|
@ -150,7 +247,6 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
|||
algorithm = TCG_ALG_SHA;
|
||||
status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size,
|
||||
algorithm, event, &eventnum, &lastevent);
|
||||
grub_free (event);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
@ -201,7 +297,6 @@ 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,
|
||||
(grub_uint64_t) size, event);
|
||||
grub_free (event);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
@ -222,7 +317,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf,
|
|||
}
|
||||
|
||||
grub_err_t
|
||||
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
grub_tpm_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
grub_efi_handle_t tpm_handle;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/* 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);
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
/* 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);
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/* 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
|
||||
parse_args (int argc, char *argv[], int *byte, int *bit)
|
||||
{
|
||||
const char *rest;
|
||||
char *rest;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "address required");
|
||||
|
|
|
@ -132,7 +132,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
|
|||
}
|
||||
else
|
||||
{
|
||||
const char *end;
|
||||
char *end;
|
||||
unsigned tempo;
|
||||
struct note note;
|
||||
int i;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* smbios.c - get smbios tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2015 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
|
||||
|
@ -27,12 +27,11 @@ grub_machine_smbios_get_eps (void)
|
|||
grub_uint8_t *ptr;
|
||||
|
||||
grub_dprintf ("smbios", "Looking for SMBIOS EPS. Scanning BIOS\n");
|
||||
|
||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
|
||||
ptr += 16)
|
||||
if (grub_memcmp (ptr, "_SM_", 4) == 0
|
||||
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps)) == 0)
|
||||
return (struct grub_smbios_eps *) ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -42,11 +41,10 @@ grub_machine_smbios_get_eps3 (void)
|
|||
grub_uint8_t *ptr;
|
||||
|
||||
grub_dprintf ("smbios", "Looking for SMBIOS3 EPS. Scanning BIOS\n");
|
||||
|
||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16)
|
||||
for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
|
||||
ptr += 16)
|
||||
if (grub_memcmp (ptr, "_SM3_", 5) == 0
|
||||
&& grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0)
|
||||
return (struct grub_smbios_eps3 *) ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
{
|
||||
grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
|
||||
grub_uint64_t value;
|
||||
const char *ptr;
|
||||
char *ptr;
|
||||
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_uint64_t value;
|
||||
const char *ptr;
|
||||
char *ptr;
|
||||
|
||||
/*
|
||||
* The CPUID instruction should be used to determine whether MSRs
|
||||
|
|
|
@ -35,6 +35,24 @@ static const struct grub_arg_option options[] =
|
|||
{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
|
||||
grub_cmd_keystatus (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include <grub/auth.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -105,22 +104,13 @@ legacy_file (const char *filename)
|
|||
if (newsuffix)
|
||||
{
|
||||
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;
|
||||
suffix = grub_realloc (suffix, sz);
|
||||
suffix = grub_realloc (suffix, grub_strlen (suffix)
|
||||
+ grub_strlen (newsuffix) + 1);
|
||||
if (!suffix)
|
||||
{
|
||||
grub_free (t);
|
||||
|
||||
fail_0:
|
||||
grub_free (entrysrc);
|
||||
grub_free (parsed);
|
||||
grub_free (newsuffix);
|
||||
|
@ -164,22 +154,13 @@ legacy_file (const char *filename)
|
|||
else
|
||||
{
|
||||
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;
|
||||
entrysrc = grub_realloc (entrysrc, sz);
|
||||
entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
|
||||
+ grub_strlen (parsed) + 1);
|
||||
if (!entrysrc)
|
||||
{
|
||||
grub_free (t);
|
||||
|
||||
fail_1:
|
||||
grub_free (parsed);
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
|
@ -333,7 +314,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
|||
if (argc < 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
cutargs = grub_calloc (argc - 1, sizeof (cutargs[0]));
|
||||
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
|
||||
if (!cutargs)
|
||||
return grub_errno;
|
||||
cutargc = argc - 1;
|
||||
|
@ -455,7 +436,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
|||
{
|
||||
char rbuf[3] = "-r";
|
||||
bsdargc = cutargc + 2;
|
||||
bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0]));
|
||||
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
|
||||
if (!bsdargs)
|
||||
{
|
||||
err = grub_errno;
|
||||
|
@ -578,7 +559,7 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused
|
|||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
|
||||
"module");
|
||||
|
||||
newargs = grub_calloc (argc + 1, sizeof (newargs[0]));
|
||||
newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
|
||||
if (!newargs)
|
||||
return grub_errno;
|
||||
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;
|
||||
|
||||
/* Save argc, args to pass as parameters to block arg later. */
|
||||
menu_args = grub_calloc (argc + 1, sizeof (char *));
|
||||
menu_args = grub_malloc (sizeof (char*) * (argc + 1));
|
||||
if (! menu_args)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
|
|||
else
|
||||
path_prefix = prefix;
|
||||
|
||||
mods = grub_calloc (argc, sizeof (mods[0]));
|
||||
mods = grub_malloc (argc * sizeof (mods[0]));
|
||||
if (!mods)
|
||||
return grub_errno;
|
||||
|
||||
|
|
|
@ -59,13 +59,7 @@ grub_parttool_register(const char *part_name,
|
|||
for (nargs = 0; args[nargs].name != 0; nargs++);
|
||||
cur->nargs = nargs;
|
||||
cur->args = (struct grub_parttool_argdesc *)
|
||||
grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc));
|
||||
if (!cur->args)
|
||||
{
|
||||
grub_free (cur);
|
||||
curhandle--;
|
||||
return -1;
|
||||
}
|
||||
grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
|
||||
grub_memcpy (cur->args, args,
|
||||
(nargs + 1) * sizeof (struct grub_parttool_argdesc));
|
||||
|
||||
|
@ -263,7 +257,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
|||
return err;
|
||||
}
|
||||
|
||||
parsed = (int *) grub_calloc (argc, sizeof (int));
|
||||
parsed = (int *) grub_zalloc (argc * sizeof (int));
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
if (! parsed[i])
|
||||
|
@ -296,7 +290,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
|||
}
|
||||
ptool = cur;
|
||||
pargs = (struct grub_parttool_args *)
|
||||
grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args));
|
||||
grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));
|
||||
for (j = i; j < argc; j++)
|
||||
if (! parsed[j])
|
||||
{
|
||||
|
|
|
@ -86,7 +86,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
|
|||
int argc, char **args)
|
||||
{
|
||||
grub_err_t err;
|
||||
const char *ptr, *ptr2;
|
||||
char *ptr, *ptr2;
|
||||
grub_uint8_t *ptro;
|
||||
struct pbkdf2_password *pass;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
|||
if (ctxt->state[0].set)
|
||||
{
|
||||
ptr = ctxt->state[0].arg;
|
||||
ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff);
|
||||
ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
@ -108,7 +108,8 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
|||
if (*ptr != ':')
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||
ptr++;
|
||||
ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16;
|
||||
ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
|
||||
<< 16;
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
else
|
||||
|
@ -120,10 +121,10 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
|||
if (ctxt->state[1].set)
|
||||
{
|
||||
const char *optr;
|
||||
|
||||
|
||||
ptr = ctxt->state[1].arg;
|
||||
optr = ptr;
|
||||
ctx.bus = grub_strtoul (ptr, &ptr, 16);
|
||||
ctx.bus = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
@ -137,7 +138,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
|||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||
ptr++;
|
||||
optr = ptr;
|
||||
ctx.device = grub_strtoul (ptr, &ptr, 16);
|
||||
ctx.device = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
@ -148,7 +149,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt,
|
|||
if (*ptr == '.')
|
||||
{
|
||||
ptr++;
|
||||
ctx.function = grub_strtoul (ptr, &ptr, 16);
|
||||
ctx.function = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
ctx.check_function = 1;
|
||||
|
|
|
@ -759,6 +759,78 @@ grub_cmd_trust (grub_extcmd_context_t ctxt,
|
|||
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
|
||||
grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
|
@ -922,21 +994,6 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
|
|||
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 =
|
||||
{
|
||||
.name = "pgp",
|
||||
|
@ -947,7 +1004,7 @@ struct grub_file_verifier grub_pubkey_verifier =
|
|||
};
|
||||
|
||||
static grub_extcmd_t cmd, cmd_trust;
|
||||
static grub_command_t cmd_distrust, cmd_list;
|
||||
static grub_command_t cmd_trust_var, cmd_distrust, cmd_list;
|
||||
|
||||
GRUB_MOD_INIT(pgp)
|
||||
{
|
||||
|
@ -998,6 +1055,9 @@ GRUB_MOD_INIT(pgp)
|
|||
N_("[-s|--skip-sig] PUBKEY_FILE"),
|
||||
N_("Add PUBKEY_FILE to trusted keys."),
|
||||
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,
|
||||
0,
|
||||
N_("Show the list of trusted keys."));
|
||||
|
@ -1013,6 +1073,7 @@ GRUB_MOD_FINI(pgp)
|
|||
grub_verifier_unregister (&grub_pubkey_verifier);
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_trust);
|
||||
grub_unregister_command (cmd_trust_var);
|
||||
grub_unregister_command (cmd_list);
|
||||
grub_unregister_command (cmd_distrust);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <grub/device.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/gpt_partition.h>
|
||||
#include <grub/net.h>
|
||||
#include <grub/fs.h>
|
||||
#include <grub/file.h>
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include <grub/env.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/i386/pc/boot.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -47,7 +45,6 @@ static const struct grub_arg_option options[] =
|
|||
{"fs", 'f', 0, N_("Determine filesystem type."), 0, 0},
|
||||
{"fs-uuid", 'u', 0, N_("Determine filesystem UUID."), 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}
|
||||
};
|
||||
|
||||
|
@ -101,52 +98,6 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
grub_device_close (dev);
|
||||
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);
|
||||
if (! fs)
|
||||
return grub_errno;
|
||||
|
|
|
@ -64,7 +64,7 @@ set_matches (char **varnames, char *str, grub_size_t nmatches,
|
|||
{
|
||||
int i;
|
||||
char *p;
|
||||
const char * q;
|
||||
char *q;
|
||||
grub_err_t err;
|
||||
unsigned long j;
|
||||
|
||||
|
@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches));
|
||||
matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1));
|
||||
if (! matches)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include <grub/i18n.h>
|
||||
#include <grub/disk.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+");
|
||||
|
||||
|
@ -66,7 +70,7 @@ iterate_device (const char *name, void *data)
|
|||
name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
|
||||
return 1;
|
||||
|
||||
#ifdef DO_SEARCH_FS_UUID
|
||||
#if defined(DO_SEARCH_FS_UUID) || defined(DO_SEARCH_DISK_UUID)
|
||||
#define compare_fn grub_strcasecmp
|
||||
#else
|
||||
#define compare_fn grub_strcmp
|
||||
|
@ -90,6 +94,63 @@ iterate_device (const char *name, void *data)
|
|||
}
|
||||
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
|
||||
{
|
||||
/* SEARCH_FS_UUID or SEARCH_LABEL */
|
||||
|
@ -313,8 +374,14 @@ static grub_command_t cmd;
|
|||
|
||||
#ifdef DO_SEARCH_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)
|
||||
GRUB_MOD_INIT(search_fs_uuid)
|
||||
#elif defined (DO_SEARCH_DISK_UUID)
|
||||
GRUB_MOD_INIT(search_disk_uuid)
|
||||
#else
|
||||
GRUB_MOD_INIT(search_label)
|
||||
#endif
|
||||
|
@ -327,8 +394,14 @@ GRUB_MOD_INIT(search_label)
|
|||
|
||||
#ifdef DO_SEARCH_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)
|
||||
GRUB_MOD_FINI(search_fs_uuid)
|
||||
#elif defined (DO_SEARCH_DISK_UUID)
|
||||
GRUB_MOD_FINI(search_disk_uuid)
|
||||
#else
|
||||
GRUB_MOD_FINI(search_label)
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#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"
|
|
@ -0,0 +1,5 @@
|
|||
#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"
|
|
@ -0,0 +1,5 @@
|
|||
#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,6 +36,12 @@ static const struct grub_arg_option options[] =
|
|||
0, 0},
|
||||
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
|
||||
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,
|
||||
N_("Set a variable to the first device found."), N_("VARNAME"),
|
||||
ARG_TYPE_STRING},
|
||||
|
@ -71,6 +77,9 @@ enum options
|
|||
SEARCH_FILE,
|
||||
SEARCH_LABEL,
|
||||
SEARCH_FS_UUID,
|
||||
SEARCH_PART_LABEL,
|
||||
SEARCH_PART_UUID,
|
||||
SEARCH_DISK_UUID,
|
||||
SEARCH_SET,
|
||||
SEARCH_NO_FLOPPY,
|
||||
SEARCH_HINT,
|
||||
|
@ -122,7 +131,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++)
|
||||
nhints++;
|
||||
|
||||
hints = grub_calloc (nhints, sizeof (hints[0]));
|
||||
hints = grub_malloc (sizeof (hints[0]) * nhints);
|
||||
if (!hints)
|
||||
return grub_errno;
|
||||
j = 0;
|
||||
|
@ -186,6 +195,15 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
else if (state[SEARCH_FS_UUID].set)
|
||||
grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
|
||||
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)
|
||||
grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
|
||||
hints, nhints);
|
||||
|
|
|
@ -169,7 +169,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (ctxt->state[0].set)
|
||||
{
|
||||
ptr = ctxt->state[0].arg;
|
||||
pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff);
|
||||
pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
@ -182,7 +182,8 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (*ptr != ':')
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||
ptr++;
|
||||
pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16;
|
||||
pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff)
|
||||
<< 16;
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
else
|
||||
|
@ -196,10 +197,10 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (ctxt->state[1].set)
|
||||
{
|
||||
const char *optr;
|
||||
|
||||
|
||||
ptr = ctxt->state[1].arg;
|
||||
optr = ptr;
|
||||
bus = grub_strtoul (ptr, &ptr, 16);
|
||||
bus = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
@ -213,7 +214,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':');
|
||||
ptr++;
|
||||
optr = ptr;
|
||||
device = grub_strtoul (ptr, &ptr, 16);
|
||||
device = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
@ -224,7 +225,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (*ptr == '.')
|
||||
{
|
||||
ptr++;
|
||||
function = grub_strtoul (ptr, &ptr, 16);
|
||||
function = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
check_function = 1;
|
||||
|
@ -252,7 +253,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (i == ARRAY_SIZE (pci_registers))
|
||||
{
|
||||
regsize = 0;
|
||||
regaddr = grub_strtoul (ptr, &ptr, 16);
|
||||
regaddr = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown register");
|
||||
}
|
||||
|
@ -269,7 +270,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (*ptr == '+')
|
||||
{
|
||||
ptr++;
|
||||
regaddr += grub_strtoul (ptr, &ptr, 16);
|
||||
regaddr += grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
}
|
||||
|
@ -301,14 +302,14 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
if (*ptr == '=')
|
||||
{
|
||||
ptr++;
|
||||
regwrite = grub_strtoul (ptr, &ptr, 16);
|
||||
regwrite = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
write_mask = 0xffffffff;
|
||||
if (*ptr == ':')
|
||||
{
|
||||
ptr++;
|
||||
write_mask = grub_strtoul (ptr, &ptr, 16);
|
||||
write_mask = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
write_mask = 0xffffffff;
|
||||
|
|
|
@ -55,7 +55,7 @@ grub_interruptible_millisleep (grub_uint32_t ms)
|
|||
start = grub_get_time_ms ();
|
||||
|
||||
while (grub_get_time_ms () - start < ms)
|
||||
if (grub_key_is_interrupt (grub_getkey_noblock ()))
|
||||
if (grub_getkey_noblock () == GRUB_TERM_ESC)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* smbios.c - retrieve smbios information. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2013,2014,2015 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
|
||||
|
@ -27,111 +27,86 @@
|
|||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */
|
||||
static struct {
|
||||
grub_addr_t start;
|
||||
grub_addr_t end;
|
||||
grub_uint16_t structures;
|
||||
} table_desc;
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
/* Locate the SMBIOS entry point structure depending on the hardware. */
|
||||
struct grub_smbios_eps *
|
||||
grub_smbios_get_eps (void)
|
||||
{
|
||||
static struct grub_smbios_eps *eps = NULL;
|
||||
|
||||
if (eps != NULL)
|
||||
return eps;
|
||||
|
||||
eps = grub_machine_smbios_get_eps ();
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
/* Locate the SMBIOS3 entry point structure depending on the hardware. */
|
||||
static struct grub_smbios_eps3 *
|
||||
struct grub_smbios_eps3 *
|
||||
grub_smbios_get_eps3 (void)
|
||||
{
|
||||
static struct grub_smbios_eps3 *eps = NULL;
|
||||
|
||||
if (eps != NULL)
|
||||
return eps;
|
||||
|
||||
eps = grub_machine_smbios_get_eps3 ();
|
||||
|
||||
return eps;
|
||||
}
|
||||
|
||||
static char *
|
||||
linux_string (const char *value)
|
||||
{
|
||||
char *out = grub_malloc( grub_strlen (value) + 1);
|
||||
const char *src = value;
|
||||
char *dst = out;
|
||||
/* 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 = {0, 0, 0};
|
||||
|
||||
for (; *src; src++)
|
||||
if (*src > ' ' && *src < 127 && *src != ':')
|
||||
*dst++ = *src;
|
||||
|
||||
*dst = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions convert values from the various SMBIOS structure field types
|
||||
* into a string formatted to be returned to the user. They expect that the
|
||||
* structure and offset were already validated. When the requested data is
|
||||
* successfully retrieved and formatted, the pointer to the string is returned;
|
||||
* otherwise, NULL is returned on failure. Don't free the result.
|
||||
* structure and offset were already validated. The given buffer stores the
|
||||
* newly formatted string if needed. When the requested data is successfully
|
||||
* retrieved and formatted, the pointer to the string is returned; otherwise,
|
||||
* NULL is returned on failure.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
grub_smbios_format_byte (char *buffer, grub_size_t size,
|
||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("255")];
|
||||
|
||||
grub_snprintf (buffer, sizeof (buffer), "%u", structure[offset]);
|
||||
|
||||
grub_snprintf (buffer, size, "%u", structure[offset]);
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_word (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
grub_smbios_format_word (char *buffer, grub_size_t size,
|
||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("65535")];
|
||||
|
||||
grub_uint16_t value = grub_get_unaligned16 (structure + offset);
|
||||
grub_snprintf (buffer, sizeof (buffer), "%u", value);
|
||||
|
||||
grub_snprintf (buffer, size, "%u", value);
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_dword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
grub_smbios_format_dword (char *buffer, grub_size_t size,
|
||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("4294967295")];
|
||||
|
||||
grub_uint32_t value = grub_get_unaligned32 (structure + offset);
|
||||
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value);
|
||||
|
||||
grub_snprintf (buffer, size, "%" PRIuGRUB_UINT32_T, value);
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_qword (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
grub_smbios_format_qword (char *buffer, grub_size_t size,
|
||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("18446744073709551615")];
|
||||
|
||||
grub_uint64_t value = grub_get_unaligned64 (structure + offset);
|
||||
grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value);
|
||||
|
||||
grub_snprintf (buffer, size, "%" PRIuGRUB_UINT64_T, value);
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
/* The matching string pointer is returned directly to avoid extra copying. */
|
||||
static const char *
|
||||
grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
grub_smbios_get_string (char *buffer __attribute__ ((unused)),
|
||||
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 *table_end = (const grub_uint8_t *)table_desc.end;
|
||||
|
@ -160,24 +135,25 @@ grub_smbios_get_string (const grub_uint8_t *structure, grub_uint8_t offset)
|
|||
}
|
||||
|
||||
static const char *
|
||||
grub_smbios_format_uuid (const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
grub_smbios_format_uuid (char *buffer, grub_size_t size,
|
||||
const grub_uint8_t *structure, grub_uint8_t offset)
|
||||
{
|
||||
static char buffer[sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")];
|
||||
const grub_uint8_t *f = structure + offset; /* little-endian fields */
|
||||
const grub_uint8_t *g = f + 8; /* byte-by-byte fields */
|
||||
|
||||
grub_snprintf (buffer, sizeof (buffer),
|
||||
grub_snprintf (buffer, size,
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
|
||||
"%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
f[3], f[2], f[1], f[0], f[5], f[4], f[7], f[6],
|
||||
g[0], g[1], g[2], g[3], g[4], g[5], g[6], g[7]);
|
||||
|
||||
return (const char *)buffer;
|
||||
}
|
||||
|
||||
|
||||
/* List the field formatting functions and the number of bytes they need. */
|
||||
#define MAXIMUM_FORMAT_LENGTH (sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff"))
|
||||
static const struct {
|
||||
const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset);
|
||||
const char *(*format) (char *buffer, grub_size_t size,
|
||||
const grub_uint8_t *structure, grub_uint8_t offset);
|
||||
grub_uint8_t field_length;
|
||||
} field_extractors[] = {
|
||||
{grub_smbios_format_byte, 1},
|
||||
|
@ -191,12 +167,10 @@ static const struct {
|
|||
/* List command options, with structure field getters ordered as above. */
|
||||
#define FIRST_GETTER_OPT (3)
|
||||
#define SETTER_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors))
|
||||
#define LINUX_OPT (FIRST_GETTER_OPT + ARRAY_SIZE(field_extractors) + 1)
|
||||
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"type", 't', 0, N_("Match structures with the given type."),
|
||||
{"type", 't', 0, N_("Match entries with the given type."),
|
||||
N_("type"), ARG_TYPE_INT},
|
||||
{"handle", 'h', 0, N_("Match structures with the given handle."),
|
||||
{"handle", 'h', 0, N_("Match entries with the given handle."),
|
||||
N_("handle"), ARG_TYPE_INT},
|
||||
{"match", 'm', 0, N_("Select a structure when several match."),
|
||||
N_("match"), ARG_TYPE_INT},
|
||||
|
@ -214,11 +188,10 @@ static const struct grub_arg_option options[] = {
|
|||
N_("offset"), ARG_TYPE_INT},
|
||||
{"set", '\0', 0, N_("Store the value in the given variable name."),
|
||||
N_("variable"), ARG_TYPE_STRING},
|
||||
{"linux", '\0', 0, N_("Filter the result like linux does."),
|
||||
N_("variable"), ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Return a matching SMBIOS structure.
|
||||
*
|
||||
|
@ -252,6 +225,7 @@ grub_smbios_match_structure (const grub_int16_t type,
|
|||
&& (type < 0 || type == structure_type)
|
||||
&& (match == 0 || match == ++matches))
|
||||
return ptr;
|
||||
|
||||
else
|
||||
{
|
||||
ptr += ptr[1];
|
||||
|
@ -265,6 +239,7 @@ grub_smbios_match_structure (const grub_int16_t type,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
|
@ -279,7 +254,7 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
|||
|
||||
const grub_uint8_t *structure;
|
||||
const char *value;
|
||||
char *modified_value = NULL;
|
||||
char buffer[MAXIMUM_FORMAT_LENGTH];
|
||||
grub_int32_t option;
|
||||
grub_int8_t field_type = -1;
|
||||
grub_uint8_t i;
|
||||
|
@ -308,7 +283,7 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
|||
if (state[2].set)
|
||||
{
|
||||
option = grub_strtol (state[2].arg, NULL, 0);
|
||||
if (option <= 0 || option > 65535)
|
||||
if (option <= 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("the match must be a positive integer"));
|
||||
match = (grub_uint16_t)option;
|
||||
|
@ -348,25 +323,24 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt,
|
|||
N_("the field ends outside the structure"));
|
||||
|
||||
/* Format the requested structure field into a readable string. */
|
||||
value = field_extractors[field_type].format (structure, offset);
|
||||
value = field_extractors[field_type].format (buffer, sizeof (buffer),
|
||||
structure, offset);
|
||||
if (value == NULL)
|
||||
return grub_error (GRUB_ERR_IO,
|
||||
N_("failed to retrieve the structure field"));
|
||||
|
||||
if (state[LINUX_OPT].set)
|
||||
value = modified_value = linux_string (value);
|
||||
|
||||
/* Store or print the formatted value. */
|
||||
if (state[SETTER_OPT].set)
|
||||
grub_env_set (state[SETTER_OPT].arg, value);
|
||||
else
|
||||
grub_printf ("%s\n", value);
|
||||
|
||||
grub_free(modified_value);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(smbios)
|
||||
{
|
||||
struct grub_smbios_eps3 *eps3;
|
||||
|
|
|
@ -31,7 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||
|
||||
/* A simple implementation for signed numbers. */
|
||||
static int
|
||||
grub_strtosl (char *arg, const char ** const end, int base)
|
||||
grub_strtosl (char *arg, char **end, int base)
|
||||
{
|
||||
if (arg[0] == '-')
|
||||
return -grub_strtoul (arg + 1, end, base);
|
||||
|
|
|
@ -29,6 +29,13 @@
|
|||
|
||||
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
|
||||
grub_tpm_verify_init (grub_file_t io,
|
||||
enum grub_file_type type __attribute__ ((unused)),
|
||||
|
|
|
@ -196,8 +196,7 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type)
|
|||
return ret;
|
||||
|
||||
fail:
|
||||
if (ver->close)
|
||||
ver->close (context);
|
||||
ver->close (context);
|
||||
fail_noclose:
|
||||
verified_free (verified);
|
||||
grub_free (ret);
|
||||
|
@ -208,9 +207,6 @@ grub_err_t
|
|||
grub_verify_string (char *str, enum grub_verify_string_type type)
|
||||
{
|
||||
struct grub_file_verifier *ver;
|
||||
|
||||
grub_dprintf ("verify", "string: %s, type: %d\n", str, type);
|
||||
|
||||
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
|
||||
{
|
||||
grub_err_t err;
|
||||
|
|
|
@ -136,7 +136,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
|
|||
ctx.height = ctx.width = ctx.depth = 0;
|
||||
if (argc)
|
||||
{
|
||||
const char *ptr;
|
||||
char *ptr;
|
||||
ptr = args[0];
|
||||
ctx.width = grub_strtoul (ptr, &ptr, 0);
|
||||
if (grub_errno)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <grub/file.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
|
@ -49,7 +48,6 @@ merge (char **dest, char **ps)
|
|||
int i;
|
||||
int j;
|
||||
char **p;
|
||||
grub_size_t sz;
|
||||
|
||||
if (! dest)
|
||||
return ps;
|
||||
|
@ -62,12 +60,7 @@ merge (char **dest, char **ps)
|
|||
for (j = 0; ps[j]; j++)
|
||||
;
|
||||
|
||||
if (grub_add (i, j, &sz) ||
|
||||
grub_add (sz, 1, &sz) ||
|
||||
grub_mul (sz, sizeof (char *), &sz))
|
||||
return dest;
|
||||
|
||||
p = grub_realloc (dest, sz);
|
||||
p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
|
||||
if (! p)
|
||||
{
|
||||
grub_free (dest);
|
||||
|
@ -122,15 +115,8 @@ make_regex (const char *start, const char *end, regex_t *regexp)
|
|||
char ch;
|
||||
int i = 0;
|
||||
unsigned len = end - start;
|
||||
char *buffer;
|
||||
grub_size_t sz;
|
||||
char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
|
||||
|
||||
/* 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)
|
||||
return 1;
|
||||
|
||||
|
@ -240,7 +226,6 @@ match_devices_iter (const char *name, void *data)
|
|||
struct match_devices_ctx *ctx = data;
|
||||
char **t;
|
||||
char *buffer;
|
||||
grub_size_t sz;
|
||||
|
||||
/* skip partitions if asked to. */
|
||||
if (ctx->noparts && grub_strchr (name, ','))
|
||||
|
@ -254,16 +239,11 @@ match_devices_iter (const char *name, void *data)
|
|||
if (regexec (ctx->regexp, buffer, 0, 0, 0))
|
||||
{
|
||||
grub_dprintf ("expand", "not matched\n");
|
||||
fail:
|
||||
grub_free (buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (grub_add (ctx->ndev, 2, &sz) ||
|
||||
grub_mul (sz, sizeof (char *), &sz))
|
||||
goto fail;
|
||||
|
||||
t = grub_realloc (ctx->devs, sz);
|
||||
t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
|
||||
if (! t)
|
||||
{
|
||||
grub_free (buffer);
|
||||
|
@ -320,7 +300,6 @@ match_files_iter (const char *name,
|
|||
struct match_files_ctx *ctx = data;
|
||||
char **t;
|
||||
char *buffer;
|
||||
grub_size_t sz;
|
||||
|
||||
/* skip . and .. names */
|
||||
if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
|
||||
|
@ -336,14 +315,9 @@ match_files_iter (const char *name,
|
|||
if (! buffer)
|
||||
return 1;
|
||||
|
||||
if (grub_add (ctx->nfile, 2, &sz) ||
|
||||
grub_mul (sz, sizeof (char *), &sz))
|
||||
goto fail;
|
||||
|
||||
t = grub_realloc (ctx->files, sz);
|
||||
if (!t)
|
||||
t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
|
||||
if (! t)
|
||||
{
|
||||
fail:
|
||||
grub_free (buffer);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,9 @@
|
|||
*/
|
||||
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/mm.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,
|
||||
grub_uint8_t * dst, grub_size_t blocksize,
|
||||
grub_size_t blocknumbers);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2007,2010,2011,2019 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2003,2007,2010,2011 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
|
||||
|
@ -404,167 +404,6 @@ grub_cryptodisk_decrypt (struct grub_cryptodisk *dev,
|
|||
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
|
||||
grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize)
|
||||
{
|
||||
|
@ -757,8 +596,9 @@ grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
size, sector, dev->offset);
|
||||
|
||||
err = grub_disk_read (dev->source_disk,
|
||||
grub_disk_from_native_sector (disk, sector + dev->offset),
|
||||
0, size << disk->log_sector_size, buf);
|
||||
(sector << (disk->log_sector_size
|
||||
- GRUB_DISK_SECTOR_BITS)) + dev->offset, 0,
|
||||
size << disk->log_sector_size, buf);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err);
|
||||
|
@ -815,10 +655,12 @@ grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
}
|
||||
|
||||
/* Since ->write was called so disk.mod is loaded but be paranoid */
|
||||
sector = sector + dev->offset;
|
||||
|
||||
if (grub_disk_write_weak)
|
||||
err = grub_disk_write_weak (dev->source_disk,
|
||||
grub_disk_from_native_sector (disk, sector),
|
||||
(sector << (disk->log_sector_size
|
||||
- GRUB_DISK_SECTOR_BITS))
|
||||
+ dev->offset,
|
||||
0, size << disk->log_sector_size, tmp);
|
||||
else
|
||||
err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded");
|
||||
|
@ -1308,6 +1150,5 @@ GRUB_MOD_FINI (cryptodisk)
|
|||
{
|
||||
grub_disk_dev_unregister (&grub_cryptodisk_dev);
|
||||
cryptodisk_cleanup ();
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_procfs_unregister (&luks_script);
|
||||
}
|
||||
|
|
|
@ -969,8 +969,7 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
|
|||
for (p = vgp->lvs; p; p = p->next)
|
||||
{
|
||||
int cur_num;
|
||||
char *num;
|
||||
const char *end;
|
||||
char *num, *end;
|
||||
if (!p->fullname)
|
||||
continue;
|
||||
if (grub_strncmp (p->fullname, lv->fullname, len) != 0)
|
||||
|
@ -1135,7 +1134,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
|||
array->lvs->segments->node_count = nmemb;
|
||||
array->lvs->segments->raid_member_size = disk_size;
|
||||
array->lvs->segments->nodes
|
||||
= grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0]));
|
||||
= grub_zalloc (nmemb * sizeof (array->lvs->segments->nodes[0]));
|
||||
array->lvs->segments->stripe_size = stripe_size;
|
||||
for (i = 0; i < nmemb; i++)
|
||||
{
|
||||
|
@ -1227,7 +1226,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
|
|||
grub_partition_t p;
|
||||
for (p = disk->partition; p; p = p->parent)
|
||||
s++;
|
||||
pv->partmaps = xcalloc (s, sizeof (pv->partmaps[0]));
|
||||
pv->partmaps = xmalloc (s * sizeof (pv->partmaps[0]));
|
||||
s = 0;
|
||||
for (p = disk->partition; p; p = p->parent)
|
||||
pv->partmaps[s++] = xstrdup (p->partmap->name);
|
||||
|
|
|
@ -278,10 +278,14 @@ grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
|||
char name[10];
|
||||
|
||||
if (cd_drive && drive == cd_drive)
|
||||
return hook ("cd", hook_data);
|
||||
{
|
||||
grub_dprintf ("biosdisk", "iterating cd\n");
|
||||
return hook ("cd", hook_data);
|
||||
}
|
||||
|
||||
grub_snprintf (name, sizeof (name),
|
||||
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
|
||||
grub_dprintf ("biosdisk", "iterating %s\n", name);
|
||||
return hook (name, hook_data);
|
||||
}
|
||||
|
||||
|
@ -301,7 +305,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,
|
||||
GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
|
||||
{
|
||||
grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
|
||||
grub_dprintf ("biosdisk", "Read error when probing drive 0x%2x\n", drive);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -336,6 +340,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
int drive;
|
||||
struct grub_biosdisk_data *data;
|
||||
|
||||
grub_dprintf ("biosdisk", "opening %s\n", name);
|
||||
|
||||
drive = grub_biosdisk_get_drive (name);
|
||||
if (drive < 0)
|
||||
return grub_errno;
|
||||
|
@ -393,6 +399,11 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
(1 << disk->log_sector_size) < drp->bytes_per_sector;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,6 +439,9 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
if (! total_sectors)
|
||||
total_sectors = ((grub_uint64_t) data->cylinders)
|
||||
* 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;
|
||||
|
@ -440,12 +454,15 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
|
||||
disk->data = data;
|
||||
|
||||
grub_dprintf ("biosdisk", "opening %s succeeded\n", name);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_biosdisk_close (grub_disk_t disk)
|
||||
{
|
||||
grub_dprintf ("biosdisk", "closing %s\n", disk->name);
|
||||
grub_free (disk->data);
|
||||
}
|
||||
|
||||
|
@ -577,6 +594,9 @@ static grub_err_t
|
|||
grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
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)
|
||||
{
|
||||
grub_size_t len;
|
||||
|
@ -607,6 +627,9 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
{
|
||||
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)
|
||||
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
|
||||
one system. Using a slightly larger value to be safe. */
|
||||
table_size = 768;
|
||||
table = grub_calloc (table_size, sizeof (grub_uint64_t));
|
||||
table = grub_malloc (table_size * sizeof (grub_uint64_t));
|
||||
|
||||
if (!table)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <grub/msdos_partition.h>
|
||||
#include <grub/gpt_partition.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/misc.h>
|
||||
|
@ -290,7 +289,6 @@ make_vg (grub_disk_t disk,
|
|||
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_ldm_vblk)];
|
||||
unsigned i;
|
||||
grub_size_t sz;
|
||||
err = grub_disk_read (disk, cursec, 0,
|
||||
sizeof(vblk), &vblk);
|
||||
if (err)
|
||||
|
@ -325,8 +323,8 @@ make_vg (grub_disk_t disk,
|
|||
lv->segments->type = GRUB_DISKFILTER_MIRROR;
|
||||
lv->segments->node_count = 0;
|
||||
lv->segments->node_alloc = 8;
|
||||
lv->segments->nodes = grub_calloc (lv->segments->node_alloc,
|
||||
sizeof (*lv->segments->nodes));
|
||||
lv->segments->nodes = grub_zalloc (sizeof (*lv->segments->nodes)
|
||||
* lv->segments->node_alloc);
|
||||
if (!lv->segments->nodes)
|
||||
goto fail2;
|
||||
ptr = vblk[i].dynamic;
|
||||
|
@ -352,13 +350,7 @@ make_vg (grub_disk_t disk,
|
|||
grub_free (lv);
|
||||
goto fail2;
|
||||
}
|
||||
if (grub_add (*ptr, 1, &sz))
|
||||
{
|
||||
grub_free (lv->internal_id);
|
||||
grub_free (lv);
|
||||
goto fail2;
|
||||
}
|
||||
lv->name = grub_malloc (sz);
|
||||
lv->name = grub_malloc (*ptr + 1);
|
||||
if (!lv->name)
|
||||
{
|
||||
grub_free (lv->internal_id);
|
||||
|
@ -551,8 +543,8 @@ make_vg (grub_disk_t disk,
|
|||
{
|
||||
comp->segment_alloc = 8;
|
||||
comp->segment_count = 0;
|
||||
comp->segments = grub_calloc (comp->segment_alloc,
|
||||
sizeof (*comp->segments));
|
||||
comp->segments = grub_malloc (sizeof (*comp->segments)
|
||||
* comp->segment_alloc);
|
||||
if (!comp->segments)
|
||||
goto fail2;
|
||||
}
|
||||
|
@ -598,8 +590,8 @@ make_vg (grub_disk_t disk,
|
|||
}
|
||||
comp->segments->node_count = read_int (ptr + 1, *ptr);
|
||||
comp->segments->node_alloc = comp->segments->node_count;
|
||||
comp->segments->nodes = grub_calloc (comp->segments->node_alloc,
|
||||
sizeof (*comp->segments->nodes));
|
||||
comp->segments->nodes = grub_zalloc (sizeof (*comp->segments->nodes)
|
||||
* comp->segments->node_alloc);
|
||||
if (!lv->segments->nodes)
|
||||
goto fail2;
|
||||
}
|
||||
|
@ -607,13 +599,10 @@ make_vg (grub_disk_t disk,
|
|||
if (lv->segments->node_alloc == lv->segments->node_count)
|
||||
{
|
||||
void *t;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
|
||||
grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
|
||||
goto fail2;
|
||||
|
||||
t = grub_realloc (lv->segments->nodes, sz);
|
||||
lv->segments->node_alloc *= 2;
|
||||
t = grub_realloc (lv->segments->nodes,
|
||||
sizeof (*lv->segments->nodes)
|
||||
* lv->segments->node_alloc);
|
||||
if (!t)
|
||||
goto fail2;
|
||||
lv->segments->nodes = t;
|
||||
|
@ -734,13 +723,10 @@ make_vg (grub_disk_t disk,
|
|||
if (comp->segment_alloc == comp->segment_count)
|
||||
{
|
||||
void *t;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
|
||||
grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
|
||||
goto fail2;
|
||||
|
||||
t = grub_realloc (comp->segments, sz);
|
||||
comp->segment_alloc *= 2;
|
||||
t = grub_realloc (comp->segments,
|
||||
comp->segment_alloc
|
||||
* sizeof (*comp->segments));
|
||||
if (!t)
|
||||
goto fail2;
|
||||
comp->segments = t;
|
||||
|
@ -1031,7 +1017,7 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
|||
*nsectors = lv->size;
|
||||
if (*nsectors > max_nsectors)
|
||||
*nsectors = max_nsectors;
|
||||
*sectors = grub_calloc (*nsectors, sizeof (**sectors));
|
||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||
if (!*sectors)
|
||||
return grub_errno;
|
||||
for (i = 0; i < *nsectors; i++)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2007,2010,2011,2019 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2003,2007,2010,2011 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
|
||||
|
@ -75,7 +75,15 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
|||
char uuid[sizeof (header.uuid) + 1];
|
||||
char ciphername[sizeof (header.cipherName) + 1];
|
||||
char ciphermode[sizeof (header.cipherMode) + 1];
|
||||
char *cipheriv = NULL;
|
||||
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;
|
||||
|
||||
if (check_boot)
|
||||
|
@ -95,7 +103,6 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
|||
|| grub_be_to_cpu16 (header.version) != 1)
|
||||
return NULL;
|
||||
|
||||
grub_memset (uuid, 0, sizeof (uuid));
|
||||
optr = uuid;
|
||||
for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
|
||||
iptr++)
|
||||
|
@ -119,33 +126,183 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|
|||
grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec));
|
||||
hashspec[sizeof (header.hashSpec)] = 0;
|
||||
|
||||
newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
|
||||
if (!newdev)
|
||||
ciph = grub_crypto_lookup_cipher_by_name (ciphername);
|
||||
if (!ciph)
|
||||
{
|
||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
|
||||
ciphername);
|
||||
return NULL;
|
||||
newdev->offset = grub_be_to_cpu32 (header.payloadOffset);
|
||||
newdev->source_disk = NULL;
|
||||
newdev->log_sector_size = 9;
|
||||
newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
|
||||
grub_memcpy (newdev->uuid, uuid, sizeof (uuid));
|
||||
newdev->modname = "luks";
|
||||
}
|
||||
|
||||
/* Configure the cipher used for the bulk data. */
|
||||
cipher = grub_crypto_cipher_open (ciph);
|
||||
if (!cipher)
|
||||
return NULL;
|
||||
|
||||
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. */
|
||||
newdev->hash = grub_crypto_lookup_md_by_name (hashspec);
|
||||
if (!newdev->hash)
|
||||
hash = grub_crypto_lookup_md_by_name (hashspec);
|
||||
if (!hash)
|
||||
{
|
||||
grub_free (newdev);
|
||||
grub_crypto_cipher_close (cipher);
|
||||
grub_crypto_cipher_close (essiv_cipher);
|
||||
grub_crypto_cipher_close (secondary_cipher);
|
||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
|
||||
hashspec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = grub_cryptodisk_setcipher (newdev, ciphername, ciphermode);
|
||||
if (err)
|
||||
newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
|
||||
if (!newdev)
|
||||
{
|
||||
grub_free (newdev);
|
||||
grub_crypto_cipher_close (cipher);
|
||||
grub_crypto_cipher_close (essiv_cipher);
|
||||
grub_crypto_cipher_close (secondary_cipher);
|
||||
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));
|
||||
return newdev;
|
||||
}
|
||||
|
@ -179,7 +336,7 @@ luks_recover_key (grub_disk_t source,
|
|||
&& grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
|
||||
max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes);
|
||||
|
||||
split_key = grub_calloc (keysize, max_stripes);
|
||||
split_key = grub_malloc (keysize * max_stripes);
|
||||
if (!split_key)
|
||||
return grub_errno;
|
||||
|
||||
|
|
|
@ -1,687 +0,0 @@
|
|||
/*
|
||||
* 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,7 +25,6 @@
|
|||
#include <grub/lvm.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/misc.h>
|
||||
|
@ -34,20 +33,12 @@
|
|||
|
||||
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
|
||||
at the number. In case STR is not found, *P will be NULL and the
|
||||
return value will be 0. */
|
||||
static grub_uint64_t
|
||||
grub_lvm_getvalue (const char ** const p, const char *str)
|
||||
grub_lvm_getvalue (char **p, const char *str)
|
||||
{
|
||||
*p = grub_strstr (*p, str);
|
||||
if (! *p)
|
||||
|
@ -72,12 +63,12 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl)
|
|||
#endif
|
||||
|
||||
static int
|
||||
grub_lvm_check_flag (const char *p, const char *str, const char *flag)
|
||||
grub_lvm_check_flag (char *p, const char *str, const char *flag)
|
||||
{
|
||||
grub_size_t len_str = grub_strlen (str), len_flag = grub_strlen (flag);
|
||||
while (1)
|
||||
{
|
||||
const char *q;
|
||||
char *q;
|
||||
p = grub_strstr (p, str);
|
||||
if (! p)
|
||||
return 0;
|
||||
|
@ -104,34 +95,6 @@ grub_lvm_check_flag (const 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 *
|
||||
grub_lvm_detect (grub_disk_t disk,
|
||||
struct grub_diskfilter_pv_id *id,
|
||||
|
@ -139,12 +102,10 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
{
|
||||
grub_err_t err;
|
||||
grub_uint64_t mda_offset, mda_size;
|
||||
grub_size_t ptr;
|
||||
char buf[GRUB_LVM_LABEL_SIZE];
|
||||
char vg_id[GRUB_LVM_ID_STRLEN+1];
|
||||
char pv_id[GRUB_LVM_ID_STRLEN+1];
|
||||
char *metadatabuf, *mda_end, *vgname;
|
||||
const char *p, *q;
|
||||
char *metadatabuf, *p, *q, *vgname;
|
||||
struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
|
||||
struct grub_lvm_pv_header *pvh;
|
||||
struct grub_lvm_disk_locn *dlocn;
|
||||
|
@ -212,7 +173,7 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
first one. */
|
||||
|
||||
/* Allocate buffer space for the circular worst-case scenario. */
|
||||
metadatabuf = grub_calloc (2, mda_size);
|
||||
metadatabuf = grub_malloc (2 * mda_size);
|
||||
if (! metadatabuf)
|
||||
goto fail;
|
||||
|
||||
|
@ -244,31 +205,19 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
grub_le_to_cpu64 (rlocn->size) -
|
||||
grub_le_to_cpu64 (mdah->size));
|
||||
}
|
||||
p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
|
||||
|
||||
if (grub_add ((grub_size_t)metadatabuf,
|
||||
(grub_size_t)grub_le_to_cpu64 (rlocn->offset),
|
||||
&ptr))
|
||||
while (*q != ' ' && q < metadatabuf + mda_size)
|
||||
q++;
|
||||
|
||||
if (q == metadatabuf + mda_size)
|
||||
{
|
||||
error_parsing_metadata:
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("error parsing metadata");
|
||||
#endif
|
||||
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 = grub_malloc (vgname_len + 1);
|
||||
if (!vgname)
|
||||
|
@ -293,8 +242,6 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
|
||||
if (! vg)
|
||||
{
|
||||
struct cache_lv *cache_lvs = NULL;
|
||||
|
||||
/* First time we see this volume group. We've to create the
|
||||
whole volume group structure. */
|
||||
vg = grub_malloc (sizeof (*vg));
|
||||
|
@ -420,26 +367,8 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
{
|
||||
const char *iptr;
|
||||
char *optr;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
|
||||
+ 1 + 2 * s + 1);
|
||||
if (!lv->fullname)
|
||||
goto lvs_fail;
|
||||
|
||||
|
@ -497,7 +426,7 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
#endif
|
||||
goto lvs_fail;
|
||||
}
|
||||
lv->segments = grub_calloc (lv->segment_count, sizeof (*seg));
|
||||
lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count);
|
||||
seg = lv->segments;
|
||||
|
||||
for (i = 0; i < lv->segment_count; i++)
|
||||
|
@ -554,8 +483,8 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
if (seg->node_count != 1)
|
||||
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
|
||||
|
||||
seg->nodes = grub_calloc (seg->node_count,
|
||||
sizeof (*stripe));
|
||||
seg->nodes = grub_zalloc (sizeof (*stripe)
|
||||
* seg->node_count);
|
||||
stripe = seg->nodes;
|
||||
|
||||
p = grub_strstr (p, "stripes = [");
|
||||
|
@ -742,106 +671,6 @@ grub_lvm_detect (grub_disk_t disk,
|
|||
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
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
|
@ -918,58 +747,6 @@ 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))
|
||||
goto fail4;
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ grub_mdraid_detect (grub_disk_t disk,
|
|||
return NULL;
|
||||
|
||||
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,
|
||||
sizeof (role), &role))
|
||||
return NULL;
|
||||
|
|
|
@ -426,7 +426,7 @@ grub_xendisk_init (void)
|
|||
if (!ctr)
|
||||
return;
|
||||
|
||||
virtdisks = grub_calloc (ctr, sizeof (virtdisks[0]));
|
||||
virtdisks = grub_malloc (ctr * sizeof (virtdisks[0]));
|
||||
if (!virtdisks)
|
||||
return;
|
||||
if (grub_xenstore_dir ("device/vbd", fill, &ctr))
|
||||
|
|
|
@ -30,10 +30,14 @@ grub_machine_efiemu_init_tables (void)
|
|||
void *table;
|
||||
grub_err_t err;
|
||||
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 acpi = GRUB_EFI_ACPI_TABLE_GUID;
|
||||
|
||||
err = grub_efiemu_unregister_configuration_table (smbios);
|
||||
if (err)
|
||||
return err;
|
||||
err = grub_efiemu_unregister_configuration_table (smbios3);
|
||||
if (err)
|
||||
return err;
|
||||
err = grub_efiemu_unregister_configuration_table (acpi);
|
||||
|
@ -43,6 +47,20 @@ grub_machine_efiemu_init_tables (void)
|
|||
if (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 ();
|
||||
if (table)
|
||||
{
|
||||
|
@ -57,13 +75,6 @@ grub_machine_efiemu_init_tables (void)
|
|||
if (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;
|
||||
}
|
||||
|
|
|
@ -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_elfsyms = (struct grub_efiemu_elf_sym *)
|
||||
grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym));
|
||||
grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
|
||||
|
||||
/* Relocators */
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||
|
|
|
@ -554,11 +554,11 @@ grub_efiemu_mmap_sort_and_uniq (void)
|
|||
/* Initialize variables*/
|
||||
grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
|
||||
scanline_events = (struct grub_efiemu_mmap_scan *)
|
||||
grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2);
|
||||
grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
|
||||
|
||||
/* Number of chunks can't increase more than by factor of 2 */
|
||||
result = (grub_efi_memory_descriptor_t *)
|
||||
grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2);
|
||||
grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
|
||||
if (!result || !scanline_events)
|
||||
{
|
||||
grub_free (result);
|
||||
|
@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void)
|
|||
|
||||
/* Preallocate mmap */
|
||||
efiemu_mmap = (grub_efi_memory_descriptor_t *)
|
||||
grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t));
|
||||
grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
|
||||
if (!efiemu_mmap)
|
||||
{
|
||||
grub_efiemu_unload ();
|
||||
|
|
|
@ -39,7 +39,7 @@ static grub_size_t nvramsize;
|
|||
|
||||
/* Parse signed value */
|
||||
static int
|
||||
grub_strtosl (const char *arg, const char ** const end, int base)
|
||||
grub_strtosl (const char *arg, char **end, int base)
|
||||
{
|
||||
if (arg[0] == '-')
|
||||
return -grub_strtoul (arg + 1, end, base);
|
||||
|
@ -120,8 +120,7 @@ nvram_set (void * data __attribute__ ((unused)))
|
|||
grub_memset (nvram, 0, nvramsize);
|
||||
FOR_SORTED_ENV (var)
|
||||
{
|
||||
const char *guid;
|
||||
char *attr, *name, *varname;
|
||||
char *guid, *attr, *name, *varname;
|
||||
struct efi_variable *efivar;
|
||||
int len = 0;
|
||||
int i;
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <grub/unicode.h>
|
||||
#include <grub/fontformat.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -294,7 +293,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
|||
font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
|
||||
|
||||
/* Allocate the character index array. */
|
||||
font->char_index = grub_calloc (font->num_chars, sizeof (struct char_index_entry));
|
||||
font->char_index = grub_malloc (font->num_chars
|
||||
* sizeof (struct char_index_entry));
|
||||
if (!font->char_index)
|
||||
return 1;
|
||||
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
||||
|
@ -361,13 +361,9 @@ static char *
|
|||
read_section_as_string (struct font_file_section *section)
|
||||
{
|
||||
char *str;
|
||||
grub_size_t sz;
|
||||
grub_ssize_t ret;
|
||||
|
||||
if (grub_add (section->length, 1, &sz))
|
||||
return NULL;
|
||||
|
||||
str = grub_malloc (sz);
|
||||
str = grub_malloc (section->length + 1);
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
|
@ -532,12 +528,6 @@ grub_font_load (const char *filename)
|
|||
if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
|
||||
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);
|
||||
if (!font->name)
|
||||
goto fail;
|
||||
|
|
|
@ -301,7 +301,7 @@ grub_affs_read_symlink (grub_fshelp_node_t node)
|
|||
return 0;
|
||||
}
|
||||
latin1[symlink_size] = 0;
|
||||
utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size);
|
||||
utf8 = grub_malloc (symlink_size * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
||||
if (!utf8)
|
||||
{
|
||||
grub_free (latin1);
|
||||
|
@ -422,7 +422,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
|
|||
return 1;
|
||||
}
|
||||
|
||||
hashtable = grub_calloc (data->htsize, sizeof (*hashtable));
|
||||
hashtable = grub_zalloc (data->htsize * sizeof (*hashtable));
|
||||
if (!hashtable)
|
||||
return 1;
|
||||
|
||||
|
@ -628,7 +628,7 @@ grub_affs_label (grub_device_t device, char **label)
|
|||
len = file.namelen;
|
||||
if (len > sizeof (file.name))
|
||||
len = sizeof (file.name);
|
||||
*label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len);
|
||||
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
||||
if (*label)
|
||||
*grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0';
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <grub/btrfs.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/diskfilter.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -137,8 +136,6 @@ struct grub_btrfs_chunk_item
|
|||
#define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40
|
||||
#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80
|
||||
#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_uint16_t nstripes;
|
||||
grub_uint16_t nsubstripes;
|
||||
|
@ -332,13 +329,9 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
|
|||
if (desc->allocated < desc->depth)
|
||||
{
|
||||
void *newdata;
|
||||
grub_size_t sz;
|
||||
|
||||
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);
|
||||
desc->allocated *= 2;
|
||||
newdata = grub_realloc (desc->data, sizeof (desc->data[0])
|
||||
* desc->allocated);
|
||||
if (!newdata)
|
||||
return grub_errno;
|
||||
desc->data = newdata;
|
||||
|
@ -420,7 +413,7 @@ lower_bound (struct grub_btrfs_data *data,
|
|||
{
|
||||
desc->allocated = 16;
|
||||
desc->depth = 0;
|
||||
desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0]));
|
||||
desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated);
|
||||
if (!desc->data)
|
||||
return grub_errno;
|
||||
}
|
||||
|
@ -629,21 +622,16 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
|
|||
if (data->n_devices_attached > data->n_devices_allocated)
|
||||
{
|
||||
void *tmp;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
|
||||
grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
|
||||
grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
|
||||
goto fail;
|
||||
|
||||
data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
|
||||
data->n_devices_allocated = 2 * data->n_devices_attached + 1;
|
||||
data->devices_attached
|
||||
= grub_realloc (tmp = data->devices_attached,
|
||||
data->n_devices_allocated
|
||||
* sizeof (data->devices_attached[0]));
|
||||
if (!data->devices_attached)
|
||||
{
|
||||
data->devices_attached = tmp;
|
||||
|
||||
fail:
|
||||
if (ctx.dev_found)
|
||||
grub_device_close (ctx.dev_found);
|
||||
data->devices_attached = tmp;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -764,7 +752,7 @@ raid56_read_retry (struct grub_btrfs_data *data,
|
|||
grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY;
|
||||
grub_uint64_t i, failed_devices;
|
||||
|
||||
buffers = grub_calloc (nstripes, sizeof (*buffers));
|
||||
buffers = grub_zalloc (sizeof(*buffers) * nstripes);
|
||||
if (!buffers)
|
||||
goto cleanup;
|
||||
|
||||
|
@ -976,19 +964,14 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
|
|||
csize = (stripen + 1) * stripe_length - off;
|
||||
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_RAID1:
|
||||
{
|
||||
grub_dprintf ("btrfs", "RAID1 (copies: %d)\n", ++redundancy);
|
||||
grub_dprintf ("btrfs", "RAID1\n");
|
||||
stripen = 0;
|
||||
stripe_offset = off;
|
||||
csize = grub_le_to_cpu64 (chunk->size) - off;
|
||||
redundancy = 2;
|
||||
break;
|
||||
}
|
||||
case GRUB_BTRFS_CHUNK_TYPE_RAID0:
|
||||
|
@ -2177,7 +2160,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
|
|||
*nsectors = 64 * 2 - 1;
|
||||
if (*nsectors > max_nsectors)
|
||||
*nsectors = max_nsectors;
|
||||
*sectors = grub_calloc (*nsectors, sizeof (**sectors));
|
||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||
if (!*sectors)
|
||||
return grub_errno;
|
||||
for (i = 0; i < *nsectors; i++)
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/fshelp.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -704,7 +703,6 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
|||
{
|
||||
char *symlink;
|
||||
struct grub_fshelp_node *diro = node;
|
||||
grub_size_t sz;
|
||||
|
||||
if (! diro->inode_read)
|
||||
{
|
||||
|
@ -719,13 +717,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
|
||||
if (! symlink)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/datetime.h>
|
||||
#ifndef MODE_EXFAT
|
||||
#include <grub/fat.h>
|
||||
#else
|
||||
|
@ -597,7 +596,6 @@ struct grub_fat_iterate_context
|
|||
{
|
||||
#ifdef MODE_EXFAT
|
||||
struct grub_fat_dir_node dir;
|
||||
struct grub_fat_dir_entry entry;
|
||||
#else
|
||||
struct grub_fat_dir_entry dir;
|
||||
#endif
|
||||
|
@ -644,27 +642,27 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
|||
grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir));
|
||||
while (1)
|
||||
{
|
||||
struct grub_fat_dir_entry *dir = &ctxt->entry;
|
||||
struct grub_fat_dir_entry dir;
|
||||
|
||||
ctxt->offset += sizeof (*dir);
|
||||
ctxt->offset += sizeof (dir);
|
||||
|
||||
if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (*dir),
|
||||
(char *) dir)
|
||||
!= sizeof (*dir))
|
||||
if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir),
|
||||
(char *) &dir)
|
||||
!= sizeof (dir))
|
||||
break;
|
||||
|
||||
if (dir->entry_type == 0)
|
||||
if (dir.entry_type == 0)
|
||||
break;
|
||||
if (!(dir->entry_type & 0x80))
|
||||
if (!(dir.entry_type & 0x80))
|
||||
continue;
|
||||
|
||||
if (dir->entry_type == 0x85)
|
||||
if (dir.entry_type == 0x85)
|
||||
{
|
||||
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;
|
||||
for (i = 0; i < nsec; i++)
|
||||
{
|
||||
|
@ -707,7 +705,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
|||
|
||||
if (i != nsec)
|
||||
{
|
||||
ctxt->offset -= sizeof (*dir);
|
||||
ctxt->offset -= sizeof (dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -717,47 +715,20 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
|||
return 0;
|
||||
}
|
||||
/* Allocation bitmap. */
|
||||
if (dir->entry_type == 0x81)
|
||||
if (dir.entry_type == 0x81)
|
||||
continue;
|
||||
/* Upcase table. */
|
||||
if (dir->entry_type == 0x82)
|
||||
if (dir.entry_type == 0x82)
|
||||
continue;
|
||||
/* Volume label. */
|
||||
if (dir->entry_type == 0x83)
|
||||
if (dir.entry_type == 0x83)
|
||||
continue;
|
||||
grub_dprintf ("exfat", "unknown primary type 0x%02x\n",
|
||||
dir->entry_type);
|
||||
dir.entry_type);
|
||||
}
|
||||
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
|
||||
|
||||
static grub_err_t
|
||||
|
@ -885,29 +856,6 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
|
|||
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
|
||||
|
||||
static grub_err_t lookup_file (grub_fshelp_node_t node,
|
||||
|
@ -1017,19 +965,10 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
|||
#ifdef MODE_EXFAT
|
||||
if (!ctxt.dir.have_stream)
|
||||
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
|
||||
if (ctxt.dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
|
||||
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
|
||||
if (info.mtimeset == 0)
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
"invalid modification timestamp for %s", path);
|
||||
|
||||
if (hook (ctxt.filename, &info, hook_data))
|
||||
break;
|
||||
|
|
|
@ -1360,7 +1360,7 @@ grub_hfs_label (grub_device_t device, char **label)
|
|||
grub_size_t len = data->sblock.volname[0];
|
||||
if (len > sizeof (data->sblock.volname) - 1)
|
||||
len = sizeof (data->sblock.volname) - 1;
|
||||
*label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len);
|
||||
*label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1);
|
||||
if (*label)
|
||||
macroman_to_utf8 (*label, data->sblock.volname + 1,
|
||||
len + 1, 0);
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <grub/hfs.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/hfsplus.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -476,12 +475,8 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
|
|||
{
|
||||
char *symlink;
|
||||
grub_ssize_t numread;
|
||||
grub_size_t sz = node->size;
|
||||
|
||||
if (grub_add (sz, 1, &sz))
|
||||
return NULL;
|
||||
|
||||
symlink = grub_malloc (sz);
|
||||
symlink = grub_malloc (node->size + 1);
|
||||
if (!symlink)
|
||||
return 0;
|
||||
|
||||
|
@ -720,12 +715,12 @@ list_nodes (void *record, void *hook_arg)
|
|||
if (type == GRUB_FSHELP_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen),
|
||||
GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
|
||||
* GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
if (! filename)
|
||||
return 0;
|
||||
|
||||
keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname));
|
||||
keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname));
|
||||
if (!keyname)
|
||||
{
|
||||
grub_free (filename);
|
||||
|
@ -1012,7 +1007,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
|||
grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr);
|
||||
|
||||
label_len = grub_be_to_cpu16 (catkey->namelen);
|
||||
label_name = grub_calloc (label_len, sizeof (*label_name));
|
||||
label_name = grub_malloc (label_len * sizeof (*label_name));
|
||||
if (!label_name)
|
||||
{
|
||||
grub_free (node);
|
||||
|
@ -1034,7 +1029,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
|
|||
}
|
||||
}
|
||||
|
||||
*label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
*label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
if (! *label)
|
||||
{
|
||||
grub_free (label_name);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <grub/fshelp.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -332,7 +331,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len)
|
|||
int i;
|
||||
grub_uint16_t t[MAX_NAMELEN / 2 + 1];
|
||||
|
||||
p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
if (! p)
|
||||
return NULL;
|
||||
|
||||
|
@ -532,22 +531,11 @@ add_part (struct iterate_dir_ctx *ctx,
|
|||
int len2)
|
||||
{
|
||||
int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
|
||||
grub_size_t sz;
|
||||
char *new;
|
||||
|
||||
if (grub_add (size, len2, &sz) ||
|
||||
grub_add (sz, 1, &sz))
|
||||
ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1);
|
||||
if (! ctx->symlink)
|
||||
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);
|
||||
ctx->symlink[size + len2] = 0;
|
||||
}
|
||||
|
@ -572,24 +560,17 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
|||
{
|
||||
grub_size_t off = 0, csize = 1;
|
||||
char *old;
|
||||
grub_size_t sz;
|
||||
|
||||
csize = entry->len - 5;
|
||||
old = ctx->filename;
|
||||
if (ctx->filename_alloc)
|
||||
{
|
||||
off = grub_strlen (ctx->filename);
|
||||
if (grub_add (csize, off, &sz) ||
|
||||
grub_add (sz, 1, &sz))
|
||||
return GRUB_ERR_OUT_OF_RANGE;
|
||||
ctx->filename = grub_realloc (ctx->filename, sz);
|
||||
ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
off = 0;
|
||||
if (grub_add (csize, 1, &sz))
|
||||
return GRUB_ERR_OUT_OF_RANGE;
|
||||
ctx->filename = grub_zalloc (sz);
|
||||
ctx->filename = grub_zalloc (csize + 1);
|
||||
}
|
||||
if (!ctx->filename)
|
||||
{
|
||||
|
@ -640,12 +621,7 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
|||
is the length. Both are part of the `Component
|
||||
Record'. */
|
||||
if (ctx->symlink && !ctx->was_continue)
|
||||
{
|
||||
add_part (ctx, "/", 1);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
add_part (ctx, "/", 1);
|
||||
add_part (ctx, (char *) &entry->data[pos + 2],
|
||||
entry->data[pos + 1]);
|
||||
ctx->was_continue = (entry->data[pos] & 1);
|
||||
|
@ -664,11 +640,6 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
|||
add_part (ctx, "/", 1);
|
||||
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
|
||||
stored. */
|
||||
pos += entry->data[pos + 1] + 2;
|
||||
|
@ -805,18 +776,14 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
|||
if (node->have_dirents >= node->alloc_dirents)
|
||||
{
|
||||
struct grub_fshelp_node *new_node;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
|
||||
grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
|
||||
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
|
||||
grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
|
||||
goto fail_0;
|
||||
|
||||
new_node = grub_realloc (node, sz);
|
||||
node->alloc_dirents *= 2;
|
||||
new_node = grub_realloc (node,
|
||||
sizeof (struct grub_fshelp_node)
|
||||
+ ((node->alloc_dirents
|
||||
- ARRAY_SIZE (node->dirents))
|
||||
* sizeof (node->dirents[0])));
|
||||
if (!new_node)
|
||||
{
|
||||
fail_0:
|
||||
if (ctx.filename_alloc)
|
||||
grub_free (ctx.filename);
|
||||
grub_free (node);
|
||||
|
@ -832,18 +799,14 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
|||
* sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
|
||||
{
|
||||
struct grub_fshelp_node *new_node;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
|
||||
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
|
||||
grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
|
||||
grub_add (sz, grub_strlen (ctx.symlink), &sz))
|
||||
goto fail_1;
|
||||
|
||||
new_node = grub_realloc (node, sz);
|
||||
new_node = grub_realloc (node,
|
||||
sizeof (struct grub_fshelp_node)
|
||||
+ ((node->alloc_dirents
|
||||
- ARRAY_SIZE (node->dirents))
|
||||
* sizeof (node->dirents[0]))
|
||||
+ grub_strlen (ctx.symlink) + 1);
|
||||
if (!new_node)
|
||||
{
|
||||
fail_1:
|
||||
if (ctx.filename_alloc)
|
||||
grub_free (ctx.filename);
|
||||
grub_free (node);
|
||||
|
|
|
@ -556,8 +556,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
|
|||
grub_uint16_t *tmp;
|
||||
grub_size_t i;
|
||||
|
||||
buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
tmp = grub_calloc (len, sizeof (tmp[0]));
|
||||
buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
tmp = grub_malloc (len * sizeof (tmp[0]));
|
||||
if (!buf || !tmp)
|
||||
{
|
||||
grub_free (buf);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <grub/types.h>
|
||||
#include <grub/fshelp.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -267,7 +266,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|||
node->next_extent = node->block;
|
||||
node->cache_size = 0;
|
||||
|
||||
node->cache = grub_calloc (cache_size, sizeof (node->cache[0]));
|
||||
node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size);
|
||||
if (!node->cache)
|
||||
{
|
||||
grub_errno = 0;
|
||||
|
@ -308,15 +307,10 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|||
if (node->cache && node->cache_size >= node->cache_allocated)
|
||||
{
|
||||
struct cache_entry *e = node->cache;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
|
||||
goto fail;
|
||||
|
||||
e = grub_realloc (node->cache, sz);
|
||||
e = grub_realloc (node->cache,node->cache_allocated * 2
|
||||
* sizeof (e[0]));
|
||||
if (!e)
|
||||
{
|
||||
fail:
|
||||
grub_errno = 0;
|
||||
grub_free (node->cache);
|
||||
node->cache = 0;
|
||||
|
@ -483,16 +477,10 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
|
|||
grub_size_t len = grub_strlen (name);
|
||||
grub_uint8_t *name_u8;
|
||||
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));
|
||||
if (!*node)
|
||||
return 1;
|
||||
name_u8 = grub_malloc (sz);
|
||||
name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
||||
if (!name_u8)
|
||||
{
|
||||
grub_free (*node);
|
||||
|
@ -736,13 +724,8 @@ grub_sfs_label (grub_device_t device, char **label)
|
|||
data = grub_sfs_mount (disk);
|
||||
if (data)
|
||||
{
|
||||
grub_size_t sz, len = grub_strlen (data->label);
|
||||
|
||||
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);
|
||||
grub_size_t len = grub_strlen (data->label);
|
||||
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
||||
if (*label)
|
||||
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
|
||||
(const grub_uint8_t *) data->label,
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <grub/types.h>
|
||||
#include <grub/fshelp.h>
|
||||
#include <grub/deflate.h>
|
||||
#include <grub/safemath.h>
|
||||
#include <minilzo.h>
|
||||
|
||||
#include "xz.h"
|
||||
|
@ -460,17 +459,7 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
|
|||
{
|
||||
char *ret;
|
||||
grub_err_t err;
|
||||
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;
|
||||
ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
|
||||
|
||||
err = read_chunk (node->data, ret,
|
||||
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
||||
|
@ -517,16 +506,11 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
|||
|
||||
{
|
||||
grub_fshelp_node_t node;
|
||||
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);
|
||||
node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
||||
if (!node)
|
||||
return 0;
|
||||
grub_memcpy (node, dir, sz);
|
||||
grub_memcpy (node, dir,
|
||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
||||
if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
|
||||
return 1;
|
||||
|
||||
|
@ -534,15 +518,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
|||
{
|
||||
grub_err_t err;
|
||||
|
||||
if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
|
||||
grub_add (sz, sizeof (*node), &sz))
|
||||
return 0;
|
||||
|
||||
node = grub_malloc (sz);
|
||||
node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
grub_memcpy (node, dir, sz);
|
||||
grub_memcpy (node, dir,
|
||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
||||
|
||||
node->stsize--;
|
||||
err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
|
||||
|
@ -576,7 +557,6 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
|||
enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
|
||||
struct grub_squash_dirent di;
|
||||
struct grub_squash_inode ino;
|
||||
grub_size_t sz;
|
||||
|
||||
err = read_chunk (dir->data, &di, sizeof (di),
|
||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||
|
@ -609,16 +589,13 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
|||
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
|
||||
filetype = GRUB_FSHELP_SYMLINK;
|
||||
|
||||
if (grub_add (dir->stsize, 1, &sz) ||
|
||||
grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
|
||||
grub_add (sz, sizeof (*node), &sz))
|
||||
return 0;
|
||||
|
||||
node = grub_malloc (sz);
|
||||
node = grub_malloc (sizeof (*node)
|
||||
+ (dir->stsize + 1) * sizeof (dir->stack[0]));
|
||||
if (! node)
|
||||
return 0;
|
||||
|
||||
grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
|
||||
grub_memcpy (node, dir,
|
||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
||||
|
||||
node->ino = ino;
|
||||
node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
|
||||
|
@ -769,7 +746,7 @@ direct_read (struct grub_squash_data *data,
|
|||
struct grub_squash_cache_inode *ino,
|
||||
grub_off_t off, char *buf, grub_size_t len)
|
||||
{
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
grub_err_t err;
|
||||
grub_off_t cumulated_uncompressed_size = 0;
|
||||
grub_uint64_t a = 0;
|
||||
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)
|
||||
{
|
||||
char *n;
|
||||
n = grub_calloc (2, linksize + 1);
|
||||
n = grub_malloc (2 * (linksize + 1));
|
||||
if (!n)
|
||||
return grub_errno;
|
||||
grub_free (data->linkname);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <grub/charset.h>
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/udf.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -874,7 +873,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
|
|||
{
|
||||
unsigned i;
|
||||
utf16len = sz - 1;
|
||||
utf16 = grub_calloc (utf16len, sizeof (utf16[0]));
|
||||
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
|
||||
if (!utf16)
|
||||
return NULL;
|
||||
for (i = 0; i < utf16len; i++)
|
||||
|
@ -884,26 +883,16 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
|
|||
{
|
||||
unsigned i;
|
||||
utf16len = (sz - 1) / 2;
|
||||
utf16 = grub_calloc (utf16len, sizeof (utf16[0]));
|
||||
utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
|
||||
if (!utf16)
|
||||
return NULL;
|
||||
for (i = 0; i < utf16len; i++)
|
||||
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
||||
}
|
||||
if (!outbuf)
|
||||
{
|
||||
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);
|
||||
}
|
||||
outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
||||
if (outbuf)
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
|
||||
|
||||
fail:
|
||||
grub_free (utf16);
|
||||
return outbuf;
|
||||
}
|
||||
|
@ -965,10 +954,8 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
|||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
/* This is the parent directory. */
|
||||
|
@ -990,18 +977,11 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
|
|||
dirent.file_ident_length,
|
||||
(char *) raw))
|
||||
!= dirent.file_ident_length)
|
||||
{
|
||||
grub_free (child);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
filename = read_string (raw, dirent.file_ident_length, 0);
|
||||
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))
|
||||
{
|
||||
|
@ -1025,7 +1005,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
|||
grub_size_t sz = U64 (node->block.fe.file_size);
|
||||
grub_uint8_t *raw;
|
||||
const grub_uint8_t *ptr;
|
||||
char *out = NULL, *optr;
|
||||
char *out, *optr;
|
||||
|
||||
if (sz < 4)
|
||||
return NULL;
|
||||
|
@ -1033,16 +1013,14 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
|||
if (!raw)
|
||||
return NULL;
|
||||
if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
|
||||
goto fail_1;
|
||||
{
|
||||
grub_free (raw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (grub_mul (sz, 2, &sz) ||
|
||||
grub_add (sz, 1, &sz))
|
||||
goto fail_0;
|
||||
|
||||
out = grub_malloc (sz);
|
||||
out = grub_malloc (sz * 2 + 1);
|
||||
if (!out)
|
||||
{
|
||||
fail_0:
|
||||
grub_free (raw);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1053,17 +1031,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
|||
{
|
||||
grub_size_t s;
|
||||
if ((grub_size_t) (ptr - raw + 4) > sz)
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
if (!(ptr[2] == 0 && ptr[3] == 0))
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
s = 4 + ptr[1];
|
||||
if ((grub_size_t) (ptr - raw + s) > sz)
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 1:
|
||||
if (ptr[1])
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
/* Fallthrough. */
|
||||
case 2:
|
||||
/* in 4 bytes. out: 1 byte. */
|
||||
|
@ -1088,11 +1066,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
|||
if (optr != out)
|
||||
*optr++ = '/';
|
||||
if (!read_string (ptr + 4, s - 4, optr))
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
optr += grub_strlen (optr);
|
||||
break;
|
||||
default:
|
||||
goto fail_1;
|
||||
goto fail;
|
||||
}
|
||||
ptr += s;
|
||||
}
|
||||
|
@ -1100,7 +1078,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
|||
grub_free (raw);
|
||||
return out;
|
||||
|
||||
fail_1:
|
||||
fail:
|
||||
grub_free (raw);
|
||||
grub_free (out);
|
||||
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/fshelp.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -900,7 +899,6 @@ static struct grub_xfs_data *
|
|||
grub_xfs_mount (grub_disk_t disk)
|
||||
{
|
||||
struct grub_xfs_data *data = 0;
|
||||
grub_size_t sz;
|
||||
|
||||
data = grub_zalloc (sizeof (struct grub_xfs_data));
|
||||
if (!data)
|
||||
|
@ -915,11 +913,10 @@ grub_xfs_mount (grub_disk_t disk)
|
|||
if (!grub_xfs_sb_valid(data))
|
||||
goto fail;
|
||||
|
||||
if (grub_add (grub_xfs_inode_size (data),
|
||||
sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
|
||||
goto fail;
|
||||
|
||||
data = grub_realloc (data, sz);
|
||||
data = grub_realloc (data,
|
||||
sizeof (struct grub_xfs_data)
|
||||
- sizeof (struct grub_xfs_inode)
|
||||
+ grub_xfs_inode_size(data) + 1);
|
||||
|
||||
if (! data)
|
||||
goto fail;
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include <grub/deflate.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -142,10 +141,7 @@ ZAP_LEAF_NUMCHUNKS (int bs)
|
|||
static inline zap_leaf_chunk_t *
|
||||
ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx)
|
||||
{
|
||||
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
|
||||
return &((zap_leaf_chunk_t *) (l->l_entries
|
||||
+ (ZAP_LEAF_HASH_NUMENTRIES(bs) * 2)
|
||||
/ sizeof (grub_properly_aligned_t)))[idx];
|
||||
}
|
||||
|
@ -777,14 +773,11 @@ fill_vdev_info (struct grub_zfs_data *data,
|
|||
if (data->n_devices_attached > data->n_devices_allocated)
|
||||
{
|
||||
void *tmp;
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
|
||||
grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
|
||||
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);
|
||||
data->n_devices_allocated = 2 * data->n_devices_attached + 1;
|
||||
data->devices_attached
|
||||
= grub_realloc (tmp = data->devices_attached,
|
||||
data->n_devices_allocated
|
||||
* sizeof (data->devices_attached[0]));
|
||||
if (!data->devices_attached)
|
||||
{
|
||||
data->devices_attached = tmp;
|
||||
|
@ -3332,7 +3325,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
|
|||
}
|
||||
subvol->nkeys = 0;
|
||||
zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data);
|
||||
subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0]));
|
||||
subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0]));
|
||||
if (!subvol->keyring)
|
||||
{
|
||||
grub_free (fsname);
|
||||
|
@ -3475,18 +3468,14 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
|
|||
{
|
||||
char *nvpair;
|
||||
char *ret;
|
||||
grub_size_t size, sz;
|
||||
grub_size_t size;
|
||||
int found;
|
||||
|
||||
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
||||
&size, 0);
|
||||
if (!found)
|
||||
return 0;
|
||||
|
||||
if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz))
|
||||
return 0;
|
||||
|
||||
ret = grub_zalloc (sz);
|
||||
ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
|
||||
if (!ret)
|
||||
return 0;
|
||||
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
||||
|
@ -4347,7 +4336,7 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
|
|||
*nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
|
||||
if (*nsectors > max_nsectors)
|
||||
*nsectors = max_nsectors;
|
||||
*sectors = grub_calloc (*nsectors, sizeof (**sectors));
|
||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||
if (!*sectors)
|
||||
return grub_errno;
|
||||
for (i = 0; i < *nsectors; i++)
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/safemath.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/zfs/zfs.h>
|
||||
|
@ -83,13 +82,9 @@ grub_zfs_add_key (grub_uint8_t *key_in,
|
|||
int passphrase)
|
||||
{
|
||||
struct grub_zfs_wrap_key *key;
|
||||
grub_size_t sz;
|
||||
|
||||
if (!passphrase && keylen > 32)
|
||||
keylen = 32;
|
||||
if (grub_add (sizeof (*key), keylen, &sz))
|
||||
return GRUB_ERR_OUT_OF_RANGE;
|
||||
key = grub_malloc (sz);
|
||||
key = grub_malloc (sizeof (*key) + keylen);
|
||||
if (!key)
|
||||
return grub_errno;
|
||||
key->is_passphrase = passphrase;
|
||||
|
|
|
@ -230,7 +230,7 @@ circprog_set_state (void *vself, int visible, int start,
|
|||
static int
|
||||
parse_angle (const char *value)
|
||||
{
|
||||
const char *ptr;
|
||||
char *ptr;
|
||||
int angle;
|
||||
|
||||
angle = grub_strtol (value, &ptr, 10);
|
||||
|
|
|
@ -195,10 +195,7 @@ load_image (grub_gui_image_t self, const char *path)
|
|||
return grub_errno;
|
||||
|
||||
if (self->bitmap && (self->bitmap != self->raw_bitmap))
|
||||
{
|
||||
grub_video_bitmap_destroy (self->bitmap);
|
||||
self->bitmap = 0;
|
||||
}
|
||||
grub_video_bitmap_destroy (self->bitmap);
|
||||
if (self->raw_bitmap)
|
||||
grub_video_bitmap_destroy (self->raw_bitmap);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ canonicalize_path (const char *path)
|
|||
if (*p == '/')
|
||||
components++;
|
||||
|
||||
char **path_array = grub_calloc (components, sizeof (*path_array));
|
||||
char **path_array = grub_malloc (components * sizeof (*path_array));
|
||||
if (! path_array)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *pr
|
|||
ptr++;
|
||||
}
|
||||
|
||||
num = grub_strtoul (ptr, &ptr, 0);
|
||||
num = grub_strtoul (ptr, (char **) &ptr, 0);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
if (sig)
|
||||
|
|
|
@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix,
|
|||
box->content_height = 0;
|
||||
box->raw_pixmaps =
|
||||
(struct grub_video_bitmap **)
|
||||
grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *));
|
||||
grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
|
||||
box->scaled_pixmaps =
|
||||
(struct grub_video_bitmap **)
|
||||
grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *));
|
||||
grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
|
||||
|
||||
/* Initialize all pixmap pointers to NULL so that proper destruction can
|
||||
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 */
|
||||
|
||||
/* allocate and link in new table */
|
||||
q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft));
|
||||
q = (struct huft *) grub_zalloc ((z + 1) * sizeof (struct huft));
|
||||
if (! q)
|
||||
{
|
||||
if (h)
|
||||
|
|
|
@ -93,16 +93,13 @@ probe_caches (void)
|
|||
grub_arch_cache_ilinesz = 8 << (cache_type & 3);
|
||||
type = ARCH_ARMV6;
|
||||
break;
|
||||
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.
|
||||
*/
|
||||
case 0x80 ... 0x8f:
|
||||
grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf);
|
||||
grub_arch_cache_ilinesz = 4 << (cache_type & 0xf);
|
||||
type = ARCH_ARMV7;
|
||||
break;
|
||||
default:
|
||||
grub_fatal ("Unsupported cache type 0x%x", cache_type);
|
||||
}
|
||||
if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz)
|
||||
grub_arch_cache_max_linesz = grub_arch_cache_dlinesz;
|
||||
|
|
|
@ -71,7 +71,4 @@ grub_machine_fini (int flags)
|
|||
efi_call_1 (b->close_event, tmr_evt);
|
||||
|
||||
grub_efi_fini ();
|
||||
|
||||
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||
grub_efi_memory_fini ();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,4 @@ grub_machine_fini (int flags)
|
|||
return;
|
||||
|
||||
grub_efi_fini ();
|
||||
|
||||
if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
|
||||
grub_efi_memory_fini ();
|
||||
}
|
||||
|
|
|
@ -32,12 +32,21 @@
|
|||
#include <grub/env.h>
|
||||
#include <grub/cache.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/tpm.h>
|
||||
|
||||
/* Platforms where modules are in a readonly area of memory. */
|
||||
#if defined(GRUB_MACHINE_QEMU)
|
||||
#define GRUB_MODULES_MACHINE_READONLY
|
||||
#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"
|
||||
|
@ -686,6 +695,15 @@ grub_dl_load_file (const char *filename)
|
|||
void *core = 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);
|
||||
|
||||
file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE);
|
||||
|
@ -712,6 +730,9 @@ grub_dl_load_file (const char *filename)
|
|||
opens of the same device. */
|
||||
grub_file_close (file);
|
||||
|
||||
grub_tpm_measure(core, size, GRUB_BINARY_PCR, filename);
|
||||
grub_print_error();
|
||||
|
||||
mod = grub_dl_load_core (core, size);
|
||||
grub_free (core);
|
||||
if (! mod)
|
||||
|
|
|
@ -157,8 +157,7 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
|
|||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
|
||||
GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
|
||||
grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
|
||||
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
|
||||
for (;;) ;
|
||||
|
@ -203,7 +202,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
|||
|
||||
len = grub_strlen (var);
|
||||
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
||||
var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
|
||||
var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
|
||||
if (!var16)
|
||||
return grub_errno;
|
||||
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
||||
|
@ -238,7 +237,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
|||
|
||||
len = grub_strlen (var);
|
||||
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
||||
var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
|
||||
var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
|
||||
if (!var16)
|
||||
return NULL;
|
||||
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
||||
|
@ -274,6 +273,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
|||
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"
|
||||
|
||||
/* Search the mods section from the PE32/PE32+ image. This code uses
|
||||
|
@ -309,23 +336,13 @@ grub_efi_modules_addr (void)
|
|||
}
|
||||
|
||||
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
|
||||
+ section->virtual_address);
|
||||
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;
|
||||
}
|
||||
if (info->magic != GRUB_MODULE_MAGIC)
|
||||
return 0;
|
||||
|
||||
grub_dprintf("sections", "returning section info for section %d: \"%s\"\n",
|
||||
i, section->name);
|
||||
return (grub_addr_t) info;
|
||||
}
|
||||
|
||||
|
@ -343,7 +360,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
|||
|
||||
dp = dp0;
|
||||
|
||||
while (dp)
|
||||
while (1)
|
||||
{
|
||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
|
@ -353,15 +370,9 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
|||
if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
||||
&& subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
|
||||
{
|
||||
grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
|
||||
|
||||
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);
|
||||
grub_efi_uint16_t len;
|
||||
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
||||
/ sizeof (grub_efi_char16_t));
|
||||
filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
|
||||
}
|
||||
|
||||
|
@ -377,7 +388,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
|||
if (!name)
|
||||
return NULL;
|
||||
|
||||
while (dp)
|
||||
while (1)
|
||||
{
|
||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
|
@ -393,21 +404,14 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
|
|||
|
||||
*p++ = '/';
|
||||
|
||||
len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
|
||||
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);
|
||||
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
||||
/ sizeof (grub_efi_char16_t));
|
||||
fp = (grub_efi_file_path_device_path_t *) dp;
|
||||
/* According to EFI spec Path Name is NULL terminated */
|
||||
while (len > 0 && fp->path_name[len - 1] == 0)
|
||||
len--;
|
||||
|
||||
dup_name = grub_calloc (len, sizeof (*dup_name));
|
||||
dup_name = grub_malloc (len * sizeof (*dup_name));
|
||||
if (!dup_name)
|
||||
{
|
||||
grub_free (name);
|
||||
|
@ -476,26 +480,7 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
|
|||
;
|
||||
p = GRUB_EFI_NEXT_DEVICE_PATH (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;
|
||||
total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
||||
break;
|
||||
}
|
||||
|
@ -540,7 +525,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
|||
void
|
||||
grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
{
|
||||
while (GRUB_EFI_DEVICE_PATH_VALID (dp))
|
||||
while (1)
|
||||
{
|
||||
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
|
||||
grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
|
||||
|
@ -952,10 +937,7 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
|
|||
/* Return non-zero. */
|
||||
return 1;
|
||||
|
||||
if (dp1 == dp2)
|
||||
return 0;
|
||||
|
||||
while (GRUB_EFI_DEVICE_PATH_VALID (dp1) && GRUB_EFI_DEVICE_PATH_VALID (dp2))
|
||||
while (1)
|
||||
{
|
||||
grub_efi_uint8_t type1, type2;
|
||||
grub_efi_uint8_t subtype1, subtype2;
|
||||
|
@ -991,14 +973,5 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -80,4 +80,5 @@ grub_efi_fini (void)
|
|||
{
|
||||
grub_efidisk_fini ();
|
||||
grub_console_fini ();
|
||||
grub_efi_memory_fini ();
|
||||
}
|
||||
|
|
|
@ -49,6 +49,38 @@ static grub_efi_uintn_t finish_desc_size;
|
|||
static grub_efi_uint32_t finish_desc_version;
|
||||
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'll free on exit.
|
||||
|
@ -125,20 +157,12 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
|||
|
||||
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("invalid memory address (0x%llx > 0x%llx)"),
|
||||
address, GRUB_EFI_MAX_USABLE_ADDRESS);
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (address == 0)
|
||||
{
|
||||
|
@ -148,10 +172,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
|||
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||
grub_efi_free_pages (0, pages);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_efi_store_alloc (address, pages);
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
#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…
Reference in New Issue