Compare commits

..

No commits in common. "master" and "grub-2.12" have entirely different histories.

291 changed files with 1616 additions and 31266 deletions

6
.gitignore vendored
View file

@ -11,6 +11,7 @@
*.img *.img
*.log *.log
*.lst *.lst
!/grub-core/extra_deps.lst
*.marker *.marker
*.mod *.mod
*.o *.o
@ -104,7 +105,6 @@ widthspec.bin
/docs/version-dev.texi /docs/version-dev.texi
/docs/version.texi /docs/version.texi
/ehci_test /ehci_test
/erofs_test
/example_grub_script_test /example_grub_script_test
/example_scripted_test /example_scripted_test
/example_unit_test /example_unit_test
@ -141,12 +141,10 @@ widthspec.bin
/grub-core/kernel.img.bin /grub-core/kernel.img.bin
/grub-core/lib/gnulib /grub-core/lib/gnulib
/grub-core/lib/libgcrypt-grub /grub-core/lib/libgcrypt-grub
/grub-core/lib/libtasn1-grub
/grub-core/modinfo.sh /grub-core/modinfo.sh
/grub-core/rs_decoder.h /grub-core/rs_decoder.h
/grub-core/symlist.c /grub-core/symlist.c
/grub-core/symlist.h /grub-core/symlist.h
/grub-core/tests/asn1/tests
/grub-core/trigtables.c /grub-core/trigtables.c
/grub-core/unidata.c /grub-core/unidata.c
/grub-editenv /grub-editenv
@ -171,8 +169,6 @@ widthspec.bin
/grub-ofpathname.exe /grub-ofpathname.exe
/grub-probe /grub-probe
/grub-probe.exe /grub-probe.exe
/grub-protect
/grub-protect.exe
/grub-reboot /grub-reboot
/grub-render-label /grub-render-label
/grub-render-label.exe /grub-render-label.exe

View file

@ -74,19 +74,18 @@ Prerequisites for make-check:
* wamerican, for grub-fs-tester * wamerican, for grub-fs-tester
* mtools, FAT tools for EFI platforms * mtools, FAT tools for EFI platforms
* xfonts-unifont, for the functional tests * xfonts-unifont, for the functional tests
* swtpm-tools and tpm2-tools, for TPM2 key protector tests
* If running a Linux kernel the following modules must be loaded: * If running a Linux kernel the following modules must be loaded:
- fuse, loop - fuse, loop
- btrfs, erofs, ext4, f2fs, fat, hfs, hfsplus, jfs, mac-roman, minix, nilfs2, - btrfs, ext4, f2fs, fat, hfs, hfsplus, jfs, mac-roman, minix, nilfs2,
reiserfs, udf, xfs reiserfs, udf, xfs
- On newer kernels, the exfat kernel modules may be used instead of the - On newer kernels, the exfat kernel modules may be used instead of the
exfat FUSE filesystem exfat FUSE filesystem
* The following are Debian named packages required mostly for the full * The following are Debian named packages required mostly for the full
suite of filesystem testing (but some are needed by other tests as well): suite of filesystem testing (but some are needed by other tests as well):
- btrfs-progs, dosfstools, e2fsprogs, erofs-utils, exfatprogs, exfat-fuse, - btrfs-progs, dosfstools, e2fsprogs, exfat-utils, f2fs-tools, genromfs,
f2fs-tools, genromfs, hfsprogs, jfsutils, nilfs-tools, ntfs-3g, hfsprogs, jfsutils, nilfs-tools, ntfs-3g, reiserfsprogs, squashfs-tools,
reiserfsprogs, squashfs-tools, reiserfsprogs, udftools, xfsprogs, zfs-fuse reiserfsprogs, udftools, xfsprogs, zfs-fuse
- exfat-fuse, if not using the exfat kernel module - exfat-fuse, if not using the exfat kernel module
- gzip, lzop, xz-utils - gzip, lzop, xz-utils
- attr, cpio, g++, gawk, parted, recode, tar, util-linux - attr, cpio, g++, gawk, parted, recode, tar, util-linux

View file

@ -40,7 +40,6 @@ library = {
common = grub-core/disk/luks.c; common = grub-core/disk/luks.c;
common = grub-core/disk/luks2.c; common = grub-core/disk/luks2.c;
common = grub-core/disk/geli.c; common = grub-core/disk/geli.c;
common = grub-core/disk/key_protector.c;
common = grub-core/disk/cryptodisk.c; common = grub-core/disk/cryptodisk.c;
common = grub-core/disk/AFSplitter.c; common = grub-core/disk/AFSplitter.c;
common = grub-core/lib/pbkdf2.c; common = grub-core/lib/pbkdf2.c;
@ -99,7 +98,6 @@ library = {
common = grub-core/fs/cpio_be.c; common = grub-core/fs/cpio_be.c;
common = grub-core/fs/odc.c; common = grub-core/fs/odc.c;
common = grub-core/fs/newc.c; common = grub-core/fs/newc.c;
common = grub-core/fs/erofs.c;
common = grub-core/fs/ext2.c; common = grub-core/fs/ext2.c;
common = grub-core/fs/fat.c; common = grub-core/fs/fat.c;
common = grub-core/fs/exfat.c; common = grub-core/fs/exfat.c;
@ -208,32 +206,6 @@ program = {
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
}; };
program = {
name = grub-protect;
mansection = 1;
common = grub-core/kern/emu/argp_common.c;
common = grub-core/osdep/init.c;
common = grub-core/lib/tss2/buffer.c;
common = grub-core/lib/tss2/tss2_mu.c;
common = grub-core/lib/tss2/tpm2_cmd.c;
common = grub-core/commands/tpm2_key_protector/args.c;
common = grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c;
common = util/grub-protect.c;
common = util/probe.c;
cflags = '-I$(srcdir)/grub-core/lib/tss2 -I$(srcdir)/grub-core/commands/tpm2_key_protector';
ldadd = libgrubmods.a;
ldadd = libgrubgcry.a;
ldadd = libgrubkern.a;
ldadd = grub-core/lib/gnulib/libgnu.a;
ldadd = '$(LIBTASN1)';
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
condition = COND_GRUB_PROTECT;
};
program = { program = {
name = grub-mkrelpath; name = grub-mkrelpath;
mansection = 1; mansection = 1;
@ -791,12 +763,6 @@ script = {
dependencies = 'garbage-gen$(BUILD_EXEEXT)'; dependencies = 'garbage-gen$(BUILD_EXEEXT)';
}; };
script = {
testcase = native;
name = erofs_test;
common = tests/erofs_test.in;
};
script = { script = {
testcase = native; testcase = native;
name = ext234_test; name = ext234_test;
@ -1284,18 +1250,6 @@ script = {
common = tests/luks2_test.in; common = tests/luks2_test.in;
}; };
script = {
testcase = native;
name = asn1_test;
common = tests/asn1_test.in;
};
script = {
testcase = native;
name = tpm2_key_protector_test;
common = tests/tpm2_key_protector_test.in;
};
program = { program = {
testcase = native; testcase = native;
name = example_unit_test; name = example_unit_test;

View file

@ -51,39 +51,6 @@ for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul
cp grub-core/lib/libgcrypt-grub/mpi/generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" cp grub-core/lib/libgcrypt-grub/mpi/generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x"
done done
echo "Importing libtasn1..."
if [ -d grub-core/lib/libtasn1-grub ]; then
rm -rf grub-core/lib/libtasn1-grub
fi
mkdir -p grub-core/lib/libtasn1-grub/lib
cp grub-core/lib/libtasn1/lib/*.[ch] grub-core/lib/libtasn1-grub/lib
cp grub-core/lib/libtasn1/libtasn1.h grub-core/lib/libtasn1-grub/
if [ -d grub-core/tests/asn1/tests ]; then
rm -rf grub-core/tests/asn1/tests
fi
mkdir grub-core/tests/asn1/tests
cp grub-core/lib/libtasn1/tests/*.[ch] grub-core/tests/asn1/tests
for patch in \
0001-libtasn1-disable-code-not-needed-in-grub.patch \
0002-libtasn1-replace-strcat-with-strcpy-in-_asn1_str_cat.patch \
0003-libtasn1-replace-strcat-with-_asn1_str_cat.patch \
0004-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch \
0005-libtasn1-Use-grub_divmod64-for-division.patch \
0006-libtasn1-fix-the-potential-buffer-overrun.patch \
0007-asn1_test-include-asn1_test.h-only.patch \
0008-asn1_test-rename-the-main-functions-to-the-test-name.patch \
0009-asn1_test-return-either-0-or-1-to-reflect-the-result.patch \
0010-asn1_test-remove-verbose-and-the-unnecessary-printf.patch \
0011-asn1_test-print-the-error-messages-with-grub_printf.patch \
0012-asn1_test-use-the-grub-specific-functions-and-types.patch \
0013-asn1_test-enable-the-testcase-only-when-GRUB_LONG_MA.patch ; do
patch -p1 -i grub-core/lib/libtasn1-patches/$patch
done
echo "Generating Automake input..." echo "Generating Automake input..."
# Automake doesn't like including files from a path outside the project. # Automake doesn't like including files from a path outside the project.

View file

@ -84,14 +84,7 @@ bootstrap_post_import_hook () {
# Instead of patching our gnulib and therefore maintaining a fork, submit # Instead of patching our gnulib and therefore maintaining a fork, submit
# changes to gnulib and update the hash above when they've merged. Do not # changes to gnulib and update the hash above when they've merged. Do not
# add new patches here. # add new patches here.
for patchname in fix-width \ patch -d grub-core/lib/gnulib -p2 < grub-core/lib/gnulib-patches/fix-width.patch
fix-regcomp-resource-leak \
fix-regexec-resource-leak \
fix-gcc-15-compile \
fix-unused-value; do
patch -d grub-core/lib/gnulib -p2 \
< "grub-core/lib/gnulib-patches/$patchname.patch"
done
for patchname in \ for patchname in \
0001-Support-POTFILES-shell \ 0001-Support-POTFILES-shell \

View file

@ -111,7 +111,6 @@ MOD_FILES =
MODULE_FILES = MODULE_FILES =
MARKER_FILES = MARKER_FILES =
KERNEL_HEADER_FILES = KERNEL_HEADER_FILES =
EXTRA_DEPS =
bin_SCRIPTS = bin_SCRIPTS =
bin_PROGRAMS = bin_PROGRAMS =

View file

@ -29,19 +29,12 @@ EXTRA_DIST += grub-core/genemuinit.sh
EXTRA_DIST += grub-core/genemuinitheader.sh EXTRA_DIST += grub-core/genemuinitheader.sh
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regexec-resource-leak.patch
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-gcc-15-compile.patch
EXTRA_DIST += grub-core/lib/gnulib-patches/fix-unused-value.patch
EXTRA_DIST += grub-core/lib/libgcrypt EXTRA_DIST += grub-core/lib/libgcrypt
EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic
EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h')
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h')
EXTRA_DIST += grub-core/efiemu/runtime/config.h EXTRA_DIST += grub-core/efiemu/runtime/config.h
EXTRA_DIST += grub-core/tests/asn1/asn1_test.h
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/tests/asn1/tests -name '*.h')
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/commands/tpm2_key_protector -name '*.h')
EXTRA_DIST += grub-core/lib/LzmaDec.c EXTRA_DIST += grub-core/lib/LzmaDec.c

View file

@ -34,7 +34,7 @@ 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 the target type. See INSTALL for full list of variables and
dnl description of the relationships between them. dnl description of the relationships between them.
AC_INIT([GRUB],[2.13],[bug-grub@gnu.org]) AC_INIT([GRUB],[2.12],[bug-grub@gnu.org])
AS_CASE(["$ERROR_PLATFORM_NOT_SUPPORT_SSP"], AS_CASE(["$ERROR_PLATFORM_NOT_SUPPORT_SSP"],
[n | no | nO | N | No | NO], [ERROR_PLATFORM_NOT_SUPPORT_SSP=no], [n | no | nO | N | No | NO], [ERROR_PLATFORM_NOT_SUPPORT_SSP=no],
@ -76,7 +76,6 @@ grub_TRANSFORM([grub-mkpasswd-pbkdf2])
grub_TRANSFORM([grub-mkrelpath]) grub_TRANSFORM([grub-mkrelpath])
grub_TRANSFORM([grub-mkrescue]) grub_TRANSFORM([grub-mkrescue])
grub_TRANSFORM([grub-probe]) grub_TRANSFORM([grub-probe])
grub_TRANSFORM([grub-protect])
grub_TRANSFORM([grub-reboot]) grub_TRANSFORM([grub-reboot])
grub_TRANSFORM([grub-script-check]) grub_TRANSFORM([grub-script-check])
grub_TRANSFORM([grub-set-default]) grub_TRANSFORM([grub-set-default])
@ -803,17 +802,6 @@ if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then
if test "x$grub_cv_cc_mflush_func" = xyes; then if test "x$grub_cv_cc_mflush_func" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring" TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring"
fi fi
AC_CACHE_CHECK([whether -mno-gpopt works], [grub_cv_cc_mno_gpopt], [
CFLAGS="$TARGET_CFLAGS -mno-gpopt -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[grub_cv_cc_mno_gpopt=yes],
[grub_cv_cc_mno_gpopt=no])
])
if test "x$grub_cv_cc_mno_gpopt" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mno-gpopt"
fi
fi fi
@ -913,31 +901,6 @@ if test "x$target_cpu" = xloongarch64; then
TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs"
fi fi
if test "x$target_cpu" = xriscv64 || test "x$target_cpu" = xriscv32; then
AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [
grub_cv_target_cc_mno_relax=no
for cand in "-mno-relax" "-Wa,-mno-relax"; do
if test x"$grub_cv_target_cc_mno_relax" != xno ; then
break
fi
CFLAGS="$TARGET_CFLAGS $cand -Werror"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
asm (".globl start; start:");
void __main (void);
void __main (void) {}
int main (void);
]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], [])
done
])
CFLAGS="$TARGET_CFLAGS"
if test x"$grub_cv_target_cc_mno_relax" != xno ; then
TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_relax"
TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mno_relax"
fi
fi
# GRUB doesn't use float or doubles at all. Yet some toolchains may decide # GRUB doesn't use float or doubles at all. Yet some toolchains may decide
# that floats are a good fit to run instead of what's written in the code. # that floats are a good fit to run instead of what's written in the code.
# Given that floating point unit is disabled (if present to begin with) # Given that floating point unit is disabled (if present to begin with)
@ -1884,7 +1847,7 @@ if test "x$with_dejavufont" = x; then
# search in well-known directories # search in well-known directories
if test x"$starfield_excuse" = x; then if test x"$starfield_excuse" = x; then
for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype /usr/pkg/share/fonts/X11/TTF /usr/local/share/fonts/dejavu /usr/X11R6/lib/X11/fonts/TTF /usr/share/fonts/dejavu-sans-fonts /usr/share/fonts/truetype/dejavu; do for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype /usr/pkg/share/fonts/X11/TTF /usr/local/share/fonts/dejavu /usr/X11R6/lib/X11/fonts/TTF; do
if test -f "$dir/DejaVuSans.$ext"; then if test -f "$dir/DejaVuSans.$ext"; then
DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext" DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext"
break 2 break 2
@ -1912,7 +1875,7 @@ AC_ARG_WITH([unifont],
if test "x$with_unifont" = x; then if test "x$with_unifont" = x; then
# search in well-known directories # search in well-known directories
for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz otf otf.gz; do for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc /usr/pkg/share/fonts/X11/misc /usr/local/share/fonts/gnu-unifont /usr/local/share/fonts/unifont; do for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc /usr/pkg/share/fonts/X11/misc /usr/local/share/fonts/gnu-unifont /usr/local/share/fonts/unifont; do
if test -f "$dir/unifont.$ext"; then if test -f "$dir/unifont.$ext"; then
md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')" md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')"
@ -2094,29 +2057,6 @@ fi
AC_SUBST([LIBZFS]) AC_SUBST([LIBZFS])
AC_SUBST([LIBNVPAIR]) AC_SUBST([LIBNVPAIR])
AC_ARG_ENABLE([grub-protect],
[AS_HELP_STRING([--enable-grub-protect],
[build and install the `grub-protect' utility (default=guessed)])])
if test x"$enable_grub_protect" = xno ; then
grub_protect_excuse="explicitly disabled"
fi
LIBTASN1=
if test x"$grub_protect_excuse" = x ; then
AC_CHECK_LIB([tasn1], [asn1_write_value], [LIBTASN1="-ltasn1"], [grub_protect_excuse="need libtasn1 library"])
fi
AC_SUBST([LIBTASN1])
if test x"$enable_grub_protect" = xyes && test x"$grub_protect_excuse" != x ; then
AC_MSG_ERROR([grub-protect was explicitly requested but can't be compiled ($grub_protect_excuse)])
fi
if test x"$grub_protect_excuse" = x ; then
enable_grub_protect=yes
else
enable_grub_protect=no
fi
AC_SUBST([enable_grub_protect])
LIBS="" LIBS=""
AC_SUBST([FONT_SOURCE]) AC_SUBST([FONT_SOURCE])
@ -2233,7 +2173,6 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes])
AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes])
AM_CONDITIONAL([COND_GRUB_PROTECT], [test x$enable_grub_protect = xyes])
AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
if test x$FONT_SOURCE != x ; then if test x$FONT_SOURCE != x ; then
HAVE_FONT_SOURCE=1 HAVE_FONT_SOURCE=1
@ -2361,11 +2300,6 @@ echo grub-mount: Yes
else else
echo grub-mount: No "($grub_mount_excuse)" echo grub-mount: No "($grub_mount_excuse)"
fi fi
if [ x"$grub_protect_excuse" = x ]; then
echo grub-protect: Yes
else
echo grub-protect: No "($grub_protect_excuse)"
fi
if [ x"$starfield_excuse" = x ]; then if [ x"$starfield_excuse" = x ]; then
echo starfield theme: Yes echo starfield theme: Yes
echo With DejaVuSans font from $DJVU_FONT_SOURCE echo With DejaVuSans font from $DJVU_FONT_SOURCE

View file

@ -506,7 +506,6 @@ to update it.
* Gnulib:: * Gnulib::
* jsmn:: * jsmn::
* minilzo:: * minilzo::
* libtasn1::
@end menu @end menu
@node Gnulib @node Gnulib
@ -597,40 +596,6 @@ cp minilzo-2.10/*.[hc] grub-core/lib/minilzo
rm -r minilzo-2.10* rm -r minilzo-2.10*
@end example @end example
@node libtasn1
@section libtasn1
libtasn1 is a library providing Abstract Syntax Notation One (ASN.1, as
specified by the X.680 ITU-T recommendation) parsing and structures management,
and Distinguished Encoding Rules (DER, as per X.690) encoding and decoding
functions.
To upgrade to a new version of the libtasn1 library, download the release
tarball and copy the files into the target directory:
@example
curl -L -O https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.19.0.tar.gz
tar xvzf libtasn1-4.19.0.tar.gz
rm -rf grub-core/lib/libtasn1
mkdir -p grub-core/lib/libtasn1/lib
mkdir -p grub-core/lib/libtasn1/tests
cp libtasn1-4.19.0/@{README.md,COPYING@} grub-core/lib/libtasn1
cp libtasn1-4.19.0/lib/@{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h@} grub-core/lib/libtasn1/lib
cp libtasn1-4.19.0/lib/includes/libtasn1.h grub-core/lib/libtasn1
cp libtasn1-4.19.0/tests/@{CVE-2018-1000654-1_asn1_tab.h,CVE-2018-1000654-2_asn1_tab.h,CVE-2018-1000654.c,object-id-decoding.c,object-id-encoding.c,octet-string.c,reproducers.c,Test_overflow.c,Test_simple.c,Test_strings.c@} grub-core/lib/libtasn1/tests
rm -rf libtasn1-4.19.0*
@end example
After upgrading the library, it may be necessary to apply the patches in
@file{grub-core/lib/libtasn1-patches/} to adjust the code to be compatible with
GRUB. These patches were needed to use the current version of libtasn1. The
existing patches may not apply cleanly, apply at all, or even be needed for a
newer version of the library, and other patches may be needed due to changes in
the newer version. If existing patches need to be refreshed to apply cleanly,
please include updated patches as part of the a patch set sent to the list.
If new patches are needed or existing patches are not needed, also please send
additions or removals as part of any patch set upgrading libtasn1.
@node Debugging @node Debugging
@chapter Debugging @chapter Debugging

File diff suppressed because it is too large Load diff

View file

@ -1,4 +0,0 @@
[NAME]
grub-protect \- protect a disk key with a key protector
[DESCRIPTION]
grub-protect helps to protect a disk encryption key with a specified key protector.

View file

@ -631,10 +631,7 @@ def platform_values(defn, platform, suffix):
def extra_dist(defn): def extra_dist(defn):
return foreach_value(defn, "extra_dist", lambda value: value + " ") return foreach_value(defn, "extra_dist", lambda value: value + " ")
def extra_dep(defn): def platform_sources(defn, p): return platform_values(defn, p, "")
return foreach_value(defn, "depends", lambda value: value + " ")
def platform_sources(defn, p): return platform_values(defn, p, "_head") + platform_values(defn, p, "")
def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist") def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist")
def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup") def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup")
@ -660,7 +657,7 @@ def first_time(defn, snippet):
def is_platform_independent(defn): def is_platform_independent(defn):
if 'enable' in defn: if 'enable' in defn:
return False return False
for suffix in [ "", "_head", "_nodist" ]: for suffix in [ "", "_nodist" ]:
template = platform_values(defn, GRUB_PLATFORMS[0], suffix) template = platform_values(defn, GRUB_PLATFORMS[0], suffix)
for platform in GRUB_PLATFORMS[1:]: for platform in GRUB_PLATFORMS[1:]:
if template != platform_values(defn, platform, suffix): if template != platform_values(defn, platform, suffix):
@ -702,10 +699,6 @@ def module(defn, platform):
gvar_add("MOD_FILES", name + ".mod") gvar_add("MOD_FILES", name + ".mod")
gvar_add("MARKER_FILES", name + ".marker") gvar_add("MARKER_FILES", name + ".marker")
gvar_add("CLEANFILES", name + ".marker") gvar_add("CLEANFILES", name + ".marker")
for dep in defn.find_all("depends"):
gvar_add("EXTRA_DEPS", "depends " + name + " " + dep + ":")
output(""" output("""
""" + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES) """ + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES)
$(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)

View file

@ -90,7 +90,6 @@ endif
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/key_protector.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
@ -455,11 +454,8 @@ crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst
platform_DATA += crypto.lst platform_DATA += crypto.lst
CLEANFILES += crypto.lst CLEANFILES += crypto.lst
extra_deps.lst: syminfo.lst: gensyminfo.sh kernel_syms.lst $(top_srcdir)/grub-core/extra_deps.lst $(MODULE_FILES)
@echo $(EXTRA_DEPS) | sed "s/\s*:\s*/\n/g" > $@ cat kernel_syms.lst $(top_srcdir)/grub-core/extra_deps.lst > $@.new
syminfo.lst: gensyminfo.sh kernel_syms.lst extra_deps.lst $(MODULE_FILES)
cat kernel_syms.lst extra_deps.lst > $@.new
for m in $(MODULE_FILES); do \ for m in $(MODULE_FILES); do \
sh $< $$m >> $@.new || exit 1; \ sh $< $$m >> $@.new || exit 1; \
done done
@ -469,7 +465,7 @@ syminfo.lst: gensyminfo.sh kernel_syms.lst extra_deps.lst $(MODULE_FILES)
moddep.lst: syminfo.lst genmoddep.awk video.lst moddep.lst: syminfo.lst genmoddep.awk video.lst
cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1)
platform_DATA += moddep.lst platform_DATA += moddep.lst
CLEANFILES += config.log syminfo.lst moddep.lst extra_deps.lst CLEANFILES += config.log syminfo.lst moddep.lst
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT) $(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT)
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@

View file

@ -536,7 +536,7 @@ image = {
image = { image = {
name = xz_decompress; name = xz_decompress;
mips_head = boot/mips/startup_raw.S; mips = boot/mips/startup_raw.S;
common = boot/decompressor/minilib.c; common = boot/decompressor/minilib.c;
common = boot/decompressor/xz.c; common = boot/decompressor/xz.c;
common = lib/xzembed/xz_dec_bcj.c; common = lib/xzembed/xz_dec_bcj.c;
@ -554,7 +554,7 @@ image = {
image = { image = {
name = none_decompress; name = none_decompress;
mips_head = boot/mips/startup_raw.S; mips = boot/mips/startup_raw.S;
common = boot/decompressor/none.c; common = boot/decompressor/none.c;
cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1'; cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1';
@ -714,16 +714,12 @@ module = {
name = cmostest; name = cmostest;
common = commands/i386/cmostest.c; common = commands/i386/cmostest.c;
enable = cmos; enable = cmos;
enable = i386_efi;
enable = x86_64_efi;
}; };
module = { module = {
name = cmosdump; name = cmosdump;
common = commands/i386/cmosdump.c; common = commands/i386/cmosdump.c;
enable = cmos; enable = cmos;
enable = i386_efi;
enable = x86_64_efi;
}; };
module = { module = {
@ -1282,11 +1278,6 @@ module = {
common = disk/raid6_recover.c; common = disk/raid6_recover.c;
}; };
module = {
name = key_protector;
common = disk/key_protector.c;
};
module = { module = {
name = scsi; name = scsi;
common = disk/scsi.c; common = disk/scsi.c;
@ -1447,11 +1438,6 @@ module = {
common = fs/odc.c; common = fs/odc.c;
}; };
module = {
name = erofs;
common = fs/erofs.c;
};
module = { module = {
name = ext2; name = ext2;
common = fs/ext2.c; common = fs/ext2.c;
@ -1606,7 +1592,6 @@ module = {
common = fs/zfs/zfs_lz4.c; common = fs/zfs/zfs_lz4.c;
common = fs/zfs/zfs_sha256.c; common = fs/zfs/zfs_sha256.c;
common = fs/zfs/zfs_fletcher.c; common = fs/zfs/zfs_fletcher.c;
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd';
}; };
module = { module = {
@ -2253,10 +2238,6 @@ module = {
common = tests/videotest_checksum.c; common = tests/videotest_checksum.c;
}; };
/*
* These tests fail depending on the version of unifont. As we don't distribute
* our own unifont it fails for most users. Disable them so that they don't mask
* real failures. They can be reinstated once we solve unifont problem.
module = { module = {
name = gfxterm_menu; name = gfxterm_menu;
common = tests/gfxterm_menu.c; common = tests/gfxterm_menu.c;
@ -2266,7 +2247,6 @@ module = {
name = cmdline_cat_test; name = cmdline_cat_test;
common = tests/cmdline_cat_test.c; common = tests/cmdline_cat_test.c;
}; };
*/
module = { module = {
name = bitmap; name = bitmap;
@ -2572,34 +2552,6 @@ module = {
enable = efi; enable = efi;
}; };
module = {
name = tss2;
common = lib/tss2/buffer.c;
common = lib/tss2/tss2_mu.c;
common = lib/tss2/tpm2_cmd.c;
common = lib/tss2/tss2.c;
efi = lib/efi/tcg2.c;
emu = lib/tss2/tcg2_emu.c;
powerpc_ieee1275 = lib/ieee1275/tcg2.c;
enable = efi;
enable = emu;
enable = powerpc_ieee1275;
cppflags = '-I$(srcdir)/lib/tss2';
};
module = {
name = tpm2_key_protector;
common = commands/tpm2_key_protector/args.c;
common = commands/tpm2_key_protector/module.c;
common = commands/tpm2_key_protector/tpm2key.c;
common = commands/tpm2_key_protector/tpm2key_asn1_tab.c;
/* The plaform support of tpm2_key_protector depends on the tcg2 implementation in tss2. */
enable = efi;
enable = emu;
enable = powerpc_ieee1275;
cppflags = '-I$(srcdir)/lib/tss2 -I$(srcdir)/lib/libtasn1-grub';
};
module = { module = {
name = tr; name = tr;
common = commands/tr.c; common = commands/tr.c;
@ -2642,35 +2594,4 @@ module = {
name = bli; name = bli;
efi = commands/bli.c; efi = commands/bli.c;
enable = efi; enable = efi;
depends = part_gpt;
};
module = {
name = asn1;
common = lib/libtasn1-grub/lib/decoding.c;
common = lib/libtasn1-grub/lib/coding.c;
common = lib/libtasn1-grub/lib/element.c;
common = lib/libtasn1-grub/lib/structure.c;
common = lib/libtasn1-grub/lib/parser_aux.c;
common = lib/libtasn1-grub/lib/gstr.c;
common = lib/libtasn1-grub/lib/errors.c;
common = lib/libtasn1_wrap/wrap.c;
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
/* -Wno-type-limits comes from configure.ac of libtasn1 */
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/lib/libtasn1-grub/lib -Wno-type-limits';
};
module = {
name = asn1_test;
common = tests/asn1/tests/CVE-2018-1000654.c;
common = tests/asn1/tests/object-id-decoding.c;
common = tests/asn1/tests/object-id-encoding.c;
common = tests/asn1/tests/octet-string.c;
common = tests/asn1/tests/reproducers.c;
common = tests/asn1/tests/Test_overflow.c;
common = tests/asn1/tests/Test_simple.c;
common = tests/asn1/tests/Test_strings.c;
common = tests/asn1/asn1_test.c;
cflags = '-Wno-uninitialized';
cppflags = '-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/tests/asn1/';
}; };

View file

@ -218,7 +218,7 @@ enum
#define GRUB_EHCI_TERMINATE (1<<0) #define GRUB_EHCI_TERMINATE (1<<0)
#define GRUB_EHCI_TOGGLE ((grub_uint32_t) 1<<31) #define GRUB_EHCI_TOGGLE (1<<31)
enum enum
{ {

View file

@ -38,20 +38,6 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
enum
{
OPTION_EXCLUDE = 0,
OPTION_LOAD_ONLY,
OPTION_V1,
OPTION_V2,
OPTION_OEMID,
OPTION_OEMTABLE,
OPTION_OEMTABLEREV,
OPTION_OEMTABLECREATOR,
OPTION_OEMTABLECREATORREV,
OPTION_NO_EBDA
};
static const struct grub_arg_option options[] = { static const struct grub_arg_option options[] = {
{"exclude", 'x', 0, {"exclude", 'x', 0,
N_("Don't load host tables specified by comma-separated list."), N_("Don't load host tables specified by comma-separated list."),
@ -511,14 +497,14 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
grub_size_t tbl_addr_size; grub_size_t tbl_addr_size;
struct grub_acpi_table_header *table_head; struct grub_acpi_table_header *table_head;
exclude = state[OPTION_EXCLUDE].set ? grub_strdup (state[OPTION_EXCLUDE].arg) : 0; exclude = state[0].set ? grub_strdup (state[0].arg) : 0;
if (exclude) if (exclude)
{ {
for (ptr = exclude; *ptr; ptr++) for (ptr = exclude; *ptr; ptr++)
*ptr = grub_tolower (*ptr); *ptr = grub_tolower (*ptr);
} }
load_only = state[OPTION_LOAD_ONLY].set ? grub_strdup (state[OPTION_LOAD_ONLY].arg) : 0; load_only = state[1].set ? grub_strdup (state[1].arg) : 0;
if (load_only) if (load_only)
{ {
for (ptr = load_only; *ptr; ptr++) for (ptr = load_only; *ptr; ptr++)
@ -637,26 +623,26 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
} }
/* Does user specify versions to generate? */ /* Does user specify versions to generate? */
if (state[OPTION_V1].set || state[OPTION_V2].set) if (state[2].set || state[3].set)
{ {
rev1 = state[OPTION_V1].set; rev1 = state[2].set;
if (state[OPTION_V2].set) if (state[3].set)
rev2 = rev2 ? : 2; rev2 = rev2 ? : 2;
else else
rev2 = 0; rev2 = 0;
} }
/* Does user override root header information? */ /* Does user override root header information? */
if (state[OPTION_OEMID].set) if (state[4].set)
grub_strncpy (root_oemid, state[OPTION_OEMID].arg, sizeof (root_oemid)); grub_strncpy (root_oemid, state[4].arg, sizeof (root_oemid));
if (state[OPTION_OEMTABLE].set) if (state[5].set)
grub_strncpy (root_oemtable, state[OPTION_OEMTABLE].arg, sizeof (root_oemtable)); grub_strncpy (root_oemtable, state[5].arg, sizeof (root_oemtable));
if (state[OPTION_OEMTABLEREV].set) if (state[6].set)
root_oemrev = grub_strtoul (state[OPTION_OEMTABLEREV].arg, 0, 0); root_oemrev = grub_strtoul (state[6].arg, 0, 0);
if (state[OPTION_OEMTABLECREATOR].set) if (state[7].set)
grub_strncpy (root_creator_id, state[OPTION_OEMTABLECREATOR].arg, sizeof (root_creator_id)); grub_strncpy (root_creator_id, state[7].arg, sizeof (root_creator_id));
if (state[OPTION_OEMTABLECREATORREV].set) if (state[8].set)
root_creator_rev = grub_strtoul (state[OPTION_OEMTABLECREATORREV].arg, 0, 0); root_creator_rev = grub_strtoul (state[8].arg, 0, 0);
/* Load user tables */ /* Load user tables */
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
@ -772,7 +758,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
acpi_tables = 0; acpi_tables = 0;
#if defined (__i386__) || defined (__x86_64__) #if defined (__i386__) || defined (__x86_64__)
if (! state[OPTION_NO_EBDA].set) if (! state[9].set)
{ {
grub_err_t err; grub_err_t err;
err = grub_acpi_create_ebda (); err = grub_acpi_create_ebda ();

View file

@ -48,22 +48,6 @@ get_part_uuid (const char *device_name, char **part_uuid)
if (device == NULL) if (device == NULL)
return grub_error (grub_errno, N_("cannot open device: %s"), device_name); return grub_error (grub_errno, N_("cannot open device: %s"), device_name);
if (device->disk == NULL)
{
grub_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name);
*part_uuid = NULL;
grub_device_close (device);
return GRUB_ERR_NONE;
}
if (device->disk->partition == NULL)
{
grub_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name);
*part_uuid = NULL;
grub_device_close (device);
return GRUB_ERR_NONE;
}
disk = grub_disk_open (device->disk->name); disk = grub_disk_open (device->disk->name);
if (disk == NULL) if (disk == NULL)
{ {
@ -115,7 +99,7 @@ set_loader_device_part_uuid (void)
status = get_part_uuid (device_name, &part_uuid); status = get_part_uuid (device_name, &part_uuid);
if (status == GRUB_ERR_NONE && part_uuid) if (status == GRUB_ERR_NONE)
status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid, status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid,
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
GRUB_EFI_VARIABLE_RUNTIME_ACCESS); GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
@ -133,6 +117,4 @@ GRUB_MOD_INIT (bli)
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
GRUB_EFI_VARIABLE_RUNTIME_ACCESS); GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
set_loader_device_part_uuid (); set_loader_device_part_uuid ();
/* No error here is critical, other than being logged */
grub_print_error ();
} }

View file

@ -292,15 +292,6 @@ grub_tpm_present (void)
{ {
grub_efi_handle_t tpm_handle; grub_efi_handle_t tpm_handle;
grub_efi_uint8_t protocol_version; grub_efi_uint8_t protocol_version;
grub_efi_cc_protocol_t *cc;
/*
* When confidential computing measurement protocol is enabled
* we assume the TPM is present.
*/
cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL);
if (cc != NULL)
return 1;
if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
return 0; return 0;

View file

@ -49,9 +49,6 @@ grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args,
} }
state = grub_arg_list_alloc (ext, argc, args); state = grub_arg_list_alloc (ext, argc, args);
if (state == NULL)
return grub_errno;
if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc)) if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
{ {
context.state = state; context.state = state;

View file

@ -306,8 +306,6 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
elf = grub_elf_file (file, file->name); elf = grub_elf_file (file, file->name);
if (elf == NULL)
break;
if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC) if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
|| elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB) || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB)
break; break;

View file

@ -24,7 +24,6 @@
#include <grub/lib/hexdump.h> #include <grub/lib/hexdump.h>
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -52,11 +51,7 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256; length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256;
if (!grub_strcmp (args[0], "(mem)")) if (!grub_strcmp (args[0], "(mem)"))
{ hexdump (skip, (char *) (grub_addr_t) skip, length);
if (grub_is_lockdown() == GRUB_LOCKDOWN_ENABLED)
return grub_error (GRUB_ERR_ACCESS_DENIED, N_("memory reading is disabled in lockdown mode"));
hexdump (skip, (char *) (grub_addr_t) skip, length);
}
else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')')) else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')'))
{ {
grub_disk_t disk; grub_disk_t disk;

View file

@ -104,13 +104,13 @@ static grub_command_t cmd, cmd_clean, cmd_set;
GRUB_MOD_INIT(cmostest) GRUB_MOD_INIT(cmostest)
{ {
cmd = grub_register_command_lockdown ("cmostest", grub_cmd_cmostest, cmd = grub_register_command ("cmostest", grub_cmd_cmostest,
N_("BYTE:BIT"), N_("BYTE:BIT"),
N_("Test bit at BYTE:BIT in CMOS.")); N_("Test bit at BYTE:BIT in CMOS."));
cmd_clean = grub_register_command_lockdown ("cmosclean", grub_cmd_cmosclean, cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean,
N_("BYTE:BIT"), N_("BYTE:BIT"),
N_("Clear bit at BYTE:BIT in CMOS.")); N_("Clear bit at BYTE:BIT in CMOS."));
cmd_set = grub_register_command_lockdown ("cmosset", grub_cmd_cmosset, cmd_set = grub_register_command ("cmosset", grub_cmd_cmosset,
N_("BYTE:BIT"), N_("BYTE:BIT"),
/* TRANSLATORS: A bit may be either set (1) or clear (0). */ /* TRANSLATORS: A bit may be either set (1) or clear (0). */
N_("Set bit at BYTE:BIT in CMOS.")); N_("Set bit at BYTE:BIT in CMOS."));

View file

@ -26,7 +26,7 @@
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/i386/cpuid.h> #include <grub/i386/cpuid.h>
#include <grub/i386/msr.h> #include <grub/i386/rdmsr.h>
GRUB_MOD_LICENSE("GPLv3+"); GRUB_MOD_LICENSE("GPLv3+");
@ -42,16 +42,27 @@ static const struct grub_arg_option options[] =
static grub_err_t static grub_err_t
grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv)
{ {
grub_err_t err; grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
grub_uint32_t addr;
grub_uint64_t value; grub_uint64_t value;
const char *ptr; const char *ptr;
char buf[sizeof("1122334455667788")]; char buf[sizeof("1122334455667788")];
err = grub_cpu_is_msr_supported (); /*
* The CPUID instruction should be used to determine whether MSRs
* are supported. (CPUID.01H:EDX[5] = 1)
*/
if (! grub_cpu_is_cpuid_supported ())
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
if (err != GRUB_ERR_NONE) grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
return grub_error (err, N_("RDMSR is unsupported"));
if (max_cpuid < 1)
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
grub_cpuid (1, a, b, c, features);
if (!(features & (1 << 5)))
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
if (argc != 1) if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
@ -65,7 +76,7 @@ grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv)
if (*ptr != '\0') if (*ptr != '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
value = grub_rdmsr (addr); value = grub_msr_read (addr);
if (ctxt->state[0].set) if (ctxt->state[0].set)
{ {

View file

@ -27,7 +27,7 @@
#include <grub/lockdown.h> #include <grub/lockdown.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/i386/cpuid.h> #include <grub/i386/cpuid.h>
#include <grub/i386/msr.h> #include <grub/i386/wrmsr.h>
GRUB_MOD_LICENSE("GPLv3+"); GRUB_MOD_LICENSE("GPLv3+");
@ -36,15 +36,26 @@ static grub_command_t cmd_write;
static grub_err_t static grub_err_t
grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv) grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv)
{ {
grub_err_t err; grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr;
grub_uint32_t addr;
grub_uint64_t value; grub_uint64_t value;
const char *ptr; const char *ptr;
err = grub_cpu_is_msr_supported (); /*
* The CPUID instruction should be used to determine whether MSRs
* are supported. (CPUID.01H:EDX[5] = 1)
*/
if (!grub_cpu_is_cpuid_supported ())
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
if (err != GRUB_ERR_NONE) grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);
return grub_error (err, N_("WRMSR is unsupported"));
if (max_cpuid < 1)
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
grub_cpuid (1, a, b, c, features);
if (!(features & (1 << 5)))
return grub_error (GRUB_ERR_BUG, N_("unsupported instruction"));
if (argc != 2) if (argc != 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
@ -66,7 +77,7 @@ grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char
if (*ptr != '\0') if (*ptr != '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
grub_wrmsr (addr, value); grub_msr_write (addr, value);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

View file

@ -23,10 +23,48 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/tpm.h> #include <grub/tpm.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/ieee1275/tpm.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/misc.h> #include <grub/misc.h>
static grub_ieee1275_ihandle_t tpm_ihandle;
static grub_uint8_t tpm_version;
#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0)
static void
tpm_get_tpm_version (void)
{
grub_ieee1275_phandle_t vtpm;
char buffer[20];
if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) &&
!grub_ieee1275_get_property (vtpm, "compatible", buffer,
sizeof (buffer), NULL) &&
!grub_strcmp (buffer, "IBM,vtpm20"))
tpm_version = 2;
}
static grub_err_t
tpm_init (void)
{
static int init_success = 0;
if (!init_success)
{
if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0)
{
tpm_ihandle = IEEE1275_IHANDLE_INVALID;
return GRUB_ERR_UNKNOWN_DEVICE;
}
init_success = 1;
tpm_get_tpm_version ();
}
return GRUB_ERR_NONE;
}
static int static int
ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex, ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
grub_uint32_t eventtype, grub_uint32_t eventtype,
@ -52,7 +90,7 @@ ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex,
INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2); INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2);
args.method = (grub_ieee1275_cell_t) "2hash-ext-log"; args.method = (grub_ieee1275_cell_t) "2hash-ext-log";
args.ihandle = grub_ieee1275_tpm_ihandle; args.ihandle = tpm_ihandle;
args.pcrindex = pcrindex; args.pcrindex = pcrindex;
args.eventtype = eventtype; args.eventtype = eventtype;
args.description = (grub_ieee1275_cell_t) description; args.description = (grub_ieee1275_cell_t) description;
@ -100,7 +138,7 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
pcr, size, description); pcr, size, description);
if (grub_ieee1275_tpm_ihandle != GRUB_IEEE1275_IHANDLE_INVALID) if (tpm_version == 2)
return tpm2_log_event (buf, size, pcr, description); return tpm2_log_event (buf, size, pcr, description);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -113,5 +151,5 @@ grub_tpm_present (void)
* Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes * Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes
* can be found. * can be found.
*/ */
return grub_ieee1275_tpm_init() == GRUB_ERR_NONE; return tpm_init() == GRUB_ERR_NONE;
} }

View file

@ -198,6 +198,7 @@ legacy_file (const char *filename)
const char **args = grub_malloc (sizeof (args[0])); const char **args = grub_malloc (sizeof (args[0]));
if (!args) if (!args)
{ {
grub_file_close (file);
grub_free (suffix); grub_free (suffix);
grub_free (entrysrc); grub_free (entrysrc);
return grub_errno; return grub_errno;

View file

@ -87,44 +87,37 @@ grub_ls_list_devices (int longlist)
struct grub_ls_list_files_ctx struct grub_ls_list_files_ctx
{ {
char *dirname; char *dirname;
char *filename;
int all; int all;
int human; int human;
int longlist;
int print_dirhdr;
}; };
/* Helper for grub_ls_list_files. */ /* Helper for grub_ls_list_files. */
static int static int
print_file (const char *filename, const struct grub_dirhook_info *info, print_files (const char *filename, const struct grub_dirhook_info *info,
void *data)
{
struct grub_ls_list_files_ctx *ctx = data;
if (ctx->all || filename[0] != '.')
grub_printf ("%s%s ", filename, info->dir ? "/" : "");
return 0;
}
/* Helper for grub_ls_list_files. */
static int
print_files_long (const char *filename, const struct grub_dirhook_info *info,
void *data) void *data)
{ {
char *pathname = NULL;
struct grub_ls_list_files_ctx *ctx = data; struct grub_ls_list_files_ctx *ctx = data;
if ((! ctx->all) && (filename[0] == '.')) if ((! ctx->all) && (filename[0] == '.'))
return 0; return 0;
if ((ctx->filename != NULL) && (grub_strcmp (filename, ctx->filename) != 0))
return 0;
if (ctx->print_dirhdr)
{
grub_printf ("%s:\n", ctx->dirname);
ctx->print_dirhdr = 0;
}
if (! ctx->longlist)
{
if (ctx->filename != NULL)
grub_xputs (ctx->dirname);
grub_printf ("%s%s ", filename, info->dir ? "/" : "");
return 0;
}
if (! info->dir) if (! info->dir)
{ {
grub_file_t file; grub_file_t file;
char *pathname;
if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/') if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/')
pathname = grub_xasprintf ("%s%s", ctx->dirname, filename); pathname = grub_xasprintf ("%s%s", ctx->dirname, filename);
@ -150,6 +143,7 @@ print_file (const char *filename, const struct grub_dirhook_info *info,
else else
grub_xputs ("????????????"); grub_xputs ("????????????");
grub_free (pathname);
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }
else else
@ -171,22 +165,13 @@ print_file (const char *filename, const struct grub_dirhook_info *info,
datetime.day, datetime.hour, datetime.day, datetime.hour,
datetime.minute, datetime.second); datetime.minute, datetime.second);
} }
/* grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
* Only print the full path when listing a file path given as an argument
* to ls, i.e. when ctx->filename != NULL. File listings that are printed
* due to showing the contents of a directory do not need a full path because
* the full path to the directory will have already been printed.
*/
grub_printf ("%s%s\n", (ctx->filename != NULL) ? pathname : filename,
info->dir ? "/" : "");
grub_free (pathname);
return 0; return 0;
} }
static grub_err_t static grub_err_t
grub_ls_list_files (char *dirname, int longlist, int all, int human, int dirhdr) grub_ls_list_files (char *dirname, int longlist, int all, int human)
{ {
char *device_name; char *device_name;
grub_fs_t fs; grub_fs_t fs;
@ -231,36 +216,42 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human, int dirhdr)
{ {
struct grub_ls_list_files_ctx ctx = { struct grub_ls_list_files_ctx ctx = {
.dirname = dirname, .dirname = dirname,
.filename = NULL,
.all = all, .all = all,
.human = human, .human = human
.longlist = longlist,
.print_dirhdr = dirhdr
}; };
(fs->fs_dir) (dev, path, print_file, &ctx); if (longlist)
(fs->fs_dir) (dev, path, print_files_long, &ctx);
else
(fs->fs_dir) (dev, path, print_files, &ctx);
if (grub_errno == GRUB_ERR_BAD_FILE_TYPE if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
&& path[grub_strlen (path) - 1] != '/') && path[grub_strlen (path) - 1] != '/')
{ {
/*
* Reset errno as it is currently set, but will cause subsequent code
* to think there is an error.
*/
grub_errno = GRUB_ERR_NONE;
/* PATH might be a regular file. */ /* PATH might be a regular file. */
ctx.print_dirhdr = 0; char *p;
ctx.filename = grub_strrchr (dirname, '/'); grub_file_t file;
if (ctx.filename == NULL) struct grub_dirhook_info info;
goto fail; grub_errno = 0;
++(ctx.filename);
ctx.dirname = grub_strndup (dirname, ctx.filename - dirname); file = grub_file_open (dirname, GRUB_FILE_TYPE_GET_SIZE
| GRUB_FILE_TYPE_NO_DECOMPRESS);
if (! file)
goto fail;
grub_file_close (file);
p = grub_strrchr (dirname, '/') + 1;
ctx.dirname = grub_strndup (dirname, p - dirname);
if (ctx.dirname == NULL) if (ctx.dirname == NULL)
goto fail; goto fail;
(fs->fs_dir) (dev, ctx.dirname + (path - dirname), print_file, &ctx); all = 1;
grub_memset (&info, 0, sizeof (info));
if (longlist)
print_files_long (p, &info, &ctx);
else
print_files (p, &info, &ctx);
grub_free (ctx.dirname); grub_free (ctx.dirname);
} }
@ -277,7 +268,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human, int dirhdr)
grub_free (device_name); grub_free (device_name);
return GRUB_ERR_NONE; return 0;
} }
static grub_err_t static grub_err_t
@ -290,10 +281,10 @@ grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args)
grub_ls_list_devices (state[0].set); grub_ls_list_devices (state[0].set);
else else
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
grub_ls_list_files (args[i], state[0].set, state[2].set, state[1].set, grub_ls_list_files (args[i], state[0].set, state[2].set,
argc > 1); state[1].set);
return GRUB_ERR_NONE; return 0;
} }
static grub_extcmd_t cmd; static grub_extcmd_t cmd;

View file

@ -122,20 +122,17 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
GRUB_MOD_INIT(memrw) GRUB_MOD_INIT(memrw)
{ {
cmd_read_byte = cmd_read_byte =
grub_register_extcmd_lockdown ("read_byte", grub_cmd_read, 0, grub_register_extcmd ("read_byte", grub_cmd_read, 0,
N_("ADDR"), N_("ADDR"), N_("Read 8-bit value from ADDR."),
N_("Read 8-bit value from ADDR."), options);
options);
cmd_read_word = cmd_read_word =
grub_register_extcmd_lockdown ("read_word", grub_cmd_read, 0, grub_register_extcmd ("read_word", grub_cmd_read, 0,
N_("ADDR"), N_("ADDR"), N_("Read 16-bit value from ADDR."),
N_("Read 16-bit value from ADDR."), options);
options);
cmd_read_dword = cmd_read_dword =
grub_register_extcmd_lockdown ("read_dword", grub_cmd_read, 0, grub_register_extcmd ("read_dword", grub_cmd_read, 0,
N_("ADDR"), N_("ADDR"), N_("Read 32-bit value from ADDR."),
N_("Read 32-bit value from ADDR."), options);
options);
cmd_write_byte = cmd_write_byte =
grub_register_command_lockdown ("write_byte", grub_cmd_write, grub_register_command_lockdown ("write_byte", grub_cmd_write,
N_("ADDR VALUE [MASK]"), N_("ADDR VALUE [MASK]"),

View file

@ -29,10 +29,6 @@
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/cryptodisk.h>
#endif
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
/* cat FILE */ /* cat FILE */
@ -171,7 +167,7 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
{ {
grub_dl_dep_t dep; grub_dl_dep_t dep;
grub_printf ("%s\t%" PRIuGRUB_UINT64_T "\t\t", mod->name, mod->ref_count); grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
for (dep = mod->dep; dep; dep = dep->next) for (dep = mod->dep; dep; dep = dep->next)
{ {
if (dep != mod->dep) if (dep != mod->dep)
@ -191,13 +187,6 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)), int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused))) char *argv[] __attribute__ ((unused)))
{ {
#ifdef GRUB_MACHINE_EFI
/*
* The "exit" command is often used to launch the next boot application.
* So, erase the secrets.
*/
grub_cryptodisk_erasesecrets ();
#endif
grub_exit (); grub_exit ();
/* Not reached. */ /* Not reached. */
} }
@ -214,8 +203,8 @@ GRUB_MOD_INIT(minicmd)
grub_register_command ("help", grub_mini_cmd_help, grub_register_command ("help", grub_mini_cmd_help,
0, N_("Show this message.")); 0, N_("Show this message."));
cmd_dump = cmd_dump =
grub_register_command_lockdown ("dump", grub_mini_cmd_dump, grub_register_command ("dump", grub_mini_cmd_dump,
N_("ADDR [SIZE]"), N_("Show memory contents.")); N_("ADDR [SIZE]"), N_("Show memory contents."));
cmd_rmmod = cmd_rmmod =
grub_register_command ("rmmod", grub_mini_cmd_rmmod, grub_register_command ("rmmod", grub_mini_cmd_rmmod,
N_("MODULE"), N_("Remove a module.")); N_("MODULE"), N_("Remove a module."));

View file

@ -1010,8 +1010,6 @@ GRUB_MOD_INIT(pgp)
GRUB_MOD_FINI(pgp) GRUB_MOD_FINI(pgp)
{ {
grub_register_variable_hook ("check_signatures", NULL, NULL);
grub_env_unset ("check_signatures");
grub_verifier_unregister (&grub_pubkey_verifier); grub_verifier_unregister (&grub_pubkey_verifier);
grub_unregister_extcmd (cmd); grub_unregister_extcmd (cmd);
grub_unregister_extcmd (cmd_trust); grub_unregister_extcmd (cmd_trust);

View file

@ -25,7 +25,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -38,14 +37,13 @@ static const struct grub_arg_option options[] =
static char * static char *
grub_getline (int silent) grub_getline (int silent)
{ {
grub_size_t i; int i;
char *line; char *line;
char *tmp; char *tmp;
int c; int c;
grub_size_t alloc_size;
i = 0; i = 0;
line = grub_malloc (1 + sizeof('\0')); line = grub_malloc (1 + i + sizeof('\0'));
if (! line) if (! line)
return NULL; return NULL;
@ -61,17 +59,8 @@ grub_getline (int silent)
line[i] = (char) c; line[i] = (char) c;
if (!silent) if (!silent)
grub_printf ("%c", c); grub_printf ("%c", c);
if (grub_add (i, 1, &i)) i++;
{ tmp = grub_realloc (line, 1 + i + sizeof('\0'));
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
}
if (grub_add (i, 1 + sizeof('\0'), &alloc_size))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL;
}
tmp = grub_realloc (line, alloc_size);
if (! tmp) if (! tmp)
{ {
grub_free (line); grub_free (line);

View file

@ -54,41 +54,6 @@ struct search_ctx
int is_cache; int is_cache;
}; };
static bool
is_unencrypted_disk (grub_disk_t disk)
{
grub_command_t cmd;
char *disk_str;
int disk_str_len;
int res;
if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
return false; /* This is (crypto) disk. */
if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
{
char opt[] = "--quiet";
char *args[2];
cmd = grub_command_find ("cryptocheck");
if (cmd == NULL) /* No diskfilter module loaded for some reason. */
return true;
disk_str_len = grub_strlen (disk->name) + 2 + 1;
disk_str = grub_malloc (disk_str_len);
if (disk_str == NULL) /* Something is wrong, better report as unencrypted. */
return true;
grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
args[0] = opt;
args[1] = disk_str;
res = cmd->func (cmd, 2, args);
grub_free (disk_str);
return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */
}
return true;
}
/* Helper for FUNC_NAME. */ /* Helper for FUNC_NAME. */
static int static int
iterate_device (const char *name, void *data) iterate_device (const char *name, void *data)
@ -121,26 +86,6 @@ iterate_device (const char *name, void *data)
grub_device_close (dev); grub_device_close (dev);
} }
/* Limit to encrypted disks when requested. */
if (ctx->flags & SEARCH_FLAGS_CRYPTODISK_ONLY)
{
grub_device_t dev;
dev = grub_device_open (name);
if (dev == NULL)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
if (dev->disk == NULL || is_unencrypted_disk (dev->disk) == true)
{
grub_device_close (dev);
grub_errno = GRUB_ERR_NONE;
return 0;
}
grub_device_close (dev);
}
#ifdef DO_SEARCH_FS_UUID #ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp #define compare_fn grub_strcasecmp
#else #else

View file

@ -41,7 +41,6 @@ static const struct grub_arg_option options[] =
ARG_TYPE_STRING}, ARG_TYPE_STRING},
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
{"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0}, {"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0},
{"cryptodisk-only", 0, 0, N_("Only probe encrypted disks."), 0, 0},
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
N_("First try the device HINT. If HINT ends in comma, " N_("First try the device HINT. If HINT ends in comma, "
"also try subpartitions"), N_("HINT"), ARG_TYPE_STRING}, "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
@ -76,7 +75,6 @@ enum options
SEARCH_SET, SEARCH_SET,
SEARCH_NO_FLOPPY, SEARCH_NO_FLOPPY,
SEARCH_EFIDISK_ONLY, SEARCH_EFIDISK_ONLY,
SEARCH_CRYPTODISK_ONLY,
SEARCH_HINT, SEARCH_HINT,
SEARCH_HINT_IEEE1275, SEARCH_HINT_IEEE1275,
SEARCH_HINT_BIOS, SEARCH_HINT_BIOS,
@ -191,9 +189,6 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
if (state[SEARCH_EFIDISK_ONLY].set) if (state[SEARCH_EFIDISK_ONLY].set)
flags |= SEARCH_FLAGS_EFIDISK_ONLY; flags |= SEARCH_FLAGS_EFIDISK_ONLY;
if (state[SEARCH_CRYPTODISK_ONLY].set)
flags |= SEARCH_FLAGS_CRYPTODISK_ONLY;
if (state[SEARCH_LABEL].set) if (state[SEARCH_LABEL].set)
grub_search_label (id, var, flags, hints, nhints); grub_search_label (id, var, flags, hints, nhints);
else if (state[SEARCH_FS_UUID].set) else if (state[SEARCH_FS_UUID].set)
@ -215,7 +210,7 @@ GRUB_MOD_INIT(search)
cmd = cmd =
grub_register_extcmd ("search", grub_cmd_search, grub_register_extcmd ("search", grub_cmd_search,
GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH, GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH,
N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT [--hint HINT] ...]" N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
" NAME"), " NAME"),
N_("Search devices by file, filesystem label" N_("Search devices by file, filesystem label"
" or filesystem UUID." " or filesystem UUID."

View file

@ -29,9 +29,6 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
/* Set a limit on recursion to avoid stack overflow. */
#define MAX_TEST_RECURSION_DEPTH 100
/* A simple implementation for signed numbers. */ /* A simple implementation for signed numbers. */
static int static int
grub_strtosl (char *arg, const char ** const end, int base) grub_strtosl (char *arg, const char ** const end, int base)
@ -153,7 +150,7 @@ get_fileinfo (char *path, struct test_parse_ctx *ctx)
/* Parse a test expression starting from *argn. */ /* Parse a test expression starting from *argn. */
static int static int
test_parse (char **args, int *argn, int argc, int *depth) test_parse (char **args, int *argn, int argc)
{ {
struct test_parse_ctx ctx = { struct test_parse_ctx ctx = {
.and = 1, .and = 1,
@ -390,24 +387,13 @@ test_parse (char **args, int *argn, int argc, int *depth)
if (grub_strcmp (args[*argn], ")") == 0) if (grub_strcmp (args[*argn], ")") == 0)
{ {
(*argn)++; (*argn)++;
if (*depth > 0)
(*depth)--;
return ctx.or || ctx.and; return ctx.or || ctx.and;
} }
/* Recursively invoke if parenthesis. */ /* Recursively invoke if parenthesis. */
if (grub_strcmp (args[*argn], "(") == 0) if (grub_strcmp (args[*argn], "(") == 0)
{ {
(*argn)++; (*argn)++;
update_val (test_parse (args, argn, argc), &ctx);
if (++(*depth) > MAX_TEST_RECURSION_DEPTH)
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("max recursion depth exceeded"));
depth--;
return ctx.or || ctx.and;
}
update_val (test_parse (args, argn, argc, depth), &ctx);
continue; continue;
} }
@ -442,12 +428,11 @@ grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args) int argc, char **args)
{ {
int argn = 0; int argn = 0;
int depth = 0;
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0) if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
argc--; argc--;
return test_parse (args, &argn, argc, &depth) ? GRUB_ERR_NONE return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
: grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); : grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
} }

View file

@ -36,16 +36,6 @@ grub_tpm_verify_init (grub_file_t io,
{ {
*context = io->name; *context = io->name;
*flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
/*
* The loopback image is mapped as a disk allowing it to function like
* a block device. However, we measure files read from the block device
* not the device itself. For example, we don't measure block devices like
* hd0 disk directly. This process is crucial to prevent out-of-memory
* errors as loopback images are inherently large.
*/
if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_LOOPBACK)
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

View file

@ -1,127 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2022 Microsoft Corporation
* Copyright (C) 2024 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/err.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include "tpm2_args.h"
grub_err_t
grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs,
grub_uint8_t *pcr_count)
{
char *current_pcr = value;
char *next_pcr;
const char *pcr_end;
grub_uint64_t pcr;
grub_uint8_t i;
if (grub_strlen (value) == 0)
return GRUB_ERR_BAD_ARGUMENT;
*pcr_count = 0;
for (i = 0; i < TPM_MAX_PCRS; i++)
{
next_pcr = grub_strchr (current_pcr, ',');
if (next_pcr == current_pcr)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("empty entry in PCR list"));
if (next_pcr != NULL)
*next_pcr = '\0';
pcr = grub_strtoul (current_pcr, &pcr_end, 10);
if (*current_pcr == '\0' || *pcr_end != '\0')
return grub_error (GRUB_ERR_BAD_NUMBER, N_("entry '%s' in PCR list is not a number"), current_pcr);
if (pcr > TPM_MAX_PCRS - 1)
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("entry %llu in PCR list is too large to be a PCR number, PCR numbers range from 0 to %u"), (unsigned long long)pcr, TPM_MAX_PCRS - 1);
pcrs[i] = (grub_uint8_t) pcr;
++(*pcr_count);
if (next_pcr == NULL)
break;
current_pcr = next_pcr + 1;
if (*current_pcr == '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("trailing comma at the end of PCR list"));
}
if (i == TPM_MAX_PCRS)
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("too many PCRs in PCR list, the maximum number of PCRs is %u"), TPM_MAX_PCRS);
return GRUB_ERR_NONE;
}
grub_err_t
grub_tpm2_protector_parse_asymmetric (const char *value,
grub_srk_type_t *srk_type)
{
if (grub_strcasecmp (value, "ECC") == 0 ||
grub_strcasecmp (value, "ECC_NIST_P256") == 0)
{
srk_type->type = TPM_ALG_ECC;
srk_type->detail.ecc_curve = TPM_ECC_NIST_P256;
}
else if (grub_strcasecmp (value, "RSA") == 0 ||
grub_strcasecmp (value, "RSA2048") == 0)
{
srk_type->type = TPM_ALG_RSA;
srk_type->detail.rsa_bits = 2048;
}
else
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid asymmetric key type"), value);
return GRUB_ERR_NONE;
}
grub_err_t
grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID_t *bank)
{
if (grub_strcasecmp (value, "SHA1") == 0)
*bank = TPM_ALG_SHA1;
else if (grub_strcasecmp (value, "SHA256") == 0)
*bank = TPM_ALG_SHA256;
else if (grub_strcasecmp (value, "SHA384") == 0)
*bank = TPM_ALG_SHA384;
else if (grub_strcasecmp (value, "SHA512") == 0)
*bank = TPM_ALG_SHA512;
else
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid PCR bank"), value);
return GRUB_ERR_NONE;
}
grub_err_t
grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE_t *handle)
{
grub_uint64_t num;
const char *str_end;
num = grub_strtoul (value, &str_end, 0);
if (*value == '\0' || *str_end != '\0')
return grub_error (GRUB_ERR_BAD_NUMBER, N_("TPM handle value '%s' is not a number"), value);
if (num > GRUB_UINT_MAX)
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value %llu is too large to be a TPM handle, TPM handles are unsigned 32-bit integers"), (unsigned long long)num);
*handle = (TPM_HANDLE_t) num;
return GRUB_ERR_NONE;
}

File diff suppressed because it is too large Load diff

View file

@ -1,36 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2022 Microsoft Corporation
* Copyright (C) 2024 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/>.
*/
#ifndef GRUB_TPM2_TPM2_HEADER
#define GRUB_TPM2_TPM2_HEADER 1
#include <tss2_types.h>
#include <tss2_structs.h>
#include <tpm2_cmd.h>
/* Well-Known Windows SRK handle */
#define TPM2_SRK_HANDLE 0x81000001
struct tpm2_sealed_key {
TPM2B_PUBLIC_t public;
TPM2B_PRIVATE_t private;
};
typedef struct tpm2_sealed_key tpm2_sealed_key_t;
#endif /* ! GRUB_TPM2_TPM2_HEADER */

View file

@ -1,49 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2022 Microsoft Corporation
* Copyright (C) 2024 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/>.
*/
#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER
#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1
#include <grub/err.h>
#include "tpm2.h"
struct grub_srk_type
{
TPMI_ALG_PUBLIC_t type;
union {
TPM_KEY_BITS_t rsa_bits;
TPM_ECC_CURVE_t ecc_curve;
} detail;
};
typedef struct grub_srk_type grub_srk_type_t;
extern grub_err_t
grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, grub_uint8_t *pcr_count);
extern grub_err_t
grub_tpm2_protector_parse_asymmetric (const char *value, grub_srk_type_t *srk_type);
extern grub_err_t
grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID_t *bank);
extern grub_err_t
grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE_t *handle);
#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */

View file

@ -1,49 +0,0 @@
--
-- GRUB: GRand Unified Bootloader
-- Copyright (C) 2024 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/>.
--
-- This file describes TPM 2.0 Key File format for libtasn1.
-- To generate tpm2key_asn1_tab.c: asn1Parser tpm2key.asn
--
TPM2KEY {}
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
TPMPolicy ::= SEQUENCE {
CommandCode [0] EXPLICIT INTEGER,
CommandPolicy [1] EXPLICIT OCTET STRING
}
TPMAuthPolicy ::= SEQUENCE {
Name [0] EXPLICIT UTF8String OPTIONAL,
Policy [1] EXPLICIT SEQUENCE OF TPMPolicy
}
TPMKey ::= SEQUENCE {
type OBJECT IDENTIFIER,
emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL,
policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL,
secret [2] EXPLICIT OCTET STRING OPTIONAL,
authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL,
description [4] EXPLICIT UTF8String OPTIONAL,
rsaParent [5] EXPLICIT BOOLEAN OPTIONAL,
parent INTEGER,
pubkey OCTET STRING,
privkey OCTET STRING
}
END

View file

@ -1,499 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2023 SUSE LLC
* Copyright (C) 2024 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/list.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <tss2_buffer.h>
#include "tpm2key.h"
extern asn1_static_node tpm2key_asn1_tab[];
const char *sealed_key_oid = "2.23.133.10.1.5";
static int
asn1_allocate_and_read (asn1_node node, const char *name, void **content, grub_size_t *content_size)
{
grub_uint8_t *tmpstr = NULL;
int tmpstr_size = 0;
int ret;
if (content == NULL)
return ASN1_MEM_ERROR;
ret = asn1_read_value (node, name, NULL, &tmpstr_size);
if (ret != ASN1_MEM_ERROR)
return ret;
tmpstr = grub_malloc (tmpstr_size);
if (tmpstr == NULL)
return ASN1_MEM_ERROR;
ret = asn1_read_value (node, name, tmpstr, &tmpstr_size);
if (ret != ASN1_SUCCESS)
return ret;
*content = tmpstr;
*content_size = tmpstr_size;
return ASN1_SUCCESS;
}
static int
asn1_read_uint32 (asn1_node node, const char *name, grub_uint32_t *out)
{
grub_uint32_t tmp = 0;
grub_uint8_t *ptr;
void *data = NULL;
grub_size_t data_size;
int ret;
ret = asn1_allocate_and_read (node, name, &data, &data_size);
if (ret != ASN1_SUCCESS)
return ret;
/*
* ASN.1 INTEGER is encoded in the following format:
*
* TAG LENGTH OCTECTS
*
* The integer TAG is 02 and LENGTH is the number of followed OCTECTS in
* big endian. For example:
*
* 0x1: 02 01 01
* 0xabcd: 02 02 ab cd
*
* To decribe 0x1, it only takes 1 octect, so LENGTH is 0x01 and the
* octect is 0x01. On the other hand, 0xabcd requires 2 octects: 'ab" and
* 'cd', so LENGTH is 0x02.
*
* This function only expects a uint32 integer, so it rejects any integer
* containing more than 4 octects.
*/
if (data_size > 4)
{
ret = ASN1_MEM_ERROR;
goto error;
}
/* Copy the octects into 'tmp' to make it a big-endian uint32 */
ptr = (grub_uint8_t *) &tmp + (4 - data_size);
grub_memcpy (ptr, data, data_size);
/* Convert the big-endian integer to host uint32 */
tmp = grub_be_to_cpu32 (tmp);
*out = tmp;
error:
if (data)
grub_free (data);
return ret;
}
grub_err_t
grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size)
{
asn1_node tpm2key;
asn1_node tpm2key_asn1 = NULL;
void *type_oid = NULL;
grub_size_t type_oid_size = 0;
void *empty_auth = NULL;
grub_size_t empty_auth_size = 0;
int tmp_size = 0;
int ret;
grub_err_t err;
/*
* TPMKey ::= SEQUENCE {
* type OBJECT IDENTIFIER,
* emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL,
* policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL,
* secret [2] EXPLICIT OCTET STRING OPTIONAL,
* authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL,
* description [4] EXPLICIT UTF8String OPTIONAL,
* rsaParent [5] EXPLICIT BOOLEAN OPTIONAL,
* parent INTEGER,
* pubkey OCTET STRING,
* privkey OCTET STRING
* }
*/
ret = asn1_array2tree (tpm2key_asn1_tab, &tpm2key_asn1, NULL);
if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to parse TPM2KEY ASN.1 array");
ret = asn1_create_element (tpm2key_asn1, "TPM2KEY.TPMKey", &tpm2key);
if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to create TPM2KEY.TPMKey");
ret = asn1_der_decoding (&tpm2key, data, size, NULL);
if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to decode TPM2KEY DER");
/* Check if 'type' is Sealed Key or not */
ret = asn1_allocate_and_read (tpm2key, "type", &type_oid, &type_oid_size);
if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a valid TPM2KEY file");
if (grub_memcmp (sealed_key_oid, type_oid, type_oid_size) != 0)
{
err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a valid TPM2KEY file");
goto error;
}
/* 'emptyAuth' must be 'TRUE' since we don't support password authorization */
ret = asn1_allocate_and_read (tpm2key, "emptyAuth", &empty_auth, &empty_auth_size);
if (ret != ASN1_SUCCESS || grub_strncmp ("TRUE", empty_auth, empty_auth_size) != 0)
{
err = grub_error (GRUB_ERR_BAD_ARGUMENT, "emptyAuth not TRUE");
goto error;
}
/* 'secret' should not be in a sealed key */
ret = asn1_read_value (tpm2key, "secret", NULL, &tmp_size);
if (ret != ASN1_ELEMENT_NOT_FOUND)
{
err = grub_error (GRUB_ERR_BAD_ARGUMENT, "\"secret\" not allowed for Sealed Key");
goto error;
}
*parsed_tpm2key = tpm2key;
err = GRUB_ERR_NONE;
error:
grub_free (type_oid);
grub_free (empty_auth);
return err;
}
void
grub_tpm2key_end_parsing (asn1_node tpm2key)
{
asn1_delete_structure (&tpm2key);
tpm2key = NULL;
}
grub_err_t
grub_tpm2key_get_rsaparent (asn1_node tpm2key, grub_uint8_t *rsaparent)
{
void *bool_str = NULL;
grub_size_t bool_str_size = 0;
int ret;
if (rsaparent == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "NULL pointer detected");
if (tpm2key == NULL)
return grub_error (GRUB_ERR_READ_ERROR, "invalid parent node");
ret = asn1_allocate_and_read (tpm2key, "rsaParent", &bool_str, &bool_str_size);
if (ret == ASN1_SUCCESS)
{
if (grub_strncmp ("TRUE", bool_str, bool_str_size) == 0)
*rsaparent = 1;
else
*rsaparent = 0;
}
else if (ret == ASN1_ELEMENT_NOT_FOUND)
*rsaparent = 0;
else
return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve rsaParent");
grub_free (bool_str);
return GRUB_ERR_NONE;
}
grub_err_t
grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent)
{
int ret;
if (parent == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "NULL pointer detected");
if (tpm2key == NULL)
return grub_error (GRUB_ERR_READ_ERROR, "invalid parent node");
ret = asn1_read_uint32 (tpm2key, "parent", parent);
if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve parent");
return GRUB_ERR_NONE;
}
static grub_err_t
tpm2key_get_octstring (asn1_node tpm2key, const char *name, void **data, grub_size_t *size)
{
int ret;
if (name == NULL || data == NULL || size == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid parameter(s)");
if (tpm2key == NULL)
return grub_error (GRUB_ERR_READ_ERROR, "invalid %s node", name);
ret = asn1_allocate_and_read (tpm2key, name, data, size);
if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve %s", name);
return GRUB_ERR_NONE;
}
grub_err_t
grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size)
{
return tpm2key_get_octstring (tpm2key, "pubkey", data, size);
}
grub_err_t
grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size)
{
return tpm2key_get_octstring (tpm2key, "privkey", data, size);
}
/*
* The maximum and minimum number of elements for 'policy' and 'authPolicy' sequences
*
* Although there is no limit for the number of sequences elements, we set the upper
* bound to 99 to make it easier to implement the code.
*
* Any 'policy' or 'authPolicy' contains more than 99 commands/policies would become
* extremely complex to manage so it is impractical to support such use case.
*/
#define TPM2KEY_ELEMENTS_MAX 99
#define TPM2KEY_ELEMENTS_MIN 1
/*
* The string to fetch 'Policy' from 'authPolicy':
* authPolicy.?XX.Policy
*/
#define AUTHPOLICY_POL_MAX_STR "authPolicy.?XX.Policy"
#define AUTHPOLICY_POL_MAX (sizeof (AUTHPOLICY_POL_MAX_STR))
/*
* Expected strings for CommandCode and CommandPolicy:
* policy.?XX.CommandCode
* policy.?XX.CommandPolicy
* authPolicy.?XX.Policy.?YY.CommandCode
* authPolicy.?XX.Policy.?YY.CommandPolicy
*/
#define CMD_CODE_MAX_STR AUTHPOLICY_POL_MAX_STR".?YY.CommandCode"
#define CMD_POL_MAX_STR AUTHPOLICY_POL_MAX_STR".?YY.CommandPolicy"
#define CMD_CODE_MAX (sizeof (CMD_CODE_MAX_STR))
#define CMD_POL_MAX (sizeof (CMD_POL_MAX_STR))
static int
tpm2key_get_policy_seq (asn1_node tpm2key, const char *prefix,
tpm2key_policy_t *policy_seq)
{
tpm2key_policy_t tmp_seq = NULL;
tpm2key_policy_t policy = NULL;
int policy_n;
char cmd_code[CMD_CODE_MAX];
char cmd_pol[CMD_POL_MAX];
grub_size_t cmd_policy_len;
int i;
int ret;
ret = asn1_number_of_elements (tpm2key, prefix, &policy_n);
if (ret != ASN1_SUCCESS)
return ret;
/*
* Limit the number of policy commands to two digits (99)
* Although there is no upper bound for the number of policy commands,
* in practice, it takes one or two policy commands to unseal the key,
* so the 99 commands limit is more than enough.
*/
if (policy_n > TPM2KEY_ELEMENTS_MAX || policy_n < TPM2KEY_ELEMENTS_MIN)
return ASN1_VALUE_NOT_VALID;
/*
* Iterate the policy commands backwards since grub_list_push() prepends
* the item into the list.
*/
for (i = policy_n; i >= 1; i--) {
policy = grub_zalloc (sizeof (struct tpm2key_policy));
if (policy == NULL)
{
ret = ASN1_MEM_ALLOC_ERROR;
goto error;
}
grub_snprintf (cmd_code, CMD_CODE_MAX, "%s.?%d.CommandCode", prefix, i);
grub_snprintf (cmd_pol, CMD_POL_MAX, "%s.?%d.CommandPolicy", prefix, i);
/* CommandCode [0] EXPLICIT INTEGER */
ret = asn1_read_uint32 (tpm2key, cmd_code, &policy->cmd_code);
if (ret != ASN1_SUCCESS)
return ret;
/* CommandPolicy [1] EXPLICIT OCTET STRING */
ret = tpm2key_get_octstring (tpm2key, cmd_pol, &policy->cmd_policy,
&cmd_policy_len);
if (ret != ASN1_SUCCESS)
{
goto error;
}
else if (cmd_policy_len > GRUB_TPM2_BUFFER_CAPACITY)
{
/*
* CommandPolicy is the marshalled parameters for the TPM command so
* it should not be larger than the maximum TPM2 buffer.
*/
ret = ASN1_VALUE_NOT_VALID;
goto error;
}
policy->cmd_policy_len = (grub_uint16_t)cmd_policy_len;
/* Prepend the policy command into the sequence */
grub_list_push (GRUB_AS_LIST_P (&tmp_seq), GRUB_AS_LIST (policy));
}
*policy_seq = tmp_seq;
return ASN1_SUCCESS;
error:
if (policy != NULL)
{
grub_free (policy->cmd_policy);
grub_free (policy);
}
grub_tpm2key_free_policy_seq (tmp_seq);
return ret;
}
grub_err_t
grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq)
{
int ret;
ret = tpm2key_get_policy_seq (tpm2key, "policy", policy_seq);
if (ret == ASN1_ELEMENT_NOT_FOUND)
{
/* "policy" is optional, so it may not be available */
*policy_seq = NULL;
return GRUB_ERR_NONE;
}
else if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve policy");
return GRUB_ERR_NONE;
}
void
grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq)
{
tpm2key_policy_t policy;
tpm2key_policy_t next;
if (policy_seq == NULL)
return;
FOR_LIST_ELEMENTS_SAFE (policy, next, policy_seq)
{
grub_free (policy->cmd_policy);
grub_free (policy);
}
}
grub_err_t
grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq)
{
tpm2key_authpolicy_t tmp_seq = NULL;
tpm2key_authpolicy_t authpol = NULL;
int authpol_n;
char authpol_pol[AUTHPOLICY_POL_MAX];
int i;
int ret;
grub_err_t err;
ret = asn1_number_of_elements (tpm2key, "authPolicy", &authpol_n);
if (ret == ASN1_ELEMENT_NOT_FOUND)
{
/* "authPolicy" is optional, so it may not be available */
*authpol_seq = NULL;
return GRUB_ERR_NONE;
}
else if (ret != ASN1_SUCCESS)
return grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve authPolicy");
/* Limit the number of authPolicy elements to two digits (99) */
if (authpol_n > TPM2KEY_ELEMENTS_MAX || authpol_n < TPM2KEY_ELEMENTS_MIN)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid number of authPolicy elements");
/*
* Iterate the authPolicy elements backwards since grub_list_push() prepends
* the item into the list.
*/
for (i = authpol_n; i >= 1; i--) {
authpol = grub_zalloc (sizeof (struct tpm2key_authpolicy));
if (authpol == NULL)
{
err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate memory for authPolicy");
goto error;
}
grub_snprintf (authpol_pol, AUTHPOLICY_POL_MAX, "authPolicy.?%d.Policy", i);
ret = tpm2key_get_policy_seq (tpm2key, authpol_pol, &authpol->policy_seq);
if (ret != ASN1_SUCCESS)
{
err = grub_error (GRUB_ERR_READ_ERROR, "failed to retrieve policy from authPolicy");
goto error;
}
/* Prepend the authPolicy element into the sequence */
grub_list_push (GRUB_AS_LIST_P (&tmp_seq), GRUB_AS_LIST (authpol));
}
*authpol_seq = tmp_seq;
return GRUB_ERR_NONE;
error:
if (authpol != NULL)
{
grub_tpm2key_free_policy_seq (authpol->policy_seq);
grub_free (authpol);
}
grub_tpm2key_free_authpolicy_seq (tmp_seq);
return err;
}
void
grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq)
{
tpm2key_authpolicy_t authpol;
tpm2key_authpolicy_t next;
if (authpol_seq == NULL)
return;
FOR_LIST_ELEMENTS_SAFE (authpol, next, authpol_seq)
{
grub_tpm2key_free_policy_seq (authpol->policy_seq);
grub_free (authpol);
}
}

View file

@ -1,87 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2023 SUSE LLC
* Copyright (C) 2024 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/>.
*/
#ifndef GRUB_TPM2_TPM2KEY_HEADER
#define GRUB_TPM2_TPM2KEY_HEADER 1
#include <grub/types.h>
#include <libtasn1.h>
/*
* TPMPolicy ::= SEQUENCE {
* CommandCode [0] EXPLICIT INTEGER,
* CommandPolicy [1] EXPLICIT OCTET STRING
* }
*/
struct tpm2key_policy {
struct tpm2key_policy *next;
struct tpm2key_policy **prev;
grub_uint32_t cmd_code;
void *cmd_policy;
grub_uint16_t cmd_policy_len;
};
typedef struct tpm2key_policy *tpm2key_policy_t;
/*
* TPMAuthPolicy ::= SEQUENCE {
* Name [0] EXPLICIT UTF8String OPTIONAL,
* Policy [1] EXPLICIT SEQUENCE OF TPMPolicy
* }
*
* Name is not a necessary part to unseal the key. Ignore it.
*/
struct tpm2key_authpolicy {
struct tpm2key_authpolicy *next;
struct tpm2key_authpolicy **prev;
/* char *name; */
tpm2key_policy_t policy_seq;
};
typedef struct tpm2key_authpolicy *tpm2key_authpolicy_t;
extern grub_err_t
grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size);
extern void
grub_tpm2key_end_parsing (asn1_node tpm2key);
extern grub_err_t
grub_tpm2key_get_rsaparent (asn1_node tpm2key, grub_uint8_t *rsaparent);
extern grub_err_t
grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent);
extern grub_err_t
grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size);
extern grub_err_t
grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size);
extern grub_err_t
grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq);
extern void
grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq);
extern grub_err_t
grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq);
extern void
grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq);
#endif /* GRUB_TPM2_TPM2KEY_HEADER */

View file

@ -1,63 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2024 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/>.
*/
/*
* This file is generated by 'asn1Parser tpm2key.asn' and the '#include'
* headers are replaced with the ones in grub2.
* - 'grub/mm.h' for the definition of 'NULL'
* - 'libtasn1.h' for the definition of 'asn1_static_node'
*/
#include <grub/mm.h>
#include <libtasn1.h>
const asn1_static_node tpm2key_asn1_tab[] = {
{ "TPM2KEY", 536875024, NULL },
{ NULL, 1073741836, NULL },
{ "TPMPolicy", 1610612741, NULL },
{ "CommandCode", 1610620931, NULL },
{ NULL, 2056, "0"},
{ "CommandPolicy", 536879111, NULL },
{ NULL, 2056, "1"},
{ "TPMAuthPolicy", 1610612741, NULL },
{ "Name", 1610637346, NULL },
{ NULL, 2056, "0"},
{ "Policy", 536879115, NULL },
{ NULL, 1073743880, "1"},
{ NULL, 2, "TPMPolicy"},
{ "TPMKey", 536870917, NULL },
{ "type", 1073741836, NULL },
{ "emptyAuth", 1610637316, NULL },
{ NULL, 2056, "0"},
{ "policy", 1610637323, NULL },
{ NULL, 1073743880, "1"},
{ NULL, 2, "TPMPolicy"},
{ "secret", 1610637319, NULL },
{ NULL, 2056, "2"},
{ "authPolicy", 1610637323, NULL },
{ NULL, 1073743880, "3"},
{ NULL, 2, "TPMAuthPolicy"},
{ "description", 1610637346, NULL },
{ NULL, 2056, "4"},
{ "rsaParent", 1610637316, NULL },
{ NULL, 2056, "5"},
{ "parent", 1073741827, NULL },
{ "pubkey", 1073741831, NULL },
{ "privkey", 7, NULL },
{ NULL, 0, NULL }
};

View file

@ -152,7 +152,8 @@ struct grub_ahci_device
static grub_err_t static grub_err_t
grub_ahci_readwrite_real (struct grub_ahci_device *dev, grub_ahci_readwrite_real (struct grub_ahci_device *dev,
struct grub_disk_ata_pass_through_parms *parms, int reset); struct grub_disk_ata_pass_through_parms *parms,
int spinup, int reset);
enum enum
@ -572,7 +573,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
/* struct grub_disk_ata_pass_through_parms parms2; /* struct grub_disk_ata_pass_through_parms parms2;
grub_memset (&parms2, 0, sizeof (parms2)); grub_memset (&parms2, 0, sizeof (parms2));
parms2.taskfile.cmd = 8; parms2.taskfile.cmd = 8;
grub_ahci_readwrite_real (dev, &parms2, 1);*/ grub_ahci_readwrite_real (dev, &parms2, 1, 1);*/
} }
endtime = grub_get_time_ms () + 32000; endtime = grub_get_time_ms () + 32000;
@ -907,14 +908,15 @@ grub_ahci_reset_port (struct grub_ahci_device *dev, int force)
dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error; dev->hba->ports[dev->port].sata_error = dev->hba->ports[dev->port].sata_error;
grub_memset (&parms2, 0, sizeof (parms2)); grub_memset (&parms2, 0, sizeof (parms2));
parms2.taskfile.cmd = 8; parms2.taskfile.cmd = 8;
return grub_ahci_readwrite_real (dev, &parms2, 1); return grub_ahci_readwrite_real (dev, &parms2, 1, 1);
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
static grub_err_t static grub_err_t
grub_ahci_readwrite_real (struct grub_ahci_device *dev, grub_ahci_readwrite_real (struct grub_ahci_device *dev,
struct grub_disk_ata_pass_through_parms *parms, int reset) struct grub_disk_ata_pass_through_parms *parms,
int spinup, int reset)
{ {
struct grub_pci_dma_chunk *bufc; struct grub_pci_dma_chunk *bufc;
grub_uint64_t endtime; grub_uint64_t endtime;
@ -1036,7 +1038,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
grub_dprintf ("ahci", "AHCI tfd = %x\n", grub_dprintf ("ahci", "AHCI tfd = %x\n",
dev->hba->ports[dev->port].task_file_data); dev->hba->ports[dev->port].task_file_data);
endtime = grub_get_time_ms () + 20000; endtime = grub_get_time_ms () + (spinup ? 20000 : 20000);
while ((dev->hba->ports[dev->port].command_issue & 1)) while ((dev->hba->ports[dev->port].command_issue & 1))
if (grub_get_time_ms () > endtime || if (grub_get_time_ms () > endtime ||
(dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK)) (dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK))
@ -1095,9 +1097,9 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
static grub_err_t static grub_err_t
grub_ahci_readwrite (grub_ata_t disk, grub_ahci_readwrite (grub_ata_t disk,
struct grub_disk_ata_pass_through_parms *parms, struct grub_disk_ata_pass_through_parms *parms,
int spinup __attribute__((__unused__))) int spinup)
{ {
return grub_ahci_readwrite_real (disk->data, parms, 0); return grub_ahci_readwrite_real (disk->data, parms, spinup, 0);
} }
static grub_err_t static grub_err_t

View file

@ -112,10 +112,10 @@ grub_ata_identify (struct grub_ata *dev)
return grub_atapi_identify (dev); return grub_atapi_identify (dev);
info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE); info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE);
if (info64 == NULL)
return grub_errno;
info32 = (grub_uint32_t *) info64; info32 = (grub_uint32_t *) info64;
info16 = (grub_uint16_t *) info64; info16 = (grub_uint16_t *) info64;
if (! info16)
return grub_errno;
grub_memset (&parms, 0, sizeof (parms)); grub_memset (&parms, 0, sizeof (parms));
parms.buffer = info16; parms.buffer = info16;

View file

@ -17,7 +17,6 @@
*/ */
#include <grub/cryptodisk.h> #include <grub/cryptodisk.h>
#include <grub/env.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/dl.h> #include <grub/dl.h>
@ -27,8 +26,6 @@
#include <grub/file.h> #include <grub/file.h>
#include <grub/procfs.h> #include <grub/procfs.h>
#include <grub/partition.h> #include <grub/partition.h>
#include <grub/key_protector.h>
#include <grub/safemath.h>
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
#include <grub/emu/hostdisk.h> #include <grub/emu/hostdisk.h>
@ -47,8 +44,7 @@ enum
OPTION_KEYFILE, OPTION_KEYFILE,
OPTION_KEYFILE_OFFSET, OPTION_KEYFILE_OFFSET,
OPTION_KEYFILE_SIZE, OPTION_KEYFILE_SIZE,
OPTION_HEADER, OPTION_HEADER
OPTION_PROTECTOR
}; };
static const struct grub_arg_option options[] = static const struct grub_arg_option options[] =
@ -62,8 +58,6 @@ static const struct grub_arg_option options[] =
{"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT}, {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
{"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT}, {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
{"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING}, {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
{"protector", 'P', GRUB_ARG_OPTION_REPEATABLE,
N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0}
}; };
@ -1067,7 +1061,6 @@ grub_cryptodisk_scan_device_real (const char *name,
grub_err_t ret = GRUB_ERR_NONE; grub_err_t ret = GRUB_ERR_NONE;
grub_cryptodisk_t dev; grub_cryptodisk_t dev;
grub_cryptodisk_dev_t cr; grub_cryptodisk_dev_t cr;
int i;
struct cryptodisk_read_hook_ctx read_hook_data = {0}; struct cryptodisk_read_hook_ctx read_hook_data = {0};
int askpass = 0; int askpass = 0;
char *part = NULL; char *part = NULL;
@ -1120,175 +1113,41 @@ grub_cryptodisk_scan_device_real (const char *name,
goto error_no_close; goto error_no_close;
if (!dev) if (!dev)
continue; continue;
break;
}
if (dev == NULL) if (!cargs->key_len)
{ {
grub_error (GRUB_ERR_BAD_MODULE, /* Get the passphrase from the user, if no key data. */
"no cryptodisk module can handle this device"); askpass = 1;
goto error_no_close; part = grub_partition_get_name (source->partition);
} grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
source->partition != NULL ? "," : "",
part != NULL ? part : N_("UNKNOWN"),
dev->uuid);
grub_free (part);
if (cargs->protectors) cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
{ if (cargs->key_data == NULL)
for (i = 0; cargs->protectors[i]; i++) goto error_no_close;
{
if (cargs->key_cache[i].invalid)
continue;
if (cargs->key_cache[i].key == NULL) if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
{ {
ret = grub_key_protector_recover_key (cargs->protectors[i], grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
&cargs->key_cache[i].key,
&cargs->key_cache[i].key_len);
if (ret != GRUB_ERR_NONE)
{
if (grub_errno)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
grub_dprintf ("cryptodisk",
"failed to recover a key from key protector "
"%s, will not try it again for any other "
"disks, if any, during this invocation of "
"cryptomount\n",
cargs->protectors[i]);
cargs->key_cache[i].invalid = 1;
continue;
}
}
cargs->key_data = cargs->key_cache[i].key;
cargs->key_len = cargs->key_cache[i].key_len;
ret = cr->recover_key (source, dev, cargs);
if (ret != GRUB_ERR_NONE)
{
/* Reset key data to trigger the passphrase prompt later */
cargs->key_data = NULL;
cargs->key_len = 0;
part = grub_partition_get_name (source->partition);
grub_dprintf ("cryptodisk",
"recovered a key from key protector %s but it "
"failed to unlock %s%s%s (%s)\n",
cargs->protectors[i], source->name,
source->partition != NULL ? "," : "",
part != NULL ? part : N_("UNKNOWN"), dev->uuid);
grub_free (part);
continue;
}
else
{
ret = grub_cryptodisk_insert (dev, name, source);
if (ret != GRUB_ERR_NONE)
goto error;
#ifndef GRUB_UTIL
grub_cli_set_auth_needed ();
#endif
goto cleanup;
}
}
part = grub_partition_get_name (source->partition);
grub_error (GRUB_ERR_ACCESS_DENIED,
N_("no key protector provided a usable key for %s%s%s (%s)"),
source->name, source->partition != NULL ? "," : "",
part != NULL ? part : N_("UNKNOWN"), dev->uuid);
grub_free (part);
}
if (cargs->key_len)
{
ret = cr->recover_key (source, dev, cargs);
if (ret != GRUB_ERR_NONE)
goto error;
}
else
{
/* Get the passphrase from the user, if no key data. */
unsigned long tries = 3;
const char *tries_env;
/*
* Print the error from key protectors and clear grub_errno.
*
* Since '--protector' cannot coexist with '--password' and
* '--key-file', in case key protectors fail, only
* "cargs->key_len == 0" is expected, so cryptomount falls back
* here to request the passphrase.
*
* To avoid the error from key protectors stops the further code,
* print the error to notify the user why key protectors fail and
* clear grub_errno to have a fresh start.
*/
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
askpass = 1;
cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
if (cargs->key_data == NULL)
goto error_no_close;
tries_env = grub_env_get ("cryptodisk_passphrase_tries");
if (tries_env != NULL && tries_env[0] != '\0')
{
unsigned long tries_env_val;
const char *p;
tries_env_val = grub_strtoul (tries_env, &p, 0);
if (*p == '\0' && tries_env_val != ~0UL)
tries = tries_env_val;
else
grub_printf_ (N_("Invalid cryptodisk_passphrase_tries value `%s'. Defaulting to %lu.\n"),
tries_env,
tries);
}
for (; tries > 0; tries--)
{
part = grub_partition_get_name (source->partition);
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
source->partition != NULL ? "," : "",
part != NULL ? part : N_("UNKNOWN"),
dev->uuid);
grub_free (part);
if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
goto error;
}
cargs->key_len = grub_strlen ((char *) cargs->key_data);
ret = cr->recover_key (source, dev, cargs);
if (ret == GRUB_ERR_NONE)
break;
if (ret != GRUB_ERR_ACCESS_DENIED || tries == 1)
goto error; goto error;
grub_puts_ (N_("Invalid passphrase.")); }
cargs->key_len = grub_strlen ((char *) cargs->key_data);
}
/* ret = cr->recover_key (source, dev, cargs);
* Since recover_key() calls a function that returns grub_errno, if (ret != GRUB_ERR_NONE)
* a leftover error value from a previously rejected passphrase goto error;
* will trigger a phantom failure. We therefore clear it before
* trying a new passphrase.
*/
grub_errno = GRUB_ERR_NONE;
}
}
ret = grub_cryptodisk_insert (dev, name, source); ret = grub_cryptodisk_insert (dev, name, source);
if (ret != GRUB_ERR_NONE) if (ret != GRUB_ERR_NONE)
goto error; goto error;
goto cleanup;
}
grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
goto cleanup; goto cleanup;
error: error:
@ -1302,7 +1161,6 @@ grub_cryptodisk_scan_device_real (const char *name,
if (askpass) if (askpass)
{ {
grub_memset (cargs->key_data, 0, cargs->key_len);
cargs->key_len = 0; cargs->key_len = 0;
grub_free (cargs->key_data); grub_free (cargs->key_data);
} }
@ -1401,24 +1259,6 @@ grub_cryptodisk_scan_device (const char *name,
return ret; return ret;
} }
static void
grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
{
int i;
if (cargs->key_cache == NULL || cargs->protectors == NULL)
return;
for (i = 0; cargs->protectors[i]; i++)
{
if (cargs->key_cache[i].key)
grub_memset (cargs->key_cache[i].key, 0, cargs->key_cache[i].key_len);
grub_free (cargs->key_cache[i].key);
}
grub_free (cargs->key_cache);
}
static grub_err_t static grub_err_t
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{ {
@ -1431,14 +1271,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
if (grub_cryptodisk_list == NULL) if (grub_cryptodisk_list == NULL)
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"a password and a key protector cannot both be set");
if (state[OPTION_KEYFILE].set && state[OPTION_PROTECTOR].set) /* key file and key protector */
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"a key file and a key protector cannot both be set");
if (state[OPTION_PASSWORD].set) /* password */ if (state[OPTION_PASSWORD].set) /* password */
{ {
cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg; cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg;
@ -1488,9 +1320,9 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
if (keyfile_offset > keyfile->size) if (keyfile_offset > keyfile->size)
return grub_error (GRUB_ERR_OUT_OF_RANGE, return grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("Keyfile offset, %llu, is greater than " N_("Keyfile offset, %llu, is greater than"
"keyfile size, %llu"), "keyfile size, %" PRIuGRUB_UINT64_T),
keyfile_offset, (unsigned long long) keyfile->size); keyfile_offset, keyfile->size);
if (grub_file_seek (keyfile, (grub_off_t) keyfile_offset) == (grub_off_t) -1) if (grub_file_seek (keyfile, (grub_off_t) keyfile_offset) == (grub_off_t) -1)
return grub_errno; return grub_errno;
@ -1531,15 +1363,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
return grub_errno; return grub_errno;
} }
if (state[OPTION_PROTECTOR].set) /* key protector(s) */
{
cargs.key_cache = grub_calloc (state[OPTION_PROTECTOR].set, sizeof (*cargs.key_cache));
if (cargs.key_cache == NULL)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"no memory for key protector key cache");
cargs.protectors = state[OPTION_PROTECTOR].args;
}
if (state[OPTION_UUID].set) /* uuid */ if (state[OPTION_UUID].set) /* uuid */
{ {
int found_uuid; int found_uuid;
@ -1548,7 +1371,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
dev = grub_cryptodisk_get_by_uuid (args[0]); dev = grub_cryptodisk_get_by_uuid (args[0]);
if (dev) if (dev)
{ {
grub_cryptodisk_clear_key_cache (&cargs);
grub_dprintf ("cryptodisk", grub_dprintf ("cryptodisk",
"already mounted as crypto%lu\n", dev->id); "already mounted as crypto%lu\n", dev->id);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -1557,7 +1379,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
cargs.check_boot = state[OPTION_BOOT].set; cargs.check_boot = state[OPTION_BOOT].set;
cargs.search_uuid = args[0]; cargs.search_uuid = args[0];
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
grub_cryptodisk_clear_key_cache (&cargs);
if (found_uuid) if (found_uuid)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -1577,7 +1398,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{ {
cargs.check_boot = state[OPTION_BOOT].set; cargs.check_boot = state[OPTION_BOOT].set;
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
grub_cryptodisk_clear_key_cache (&cargs);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
else else
@ -1601,7 +1421,6 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
disk = grub_disk_open (diskname); disk = grub_disk_open (diskname);
if (!disk) if (!disk)
{ {
grub_cryptodisk_clear_key_cache (&cargs);
if (disklast) if (disklast)
*disklast = ')'; *disklast = ')';
return grub_errno; return grub_errno;
@ -1612,14 +1431,12 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{ {
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id); grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
grub_disk_close (disk); grub_disk_close (disk);
grub_cryptodisk_clear_key_cache (&cargs);
if (disklast) if (disklast)
*disklast = ')'; *disklast = ')';
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
grub_cryptodisk_clear_key_cache (&cargs);
grub_disk_close (disk); grub_disk_close (disk);
if (disklast) if (disklast)
@ -1656,7 +1473,7 @@ static char *
luks_script_get (grub_size_t *sz) luks_script_get (grub_size_t *sz)
{ {
grub_cryptodisk_t i; grub_cryptodisk_t i;
grub_size_t size = 0, mul; grub_size_t size = 0;
char *ptr, *ret; char *ptr, *ret;
*sz = 0; *sz = 0;
@ -1665,6 +1482,10 @@ luks_script_get (grub_size_t *sz)
if (grub_strcmp (i->modname, "luks") == 0 || if (grub_strcmp (i->modname, "luks") == 0 ||
grub_strcmp (i->modname, "luks2") == 0) grub_strcmp (i->modname, "luks2") == 0)
{ {
size += grub_strlen (i->modname);
size += sizeof ("_mount");
size += grub_strlen (i->uuid);
size += grub_strlen (i->cipher->cipher->name);
/* /*
* Add space in the line for (in order) spaces, cipher mode, cipher IV * Add space in the line for (in order) spaces, cipher mode, cipher IV
* mode, sector offset, sector size and the trailing newline. This is * mode, sector offset, sector size and the trailing newline. This is
@ -1672,35 +1493,14 @@ luks_script_get (grub_size_t *sz)
* in an earlier version of this code that are unaccounted for. It is * in an earlier version of this code that are unaccounted for. It is
* left in the calculations in case it is needed. At worst, its short- * left in the calculations in case it is needed. At worst, its short-
* lived wasted space. * lived wasted space.
*
* 60 = 5 + 5 + 8 + 20 + 6 + 1 + 15
*/ */
if (grub_add (size, grub_strlen (i->modname), &size) || size += 5 + 5 + 8 + 20 + 6 + 1 + 15;
grub_add (size, sizeof ("_mount") + 60, &size) ||
grub_add (size, grub_strlen (i->uuid), &size) ||
grub_add (size, grub_strlen (i->cipher->cipher->name), &size) ||
grub_mul (i->keysize, 2, &mul) ||
grub_add (size, mul, &size))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script");
return 0;
}
if (i->essiv_hash) if (i->essiv_hash)
{ size += grub_strlen (i->essiv_hash->name);
if (grub_add (size, grub_strlen (i->essiv_hash->name), &size)) size += i->keysize * 2;
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script");
return 0;
}
}
} }
if (grub_add (size, 1, &size))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script");
return 0;
}
ret = grub_malloc (size); ret = grub_malloc (size + 1);
if (!ret) if (!ret)
return 0; return 0;
@ -1776,114 +1576,6 @@ luks_script_get (grub_size_t *sz)
return ret; return ret;
} }
#ifdef GRUB_MACHINE_EFI
grub_err_t
grub_cryptodisk_challenge_password (void)
{
grub_cryptodisk_t cr_dev;
for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next)
{
grub_cryptodisk_dev_t cr;
grub_disk_t source = NULL;
grub_err_t ret = GRUB_ERR_NONE;
grub_cryptodisk_t dev = NULL;
char *part = NULL;
struct grub_cryptomount_args cargs = {0};
cargs.check_boot = 0;
cargs.search_uuid = cr_dev->uuid;
source = grub_disk_open (cr_dev->source);
if (source == NULL)
{
ret = grub_errno;
goto error_out;
}
FOR_CRYPTODISK_DEVS (cr)
{
dev = cr->scan (source, &cargs);
if (grub_errno)
{
ret = grub_errno;
goto error_out;
}
if (dev == NULL)
continue;
break;
}
if (dev == NULL)
{
ret = grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
goto error_out;
}
part = grub_partition_get_name (source->partition);
grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
source->partition != NULL ? "," : "",
part != NULL ? part : N_("UNKNOWN"), cr_dev->uuid);
grub_free (part);
cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
if (cargs.key_data == NULL)
{
ret = grub_errno;
goto error_out;
}
if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
{
ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
goto error_out;
}
cargs.key_len = grub_strlen ((char *) cargs.key_data);
ret = cr->recover_key (source, dev, &cargs);
error_out:
grub_disk_close (source);
if (dev != NULL)
cryptodisk_close (dev);
if (cargs.key_data)
{
grub_memset (cargs.key_data, 0, cargs.key_len);
grub_free (cargs.key_data);
}
return ret;
}
return GRUB_ERR_NONE;
}
void
grub_cryptodisk_erasesecrets (void)
{
grub_cryptodisk_t i;
grub_uint8_t *buf;
buf = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN);
if (buf == NULL)
grub_fatal ("grub_cryptodisk_erasesecrets: cannot allocate memory");
for (i = cryptodisk_list; i != NULL; i = i->next)
if (grub_cryptodisk_setkey (i, buf, i->keysize))
grub_fatal ("grub_cryptodisk_erasesecrets: cannot erase secrets for %s", i->source);
else
grub_printf ("Erased crypto secrets for %s\n", i->source);
/*
* Unfortunately, there is no way to "force unmount" a given disk, it may
* have mounted "child" disks as well, e.g., an LVM volume. So, this
* function MUST be called when there is no way back, e.g., when exiting.
* Otherwise, subsequent read calls for a cryptodisk will return garbage.
*/
grub_free (buf);
}
#endif /* GRUB_MACHINE_EFI */
struct grub_procfs_entry luks_script = struct grub_procfs_entry luks_script =
{ {
.name = "luks_script", .name = "luks_script",
@ -1898,7 +1590,6 @@ GRUB_MOD_INIT (cryptodisk)
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
N_("[ [-p password] | [-k keyfile" N_("[ [-p password] | [-k keyfile"
" [-O keyoffset] [-S keysize] ] ] [-H file]" " [-O keyoffset] [-S keysize] ] ] [-H file]"
" [-P protector [-P protector ...]]"
" <SOURCE|-u UUID|-a|-b>"), " <SOURCE|-u UUID|-a|-b>"),
N_("Mount a crypto device."), options); N_("Mount a crypto device."), options);
grub_procfs_register ("luks_script", &luks_script); grub_procfs_register ("luks_script", &luks_script);
@ -1906,9 +1597,6 @@ GRUB_MOD_INIT (cryptodisk)
GRUB_MOD_FINI (cryptodisk) GRUB_MOD_FINI (cryptodisk)
{ {
#ifdef GRUB_MACHINE_EFI
grub_cryptodisk_erasesecrets ();
#endif
grub_disk_dev_unregister (&grub_cryptodisk_dev); grub_disk_dev_unregister (&grub_cryptodisk_dev);
cryptodisk_cleanup (); cryptodisk_cleanup ();
grub_unregister_extcmd (cmd); grub_unregister_extcmd (cmd);

View file

@ -20,12 +20,10 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/command.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/diskfilter.h> #include <grub/diskfilter.h>
#include <grub/partition.h> #include <grub/partition.h>
#include <grub/safemath.h>
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/util/misc.h> #include <grub/util/misc.h>
@ -228,28 +226,15 @@ scan_devices (const char *arname)
int need_rescan; int need_rescan;
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
{ for (p = grub_disk_dev_list; p; p = p->next)
/* look up the crytodisk devices first */ if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
for (p = grub_disk_dev_list; p; p = p->next) && p->disk_iterate)
if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID && p->disk_iterate) {
{ if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
if ((p->disk_iterate) (scan_disk_hook, NULL, pull)) return;
return; if (arname && is_lv_readable (find_lv (arname), 1))
if (arname && is_lv_readable (find_lv (arname), 1)) return;
return; }
break;
}
/* check the devices other than crytodisk */
for (p = grub_disk_dev_list; p; p = p->next)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID && p->disk_iterate)
{
if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
return;
if (arname && is_lv_readable (find_lv (arname), 1))
return;
}
}
scan_depth = 0; scan_depth = 0;
need_rescan = 1; need_rescan = 1;
@ -981,6 +966,8 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
for (lv = vg->lvs; lv; lv = lv->next) for (lv = vg->lvs; lv; lv = lv->next)
{ {
grub_err_t err;
/* RAID 1 and single-disk RAID 0 don't use a chunksize but code /* RAID 1 and single-disk RAID 0 don't use a chunksize but code
assumes one so set one. */ assumes one so set one. */
for (i = 0; i < lv->segment_count; i++) for (i = 0; i < lv->segment_count; i++)
@ -992,10 +979,6 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
&& lv->segments[i].stripe_size == 0) && lv->segments[i].stripe_size == 0)
lv->segments[i].stripe_size = 64; lv->segments[i].stripe_size = 64;
} }
}
for (lv = vg->lvs; lv; lv = lv->next)
{
grub_err_t err;
err = validate_lv(lv); err = validate_lv(lv);
if (err) if (err)
@ -1056,7 +1039,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
{ {
struct grub_diskfilter_vg *array; struct grub_diskfilter_vg *array;
int i; int i;
grub_size_t j, sz; grub_size_t j;
grub_uint64_t totsize; grub_uint64_t totsize;
struct grub_diskfilter_pv *pv; struct grub_diskfilter_pv *pv;
grub_err_t err; grub_err_t err;
@ -1157,11 +1140,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
} }
array->lvs->vg = array; array->lvs->vg = array;
if (grub_mul (uuidlen, 2, &sz) || array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen);
grub_add (sz, sizeof ("mduuid/"), &sz))
goto fail;
array->lvs->idname = grub_malloc (sz);
if (!array->lvs->idname) if (!array->lvs->idname)
goto fail; goto fail;
@ -1378,86 +1357,6 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk,
} }
#endif #endif
static int
grub_diskfilter_check_pvs_encrypted (grub_disk_t disk, int *pvs_cnt)
{
struct grub_diskfilter_lv *lv = disk->data;
struct grub_diskfilter_pv *pv;
*pvs_cnt = 0;
if (lv->vg->pvs)
for (pv = lv->vg->pvs; pv; pv = pv->next)
{
(*pvs_cnt)++;
if (pv->disk == NULL)
{
/* Can be a partially activated VG, bail out. */
return GRUB_ERR_TEST_FAILURE;
}
if (pv->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
{
/* All backing devices must be cryptodisks, stop. */
return GRUB_ERR_TEST_FAILURE;
}
}
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_disk_t disk;
int check_pvs_res;
int namelen;
int pvs_cnt;
int opt_quiet = 0;
if (argc == 2)
{
if (grub_strcmp (args[0], "--quiet") == 0)
{
opt_quiet = 1;
argc--;
args++;
}
else
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized option: %s"), args[0]);
}
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected"));
namelen = grub_strlen (args[0]);
if (namelen > 2 && (args[0][0] == '(') && (args[0][namelen - 1] == ')'))
args[0][namelen - 1] = 0;
else
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("invalid disk: %s"),
args[0]);
if (!is_valid_diskfilter_name (&args[0][1]))
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("unrecognized disk: %s"),
&args[0][1]);
disk = grub_disk_open (&args[0][1]);
if (disk == NULL)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such disk: %s"),
&args[0][1]);
check_pvs_res = grub_diskfilter_check_pvs_encrypted (disk, &pvs_cnt);
grub_disk_close (disk);
if (!opt_quiet)
grub_printf ("%s is %sencrypted (%d pv%s examined)\n", &args[0][1],
(check_pvs_res == GRUB_ERR_NONE) ? "" : "un",
pvs_cnt,
(pvs_cnt > 1) ? "s" : "");
return check_pvs_res;
}
static struct grub_disk_dev grub_diskfilter_dev = static struct grub_disk_dev grub_diskfilter_dev =
{ {
.name = "diskfilter", .name = "diskfilter",
@ -1474,21 +1373,14 @@ static struct grub_disk_dev grub_diskfilter_dev =
.next = 0 .next = 0
}; };
static grub_command_t cmd;
GRUB_MOD_INIT(diskfilter) GRUB_MOD_INIT(diskfilter)
{ {
grub_disk_dev_register (&grub_diskfilter_dev); grub_disk_dev_register (&grub_diskfilter_dev);
cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck,
N_("[--quiet] DEVICE"),
N_("Check if a logical volume resides on encrypted disks."));
} }
GRUB_MOD_FINI(diskfilter) GRUB_MOD_FINI(diskfilter)
{ {
grub_disk_dev_unregister (&grub_diskfilter_dev); grub_disk_dev_unregister (&grub_diskfilter_dev);
if (cmd != NULL)
grub_unregister_command (cmd);
free_array (); free_array ();
} }

View file

@ -26,7 +26,6 @@
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/scsicmd.h> #include <grub/scsicmd.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/safemath.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/ieee1275/obdisk.h> #include <grub/ieee1275/obdisk.h>
@ -129,17 +128,9 @@ count_commas (const char *src)
static char * static char *
decode_grub_devname (const char *name) decode_grub_devname (const char *name)
{ {
char *devpath; char *devpath = grub_malloc (grub_strlen (name) + 1);
char *p, c; char *p, c;
grub_size_t sz;
if (grub_add (grub_strlen (name), 1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device name"));
return NULL;
}
devpath = grub_malloc (sz);
if (devpath == NULL) if (devpath == NULL)
return NULL; return NULL;
@ -165,20 +156,12 @@ static char *
encode_grub_devname (const char *path) encode_grub_devname (const char *path)
{ {
char *encoding, *optr; char *encoding, *optr;
grub_size_t sz;
if (path == NULL) if (path == NULL)
return NULL; return NULL;
if (grub_add (sizeof (IEEE1275_DEV) + 1, count_commas (path), &sz) || encoding = grub_malloc (sizeof (IEEE1275_DEV) + count_commas (path) +
grub_add (sz, grub_strlen (path), &sz)) grub_strlen (path) + 1);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining encoding size"));
grub_print_error ();
return NULL;
}
encoding = grub_malloc (sz);
if (encoding == NULL) if (encoding == NULL)
{ {
@ -413,22 +396,8 @@ canonicalise_disk (const char *devname)
real_unit_str_len = grub_strlen (op->name) + sizeof (IEEE1275_DISK_ALIAS) real_unit_str_len = grub_strlen (op->name) + sizeof (IEEE1275_DISK_ALIAS)
+ grub_strlen (real_unit_address); + grub_strlen (real_unit_address);
if (grub_add (grub_strlen (op->name), sizeof (IEEE1275_DISK_ALIAS), &real_unit_str_len) ||
grub_add (real_unit_str_len, grub_strlen (real_unit_address), &real_unit_str_len))
{
grub_free (parent);
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of canonical name"));
grub_print_error ();
return NULL;
}
real_canon = grub_malloc (real_unit_str_len); real_canon = grub_malloc (real_unit_str_len);
if (real_canon == NULL)
{
grub_free (parent);
grub_print_error ();
return NULL;
}
grub_snprintf (real_canon, real_unit_str_len, "%s/disk@%s", grub_snprintf (real_canon, real_unit_str_len, "%s/disk@%s",
op->name, real_unit_address); op->name, real_unit_address);
@ -444,7 +413,6 @@ canonicalise_disk (const char *devname)
static struct disk_dev * static struct disk_dev *
add_canon_disk (const char *cname) add_canon_disk (const char *cname)
{ {
grub_size_t sz;
struct disk_dev *dev; struct disk_dev *dev;
dev = grub_zalloc (sizeof (struct disk_dev)); dev = grub_zalloc (sizeof (struct disk_dev));
@ -460,18 +428,13 @@ add_canon_disk (const char *cname)
* arguments and allows a client program to open * arguments and allows a client program to open
* the entire (raw) disk. Any disk label is ignored. * the entire (raw) disk. Any disk label is ignored.
*/ */
if (grub_add (grub_strlen (cname), sizeof (":nolabel"), &sz)) dev->raw_name = grub_malloc (grub_strlen (cname) + sizeof (":nolabel"));
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while appending :nolabel to end of canonical name");
goto failed;
}
dev->raw_name = grub_malloc (sz);
if (dev->raw_name == NULL) if (dev->raw_name == NULL)
goto failed; goto failed;
grub_snprintf (dev->raw_name, sz, "%s:nolabel", cname); grub_snprintf (dev->raw_name, grub_strlen (cname) + sizeof (":nolabel"),
"%s:nolabel", cname);
} }
/* /*

View file

@ -24,7 +24,6 @@
#include <grub/ieee1275/ofdisk.h> #include <grub/ieee1275/ofdisk.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/safemath.h>
static char *last_devpath; static char *last_devpath;
static grub_ieee1275_ihandle_t last_ihandle; static grub_ieee1275_ihandle_t last_ihandle;
@ -81,7 +80,6 @@ ofdisk_hash_add_real (char *devpath)
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
const char *iptr; const char *iptr;
char *optr; char *optr;
grub_size_t sz;
p = grub_zalloc (sizeof (*p)); p = grub_zalloc (sizeof (*p));
if (!p) if (!p)
@ -89,14 +87,8 @@ ofdisk_hash_add_real (char *devpath)
p->devpath = devpath; p->devpath = devpath;
if (grub_mul (grub_strlen (p->devpath), 2, &sz) || p->grub_devpath = grub_malloc (sizeof ("ieee1275/")
grub_add (sz, sizeof ("ieee1275/"), &sz)) + 2 * grub_strlen (p->devpath));
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path"));
return NULL;
}
p->grub_devpath = grub_malloc (sz);
if (!p->grub_devpath) if (!p->grub_devpath)
{ {
@ -106,13 +98,7 @@ ofdisk_hash_add_real (char *devpath)
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
{ {
if (grub_add (grub_strlen (p->devpath), 3, &sz)) p->open_path = grub_malloc (grub_strlen (p->devpath) + 3);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of an open path"));
return NULL;
}
p->open_path = grub_malloc (sz);
if (!p->open_path) if (!p->open_path)
{ {
grub_free (p->grub_devpath); grub_free (p->grub_devpath);
@ -238,7 +224,6 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
args; args;
char *buf, *bufptr; char *buf, *bufptr;
unsigned i; unsigned i;
grub_size_t sz;
if (grub_ieee1275_open (alias->path, &ihandle)) if (grub_ieee1275_open (alias->path, &ihandle))
return; return;
@ -258,19 +243,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
return; return;
} }
if (grub_add (grub_strlen (alias->path), 32, &sz)) buf = grub_malloc (grub_strlen (alias->path) + 32);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for vscsi");
grub_ieee1275_close (ihandle);
return;
}
buf = grub_malloc (sz);
if (!buf) if (!buf)
{ return;
grub_ieee1275_close (ihandle);
return;
}
bufptr = grub_stpcpy (buf, alias->path); bufptr = grub_stpcpy (buf, alias->path);
for (i = 0; i < args.nentries; i++) for (i = 0; i < args.nentries; i++)
@ -312,15 +287,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
grub_uint64_t *table; grub_uint64_t *table;
grub_uint16_t table_size; grub_uint16_t table_size;
grub_ieee1275_ihandle_t ihandle; grub_ieee1275_ihandle_t ihandle;
grub_size_t sz;
if (grub_add (grub_strlen (alias->path), sizeof ("/disk@7766554433221100"), &sz)) buf = grub_malloc (grub_strlen (alias->path) +
{ sizeof ("/disk@7766554433221100"));
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for sas_ioa");
return;
}
buf = grub_malloc (sz);
if (!buf) if (!buf)
return; return;
bufptr = grub_stpcpy (buf, alias->path); bufptr = grub_stpcpy (buf, alias->path);
@ -458,17 +427,9 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
static char * static char *
compute_dev_path (const char *name) compute_dev_path (const char *name)
{ {
char *devpath; char *devpath = grub_malloc (grub_strlen (name) + 3);
char *p, c; char *p, c;
grub_size_t sz;
if (grub_add (grub_strlen (name), 3, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path"));
return NULL;
}
devpath = grub_malloc (sz);
if (!devpath) if (!devpath)
return NULL; return NULL;
@ -664,7 +625,6 @@ insert_bootpath (void)
char *bootpath; char *bootpath;
grub_ssize_t bootpath_size; grub_ssize_t bootpath_size;
char *type; char *type;
grub_size_t sz;
if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath",
&bootpath_size) &bootpath_size)
@ -675,13 +635,7 @@ insert_bootpath (void)
return; return;
} }
if (grub_add (bootpath_size, 64, &sz)) bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining bootpath size"));
return;
}
bootpath = (char *) grub_malloc (sz);
if (! bootpath) if (! bootpath)
{ {
grub_print_error (); grub_print_error ();

View file

@ -1,73 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2022 Microsoft Corporation
* Copyright (C) 2024 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/dl.h>
#include <grub/list.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/key_protector.h>
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_key_protector *grub_key_protectors = NULL;
grub_err_t
grub_key_protector_register (struct grub_key_protector *protector)
{
if (protector == NULL || protector->name == NULL || protector->name[0] == '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for registration");
if (grub_key_protectors != NULL &&
grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector->name) != NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Key protector '%s' already registered", protector->name);
grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector));
return GRUB_ERR_NONE;
}
grub_err_t
grub_key_protector_unregister (struct grub_key_protector *protector)
{
if (protector == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration");
grub_list_remove (GRUB_AS_LIST (protector));
return GRUB_ERR_NONE;
}
grub_err_t
grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
grub_size_t *key_size)
{
struct grub_key_protector *kp = NULL;
if (grub_key_protectors == NULL)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered");
if (protector == NULL || protector[0] == '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector");
kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector);
if (kp == NULL)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector);
return kp->recover_key (key, key_size);
}

View file

@ -179,36 +179,6 @@ gpt_ldm_sector (grub_disk_t dsk)
return sector; return sector;
} }
static void
free_pv (struct grub_diskfilter_pv *pv)
{
if (pv == NULL)
return;
grub_free (pv->internal_id);
grub_free (pv->id.uuid);
grub_free (pv);
}
static void
free_lv (struct grub_diskfilter_lv *lv)
{
if (lv == NULL)
return;
grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv->fullname);
if (lv->segments)
{
unsigned int i;
for (i = 0; i < lv->segment_count; i++)
grub_free (lv->segments[i].nodes);
grub_free (lv->segments);
}
grub_free (lv);
}
static struct grub_diskfilter_vg * static struct grub_diskfilter_vg *
make_vg (grub_disk_t disk, make_vg (grub_disk_t disk,
const struct grub_ldm_label *label) const struct grub_ldm_label *label)
@ -226,8 +196,12 @@ make_vg (grub_disk_t disk,
vg->name = grub_malloc (LDM_NAME_STRLEN + 1); vg->name = grub_malloc (LDM_NAME_STRLEN + 1);
vg->uuid = grub_malloc (LDM_GUID_STRLEN + 1); vg->uuid = grub_malloc (LDM_GUID_STRLEN + 1);
if (! vg->uuid || !vg->name) if (! vg->uuid || !vg->name)
goto fail1; {
grub_free (vg->uuid);
grub_free (vg->name);
grub_free (vg);
return NULL;
}
grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN); grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN);
grub_memcpy (vg->name, label->group_name, LDM_NAME_STRLEN); grub_memcpy (vg->name, label->group_name, LDM_NAME_STRLEN);
vg->name[LDM_NAME_STRLEN] = 0; vg->name[LDM_NAME_STRLEN] = 0;
@ -246,7 +220,6 @@ make_vg (grub_disk_t disk,
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_ldm_vblk)]; / sizeof (struct grub_ldm_vblk)];
unsigned i; unsigned i;
grub_size_t sz;
err = grub_disk_read (disk, cursec, 0, err = grub_disk_read (disk, cursec, 0,
sizeof(vblk), &vblk); sizeof(vblk), &vblk);
if (err) if (err)
@ -278,16 +251,10 @@ make_vg (grub_disk_t disk,
grub_free (pv); grub_free (pv);
goto fail2; goto fail2;
} }
if (grub_add (ptr[0], 2, &sz)) pv->internal_id = grub_malloc (ptr[0] + 2);
{
grub_free (pv);
goto fail2;
}
pv->internal_id = grub_malloc (sz);
if (!pv->internal_id) if (!pv->internal_id)
{ {
free_pv (pv); grub_free (pv);
goto fail2; goto fail2;
} }
grub_memcpy (pv->internal_id, ptr, (grub_size_t) ptr[0] + 1); grub_memcpy (pv->internal_id, ptr, (grub_size_t) ptr[0] + 1);
@ -297,7 +264,7 @@ make_vg (grub_disk_t disk,
if (ptr + *ptr + 1 >= vblk[i].dynamic if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_pv (pv); grub_free (pv);
goto fail2; goto fail2;
} }
/* ptr = name. */ /* ptr = name. */
@ -305,23 +272,11 @@ make_vg (grub_disk_t disk,
if (ptr + *ptr + 1 if (ptr + *ptr + 1
>= vblk[i].dynamic + sizeof (vblk[i].dynamic)) >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_pv (pv); grub_free (pv);
goto fail2; goto fail2;
} }
pv->id.uuidlen = *ptr; pv->id.uuidlen = *ptr;
pv->id.uuid = grub_malloc (pv->id.uuidlen + 1);
if (grub_add (pv->id.uuidlen, 1, &sz))
{
free_pv (pv);
goto fail2;
}
pv->id.uuid = grub_malloc (sz);
if (pv->id.uuid == NULL)
{
free_pv (pv);
goto fail2;
}
grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen); grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen);
pv->id.uuid[pv->id.uuidlen] = 0; pv->id.uuid[pv->id.uuidlen] = 0;
@ -367,7 +322,7 @@ make_vg (grub_disk_t disk,
lv->segments = grub_zalloc (sizeof (*lv->segments)); lv->segments = grub_zalloc (sizeof (*lv->segments));
if (!lv->segments) if (!lv->segments)
{ {
free_lv (lv); grub_free (lv);
goto fail2; goto fail2;
} }
lv->segments->start_extent = 0; lv->segments->start_extent = 0;
@ -378,25 +333,20 @@ make_vg (grub_disk_t disk,
sizeof (*lv->segments->nodes)); sizeof (*lv->segments->nodes));
if (!lv->segments->nodes) if (!lv->segments->nodes)
{ {
free_lv (lv); grub_free (lv);
goto fail2; goto fail2;
} }
ptr = vblk[i].dynamic; ptr = vblk[i].dynamic;
if (ptr + *ptr + 1 >= vblk[i].dynamic if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv);
goto fail2; goto fail2;
} }
if (grub_add (ptr[0], 2, &sz)) lv->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2);
{
free_lv (lv);
goto fail2;
}
lv->internal_id = grub_malloc (sz);
if (!lv->internal_id) if (!lv->internal_id)
{ {
free_lv (lv); grub_free (lv);
goto fail2; goto fail2;
} }
grub_memcpy (lv->internal_id, ptr, ptr[0] + 1); grub_memcpy (lv->internal_id, ptr, ptr[0] + 1);
@ -406,18 +356,20 @@ make_vg (grub_disk_t disk,
if (ptr + *ptr + 1 >= vblk[i].dynamic if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv);
goto fail2; goto fail2;
} }
if (grub_add (*ptr, 1, &sz)) if (grub_add (*ptr, 1, &sz))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv);
goto fail2; goto fail2;
} }
lv->name = grub_malloc (sz); lv->name = grub_malloc (sz);
if (!lv->name) if (!lv->name)
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv);
goto fail2; goto fail2;
} }
grub_memcpy (lv->name, ptr + 1, *ptr); grub_memcpy (lv->name, ptr + 1, *ptr);
@ -426,28 +378,36 @@ make_vg (grub_disk_t disk,
vg->uuid, lv->name); vg->uuid, lv->name);
if (!lv->fullname) if (!lv->fullname)
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr + *ptr + 1 if (ptr + *ptr + 1
>= vblk[i].dynamic + sizeof (vblk[i].dynamic)) >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
/* ptr = volume type. */ /* ptr = volume type. */
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
/* ptr = flags. */ /* ptr = flags. */
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
@ -456,13 +416,17 @@ make_vg (grub_disk_t disk,
/* ptr = number of children. */ /* ptr = number of children. */
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
@ -472,7 +436,9 @@ make_vg (grub_disk_t disk,
|| ptr + *ptr + 1>= vblk[i].dynamic || ptr + *ptr + 1>= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_lv (lv); grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv);
goto fail2; goto fail2;
} }
lv->size = read_int (ptr + 1, *ptr); lv->size = read_int (ptr + 1, *ptr);
@ -489,7 +455,6 @@ make_vg (grub_disk_t disk,
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_ldm_vblk)]; / sizeof (struct grub_ldm_vblk)];
unsigned i; unsigned i;
grub_size_t sz;
err = grub_disk_read (disk, cursec, 0, err = grub_disk_read (disk, cursec, 0,
sizeof(vblk), &vblk); sizeof(vblk), &vblk);
if (err) if (err)
@ -522,18 +487,13 @@ make_vg (grub_disk_t disk,
ptr = vblk[i].dynamic; ptr = vblk[i].dynamic;
if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp);
goto fail2; goto fail2;
} }
if (grub_add (ptr[0], 2, &sz)) comp->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2);
{
free_lv (comp);
goto fail2;
}
comp->internal_id = grub_malloc (sz);
if (!comp->internal_id) if (!comp->internal_id)
{ {
free_lv (comp); grub_free (comp);
goto fail2; goto fail2;
} }
grub_memcpy (comp->internal_id, ptr, ptr[0] + 1); grub_memcpy (comp->internal_id, ptr, ptr[0] + 1);
@ -542,14 +502,16 @@ make_vg (grub_disk_t disk,
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
/* ptr = name. */ /* ptr = name. */
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
/* ptr = state. */ /* ptr = state. */
@ -559,7 +521,8 @@ make_vg (grub_disk_t disk,
ptr += 4; ptr += 4;
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
@ -567,14 +530,16 @@ make_vg (grub_disk_t disk,
ptr += *ptr + 1; ptr += *ptr + 1;
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
ptr += 8 + 8; ptr += 8 + 8;
if (ptr + *ptr + 1 >= vblk[i].dynamic if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
for (lv = vg->lvs; lv; lv = lv->next) for (lv = vg->lvs; lv; lv = lv->next)
@ -585,7 +550,8 @@ make_vg (grub_disk_t disk,
} }
if (!lv) if (!lv)
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
continue; continue;
} }
comp->size = lv->size; comp->size = lv->size;
@ -597,7 +563,8 @@ make_vg (grub_disk_t disk,
sizeof (*comp->segments)); sizeof (*comp->segments));
if (!comp->segments) if (!comp->segments)
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
} }
@ -608,7 +575,8 @@ make_vg (grub_disk_t disk,
comp->segments = grub_malloc (sizeof (*comp->segments)); comp->segments = grub_malloc (sizeof (*comp->segments));
if (!comp->segments) if (!comp->segments)
{ {
free_lv (comp); grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
comp->segments->start_extent = 0; comp->segments->start_extent = 0;
@ -623,21 +591,27 @@ make_vg (grub_disk_t disk,
} }
else else
{ {
free_lv (comp); grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
ptr += *ptr + 1; ptr += *ptr + 1;
ptr++; ptr++;
if (!(vblk[i].flags & 0x10)) if (!(vblk[i].flags & 0x10))
{ {
free_lv (comp); grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)
|| ptr + *ptr + 1 >= vblk[i].dynamic || ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
comp->segments->stripe_size = read_int (ptr + 1, *ptr); comp->segments->stripe_size = read_int (ptr + 1, *ptr);
@ -645,16 +619,20 @@ make_vg (grub_disk_t disk,
if (ptr + *ptr + 1 >= vblk[i].dynamic if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic)) + sizeof (vblk[i].dynamic))
{ {
free_lv (comp); grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
comp->segments->node_count = read_int (ptr + 1, *ptr); comp->segments->node_count = read_int (ptr + 1, *ptr);
comp->segments->node_alloc = comp->segments->node_count; comp->segments->node_alloc = comp->segments->node_count;
comp->segments->nodes = grub_calloc (comp->segments->node_alloc, comp->segments->nodes = grub_calloc (comp->segments->node_alloc,
sizeof (*comp->segments->nodes)); sizeof (*comp->segments->nodes));
if (comp->segments->nodes == NULL) if (!lv->segments->nodes)
{ {
free_lv (comp); grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
} }
@ -662,18 +640,25 @@ make_vg (grub_disk_t disk,
if (lv->segments->node_alloc == lv->segments->node_count) if (lv->segments->node_alloc == lv->segments->node_count)
{ {
void *t; void *t;
grub_size_t sz;
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
{ {
free_lv (comp); grub_free (comp->segments->nodes);
grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
t = grub_realloc (lv->segments->nodes, sz); t = grub_realloc (lv->segments->nodes, sz);
if (!t) if (!t)
{ {
free_lv (comp); grub_free (comp->segments->nodes);
grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2; goto fail2;
} }
lv->segments->nodes = t; lv->segments->nodes = t;
@ -813,10 +798,7 @@ make_vg (grub_disk_t disk,
comp->segments[comp->segment_count].nodes comp->segments[comp->segment_count].nodes
= grub_malloc (sizeof (*comp->segments[comp->segment_count].nodes)); = grub_malloc (sizeof (*comp->segments[comp->segment_count].nodes));
if (!comp->segments[comp->segment_count].nodes) if (!comp->segments[comp->segment_count].nodes)
{ goto fail2;
grub_free (comp->segments);
goto fail2;
}
comp->segments[comp->segment_count].nodes[0] = part; comp->segments[comp->segment_count].nodes[0] = part;
comp->segment_count++; comp->segment_count++;
} }
@ -831,19 +813,25 @@ make_vg (grub_disk_t disk,
struct grub_diskfilter_pv *pv, *next_pv; struct grub_diskfilter_pv *pv, *next_pv;
for (lv = vg->lvs; lv; lv = next_lv) for (lv = vg->lvs; lv; lv = next_lv)
{ {
next_lv = lv->next; unsigned i;
free_lv (lv); for (i = 0; i < lv->segment_count; i++)
grub_free (lv->segments[i].nodes);
next_lv = lv->next;
grub_free (lv->segments);
grub_free (lv->internal_id);
grub_free (lv->name);
grub_free (lv->fullname);
grub_free (lv);
} }
for (pv = vg->pvs; pv; pv = next_pv) for (pv = vg->pvs; pv; pv = next_pv)
{ {
next_pv = pv->next; next_pv = pv->next;
free_pv (pv); grub_free (pv->id.uuid);
grub_free (pv);
} }
} }
fail1:
grub_free (vg->uuid); grub_free (vg->uuid);
grub_free (vg->name);
grub_free (vg); grub_free (vg);
return NULL; return NULL;
} }

View file

@ -24,7 +24,6 @@
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -34,7 +33,6 @@ struct grub_loopback
grub_file_t file; grub_file_t file;
struct grub_loopback *next; struct grub_loopback *next;
unsigned long id; unsigned long id;
grub_uint64_t refcnt;
}; };
static struct grub_loopback *loopback_list; static struct grub_loopback *loopback_list;
@ -66,8 +64,6 @@ delete_loopback (const char *name)
if (! dev) if (! dev)
return grub_error (GRUB_ERR_BAD_DEVICE, "device not found"); return grub_error (GRUB_ERR_BAD_DEVICE, "device not found");
if (dev->refcnt > 0)
return grub_error (GRUB_ERR_STILL_REFERENCED, "device still referenced");
/* Remove the device from the list. */ /* Remove the device from the list. */
*prev = dev->next; *prev = dev->next;
@ -124,7 +120,6 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
newdev->file = file; newdev->file = file;
newdev->id = last_id++; newdev->id = last_id++;
newdev->refcnt = 0;
/* Add the new entry to the list. */ /* Add the new entry to the list. */
newdev->next = loopback_list; newdev->next = loopback_list;
@ -166,9 +161,6 @@ grub_loopback_open (const char *name, grub_disk_t disk)
if (! dev) if (! dev)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
if (grub_add (dev->refcnt, 1, &dev->refcnt))
grub_fatal ("Reference count overflow");
/* Use the filesize for the disk size, round up to a complete sector. */ /* Use the filesize for the disk size, round up to a complete sector. */
if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN) if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN)
disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1) disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1)
@ -186,15 +178,6 @@ grub_loopback_open (const char *name, grub_disk_t disk)
return 0; return 0;
} }
static void
grub_loopback_close (grub_disk_t disk)
{
struct grub_loopback *dev = disk->data;
if (grub_sub (dev->refcnt, 1, &dev->refcnt))
grub_fatal ("Reference count underflow");
}
static grub_err_t static grub_err_t
grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf) grub_size_t size, char *buf)
@ -237,7 +220,6 @@ static struct grub_disk_dev grub_loopback_dev =
.id = GRUB_DISK_DEVICE_LOOPBACK_ID, .id = GRUB_DISK_DEVICE_LOOPBACK_ID,
.disk_iterate = grub_loopback_iterate, .disk_iterate = grub_loopback_iterate,
.disk_open = grub_loopback_open, .disk_open = grub_loopback_open,
.disk_close = grub_loopback_close,
.disk_read = grub_loopback_read, .disk_read = grub_loopback_read,
.disk_write = grub_loopback_write, .disk_write = grub_loopback_write,
.next = 0 .next = 0

View file

@ -26,7 +26,6 @@
#include <grub/crypto.h> #include <grub/crypto.h>
#include <grub/partition.h> #include <grub/partition.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/safemath.h>
#include <base64.h> #include <base64.h>
#include <json.h> #include <json.h>
@ -570,7 +569,6 @@ luks2_recover_key (grub_disk_t source,
gcry_err_code_t gcry_ret; gcry_err_code_t gcry_ret;
grub_json_t *json = NULL, keyslots; grub_json_t *json = NULL, keyslots;
grub_err_t ret; grub_err_t ret;
grub_size_t sz;
if (cargs->key_data == NULL || cargs->key_len == 0) if (cargs->key_data == NULL || cargs->key_len == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data");
@ -579,12 +577,7 @@ luks2_recover_key (grub_disk_t source,
if (ret) if (ret)
return ret; return ret;
grub_puts_ (N_("Attempting to decrypt master key...")); json_header = grub_zalloc (grub_be_to_cpu64 (header.hdr_size) - sizeof (header));
if (grub_sub (grub_be_to_cpu64 (header.hdr_size), sizeof (header), &sz))
return grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while calculating json header size");
json_header = grub_zalloc (sz);
if (!json_header) if (!json_header)
return GRUB_ERR_OUT_OF_MEMORY; return GRUB_ERR_OUT_OF_MEMORY;

View file

@ -34,11 +34,12 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
struct ignored_feature_lv struct cache_lv
{ {
struct grub_diskfilter_lv *lv; struct grub_diskfilter_lv *lv;
char *cache_pool;
char *origin; char *origin;
struct ignored_feature_lv *next; struct cache_lv *next;
}; };
@ -104,29 +105,30 @@ grub_lvm_check_flag (const char *p, const char *str, const char *flag)
} }
static void static void
grub_lvm_free_ignored_feature_lvs (struct ignored_feature_lv *ignored_feature_lvs) grub_lvm_free_cache_lvs (struct cache_lv *cache_lvs)
{ {
struct ignored_feature_lv *ignored_feature; struct cache_lv *cache;
while ((ignored_feature = ignored_feature_lvs)) while ((cache = cache_lvs))
{ {
ignored_feature_lvs = ignored_feature_lvs->next; cache_lvs = cache_lvs->next;
if (ignored_feature->lv) if (cache->lv)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < ignored_feature->lv->segment_count; ++i) for (i = 0; i < cache->lv->segment_count; ++i)
if (ignored_feature->lv->segments) if (cache->lv->segments)
grub_free (ignored_feature->lv->segments[i].nodes); grub_free (cache->lv->segments[i].nodes);
grub_free (ignored_feature->lv->segments); grub_free (cache->lv->segments);
grub_free (ignored_feature->lv->fullname); grub_free (cache->lv->fullname);
grub_free (ignored_feature->lv->idname); grub_free (cache->lv->idname);
grub_free (ignored_feature->lv->name); grub_free (cache->lv->name);
} }
grub_free (ignored_feature->lv); grub_free (cache->lv);
grub_free (ignored_feature->origin); grub_free (cache->origin);
grub_free (ignored_feature); grub_free (cache->cache_pool);
grub_free (cache);
} }
} }
@ -288,7 +290,7 @@ grub_lvm_detect (grub_disk_t disk,
p = q = (char *)ptr; p = q = (char *)ptr;
if (grub_add (ptr, (grub_size_t) grub_le_to_cpu64 (rlocn->size), &ptr)) if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
goto error_parsing_metadata; goto error_parsing_metadata;
mda_end = (char *)ptr; mda_end = (char *)ptr;
@ -323,7 +325,7 @@ grub_lvm_detect (grub_disk_t disk,
if (! vg) if (! vg)
{ {
struct ignored_feature_lv *ignored_feature_lvs = NULL; struct cache_lv *cache_lvs = NULL;
/* First time we see this volume group. We've to create the /* First time we see this volume group. We've to create the
whole volume group structure. */ whole volume group structure. */
@ -368,8 +370,6 @@ grub_lvm_detect (grub_disk_t disk,
break; break;
pv = grub_zalloc (sizeof (*pv)); pv = grub_zalloc (sizeof (*pv));
if (pv == NULL)
goto fail4;
q = p; q = p;
while (*q != ' ' && q < mda_end) while (*q != ' ' && q < mda_end)
q++; q++;
@ -379,8 +379,6 @@ grub_lvm_detect (grub_disk_t disk,
s = q - p; s = q - p;
pv->name = grub_malloc (s + 1); pv->name = grub_malloc (s + 1);
if (pv->name == NULL)
goto pvs_fail_noname;
grub_memcpy (pv->name, p, s); grub_memcpy (pv->name, p, s);
pv->name[s] = '\0'; pv->name[s] = '\0';
@ -453,8 +451,6 @@ grub_lvm_detect (grub_disk_t disk,
break; break;
lv = grub_zalloc (sizeof (*lv)); lv = grub_zalloc (sizeof (*lv));
if (lv == NULL)
goto fail4;
q = p; q = p;
while (*q != ' ' && q < mda_end) while (*q != ' ' && q < mda_end)
@ -549,8 +545,6 @@ grub_lvm_detect (grub_disk_t disk,
goto lvs_fail; goto lvs_fail;
} }
lv->segments = grub_calloc (lv->segment_count, sizeof (*seg)); lv->segments = grub_calloc (lv->segment_count, sizeof (*seg));
if (lv->segments == NULL)
goto lvs_fail;
seg = lv->segments; seg = lv->segments;
for (i = 0; i < lv->segment_count; i++) for (i = 0; i < lv->segment_count; i++)
@ -618,8 +612,6 @@ grub_lvm_detect (grub_disk_t disk,
seg->nodes = grub_calloc (seg->node_count, seg->nodes = grub_calloc (seg->node_count,
sizeof (*stripe)); sizeof (*stripe));
if (seg->nodes == NULL)
goto lvs_segment_fail;
stripe = seg->nodes; stripe = seg->nodes;
p = grub_strstr (p, "stripes = ["); p = grub_strstr (p, "stripes = [");
@ -679,9 +671,8 @@ grub_lvm_detect (grub_disk_t disk,
goto lvs_segment_fail; goto lvs_segment_fail;
} }
seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0])); seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
if (seg->nodes == NULL) * seg->node_count);
goto lvs_segment_fail;
p = grub_strstr (p, "mirrors = ["); p = grub_strstr (p, "mirrors = [");
if (p == NULL) if (p == NULL)
@ -769,9 +760,8 @@ grub_lvm_detect (grub_disk_t disk,
} }
} }
seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0])); seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
if (seg->nodes == NULL) * seg->node_count);
goto lvs_segment_fail;
p = grub_strstr (p, "raids = ["); p = grub_strstr (p, "raids = [");
if (p == NULL) if (p == NULL)
@ -817,98 +807,108 @@ grub_lvm_detect (grub_disk_t disk,
seg->nodes[seg->node_count - 1].name = tmp; seg->nodes[seg->node_count - 1].name = tmp;
} }
} }
/* else if (grub_memcmp (p, "cache\"",
* Cache and integrity LVs have extra parts that sizeof ("cache\"") - 1) == 0)
* we can ignore for our read-only access.
*/
else if (grub_strncmp (p, "cache\"", sizeof ("cache\"") - 1) == 0 ||
grub_strncmp (p, "cache+CACHE_USES_CACHEVOL\"", sizeof ("cache+CACHE_USES_CACHEVOL\"") - 1) == 0 ||
grub_strncmp (p, "integrity\"", sizeof ("integrity\"") - 1) == 0)
{ {
struct ignored_feature_lv *ignored_feature = NULL; struct cache_lv *cache = NULL;
char *p2, *p3; char *p2, *p3;
grub_size_t sz; grub_size_t sz;
#ifdef GRUB_UTIL
p2 = grub_strchr (p, '"');
if (p2)
*p2 = '\0';
grub_util_info ("Ignoring extra metadata type '%s' for %s", p, lv->name);
if (p2)
*p2 ='"';
#endif
ignored_feature = grub_zalloc (sizeof (*ignored_feature)); cache = grub_zalloc (sizeof (*cache));
if (!ignored_feature) if (!cache)
goto ignored_feature_lv_fail; goto cache_lv_fail;
ignored_feature->lv = grub_zalloc (sizeof (*ignored_feature->lv)); cache->lv = grub_zalloc (sizeof (*cache->lv));
if (!ignored_feature->lv) if (!cache->lv)
goto ignored_feature_lv_fail; goto cache_lv_fail;
grub_memcpy (ignored_feature->lv, lv, sizeof (*ignored_feature->lv)); grub_memcpy (cache->lv, lv, sizeof (*cache->lv));
if (lv->fullname) if (lv->fullname)
{ {
ignored_feature->lv->fullname = grub_strdup (lv->fullname); cache->lv->fullname = grub_strdup (lv->fullname);
if (!ignored_feature->lv->fullname) if (!cache->lv->fullname)
goto ignored_feature_lv_fail; goto cache_lv_fail;
} }
if (lv->idname) if (lv->idname)
{ {
ignored_feature->lv->idname = grub_strdup (lv->idname); cache->lv->idname = grub_strdup (lv->idname);
if (!ignored_feature->lv->idname) if (!cache->lv->idname)
goto ignored_feature_lv_fail; goto cache_lv_fail;
} }
if (lv->name) if (lv->name)
{ {
ignored_feature->lv->name = grub_strdup (lv->name); cache->lv->name = grub_strdup (lv->name);
if (!ignored_feature->lv->name) if (!cache->lv->name)
goto ignored_feature_lv_fail; goto cache_lv_fail;
} }
skip_lv = 1; skip_lv = 1;
p2 = grub_strstr (p, "cache_pool = \"");
p2 = grub_strstr (p, "origin = \"");
if (!p2) if (!p2)
goto ignored_feature_lv_fail; goto cache_lv_fail;
p2 = grub_strchr (p2, '"'); p2 = grub_strchr (p2, '"');
if (!p2) if (!p2)
goto ignored_feature_lv_fail; goto cache_lv_fail;
p3 = ++p2; p3 = ++p2;
if (p3 == mda_end) if (p3 == mda_end)
goto ignored_feature_lv_fail; goto cache_lv_fail;
p3 = grub_strchr (p3, '"'); p3 = grub_strchr (p3, '"');
if (!p3) if (!p3)
goto ignored_feature_lv_fail; goto cache_lv_fail;
sz = p3 - p2; sz = p3 - p2;
ignored_feature->origin = grub_malloc (sz + 1); cache->cache_pool = grub_malloc (sz + 1);
if (!ignored_feature->origin) if (!cache->cache_pool)
goto ignored_feature_lv_fail; goto cache_lv_fail;
grub_memcpy (ignored_feature->origin, p2, sz); grub_memcpy (cache->cache_pool, p2, sz);
ignored_feature->origin[sz] = '\0'; cache->cache_pool[sz] = '\0';
ignored_feature->next = ignored_feature_lvs; p2 = grub_strstr (p, "origin = \"");
ignored_feature_lvs = ignored_feature; if (!p2)
goto cache_lv_fail;
p2 = grub_strchr (p2, '"');
if (!p2)
goto cache_lv_fail;
p3 = ++p2;
if (p3 == mda_end)
goto cache_lv_fail;
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; break;
ignored_feature_lv_fail: cache_lv_fail:
if (ignored_feature) if (cache)
{ {
grub_free (ignored_feature->origin); grub_free (cache->origin);
if (ignored_feature->lv) grub_free (cache->cache_pool);
if (cache->lv)
{ {
grub_free (ignored_feature->lv->fullname); grub_free (cache->lv->fullname);
grub_free (ignored_feature->lv->idname); grub_free (cache->lv->idname);
grub_free (ignored_feature->lv->name); grub_free (cache->lv->name);
} }
grub_free (ignored_feature->lv); grub_free (cache->lv);
grub_free (ignored_feature); grub_free (cache);
} }
grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs); grub_lvm_free_cache_lvs (cache_lvs);
goto fail4; goto fail4;
} }
else else
@ -917,7 +917,7 @@ grub_lvm_detect (grub_disk_t disk,
char *p2; char *p2;
p2 = grub_strchr (p, '"'); p2 = grub_strchr (p, '"');
if (p2) if (p2)
*p2 = '\0'; *p2 = 0;
grub_util_info ("unknown LVM type %s", p); grub_util_info ("unknown LVM type %s", p);
if (p2) if (p2)
*p2 ='"'; *p2 ='"';
@ -961,68 +961,10 @@ grub_lvm_detect (grub_disk_t disk,
} }
} }
/* Match lvs. */
{
struct ignored_feature_lv *ignored_feature;
for (ignored_feature = ignored_feature_lvs; ignored_feature; ignored_feature = ignored_feature->next)
{
struct grub_diskfilter_lv *lv;
for (lv = vg->lvs; lv; lv = lv->next)
if (grub_strcmp (lv->name, ignored_feature->origin) == 0)
break;
if (lv)
{
ignored_feature->lv->segments = grub_calloc (lv->segment_count, sizeof (*lv->segments));
if (!ignored_feature->lv->segments)
{
grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs);
goto fail4;
}
grub_memcpy (ignored_feature->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;
ignored_feature->lv->segments[i].nodes = grub_calloc (node_count, sizeof (*nodes));
if (!ignored_feature->lv->segments[i].nodes)
{
for (j = 0; j < i; ++j)
grub_free (ignored_feature->lv->segments[j].nodes);
grub_free (ignored_feature->lv->segments);
ignored_feature->lv->segments = NULL;
grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs);
goto fail4;
}
grub_memcpy (ignored_feature->lv->segments[i].nodes, nodes, node_count * sizeof (*nodes));
}
if (ignored_feature->lv->segments)
{
ignored_feature->lv->segment_count = lv->segment_count;
ignored_feature->lv->vg = vg;
ignored_feature->lv->next = vg->lvs;
vg->lvs = ignored_feature->lv;
ignored_feature->lv = NULL;
}
}
else
{
#ifdef GRUB_UTIL
grub_util_info ("Couldn't find LVM part of ignored feature on %s", ignored_feature->origin);
#endif
}
}
}
/* Match LVs. Must be done after cache and integrity are found. */
{ {
struct grub_diskfilter_lv *lv1; struct grub_diskfilter_lv *lv1;
struct grub_diskfilter_lv *lv2; struct grub_diskfilter_lv *lv2;
for (lv1 = vg->lvs; lv1; lv1 = lv1->next) for (lv1 = vg->lvs; lv1; lv1 = lv1->next)
for (i = 0; i < lv1->segment_count; i++) for (i = 0; i < lv1->segment_count; i++)
for (j = 0; j < lv1->segments[i].node_count; j++) for (j = 0; j < lv1->segments[i].node_count; j++)
@ -1047,9 +989,60 @@ grub_lvm_detect (grub_disk_t disk,
lv1->segments[i].nodes[j].lv = lv2; lv1->segments[i].nodes[j].lv = lv2;
} }
} }
} }
grub_lvm_free_ignored_feature_lvs (ignored_feature_lvs); {
struct cache_lv *cache;
for (cache = cache_lvs; cache; cache = cache->next)
{
struct grub_diskfilter_lv *lv;
for (lv = vg->lvs; lv; lv = lv->next)
if (grub_strcmp (lv->name, cache->origin) == 0)
break;
if (lv)
{
cache->lv->segments = grub_calloc (lv->segment_count, sizeof (*lv->segments));
if (!cache->lv->segments)
{
grub_lvm_free_cache_lvs (cache_lvs);
goto fail4;
}
grub_memcpy (cache->lv->segments, lv->segments, lv->segment_count * sizeof (*lv->segments));
for (i = 0; i < lv->segment_count; ++i)
{
struct grub_diskfilter_node *nodes = lv->segments[i].nodes;
grub_size_t node_count = lv->segments[i].node_count;
cache->lv->segments[i].nodes = grub_calloc (node_count, sizeof (*nodes));
if (!cache->lv->segments[i].nodes)
{
for (j = 0; j < i; ++j)
grub_free (cache->lv->segments[j].nodes);
grub_free (cache->lv->segments);
cache->lv->segments = NULL;
grub_lvm_free_cache_lvs (cache_lvs);
goto fail4;
}
grub_memcpy (cache->lv->segments[i].nodes, nodes, node_count * sizeof (*nodes));
}
if (cache->lv->segments)
{
cache->lv->segment_count = lv->segment_count;
cache->lv->vg = vg;
cache->lv->next = vg->lvs;
vg->lvs = cache->lv;
cache->lv = NULL;
}
}
}
}
grub_lvm_free_cache_lvs (cache_lvs);
if (grub_diskfilter_vg_register (vg)) if (grub_diskfilter_vg_register (vg))
goto fail4; goto fail4;
} }

View file

@ -23,7 +23,6 @@
#include <grub/err.h> #include <grub/err.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/diskfilter.h> #include <grub/diskfilter.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -104,9 +103,6 @@ struct grub_raid_super_1x
#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */ #define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */
#define GRUB_MD_SECTOR_SHIFT 9 /* Follow Linux kernel v6.8. */
#define GRUB_MD_SECTOR_SIZE (1 << GRUB_MD_SECTOR_SHIFT)
static struct grub_diskfilter_vg * static struct grub_diskfilter_vg *
grub_mdraid_detect (grub_disk_t disk, grub_mdraid_detect (grub_disk_t disk,
struct grub_diskfilter_pv_id *id, struct grub_diskfilter_pv_id *id,
@ -133,7 +129,6 @@ grub_mdraid_detect (grub_disk_t disk,
grub_uint32_t level; grub_uint32_t level;
struct grub_diskfilter_vg *array; struct grub_diskfilter_vg *array;
char *uuid; char *uuid;
grub_uint64_t sb_sz, data_end, sb_end;
if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0) if (size == GRUB_DISK_SIZE_UNKNOWN && minor_version == 0)
continue; continue;
@ -159,79 +154,6 @@ grub_mdraid_detect (grub_disk_t disk,
|| grub_le_to_cpu64 (sb.super_offset) != sector) || grub_le_to_cpu64 (sb.super_offset) != sector)
continue; continue;
/*
* The first check follows the Linux kernel's data_size
* validation from v6.8-rc5.
*/
if (grub_le_to_cpu64 (sb.data_size) < 10 ||
grub_le_to_cpu64 (sb.raid_disks) > GRUB_MDRAID_MAX_DISKS)
{
grub_dprintf ("mdraid1x", "Corrupted superblock\n");
return NULL;
}
/*
* Total size of superblock: 256 bytes plus 2 bytes per device
* in the array.
*/
sb_sz = sizeof (struct grub_raid_super_1x) + grub_le_to_cpu64 (sb.raid_disks) * 2;
if (grub_add (grub_le_to_cpu64 (sb.super_offset),
(ALIGN_UP(sb_sz, GRUB_MD_SECTOR_SIZE) >> GRUB_MD_SECTOR_SHIFT), &sb_end))
{
grub_dprintf ("mdraid1x", "Invalid superblock end.\n");
return NULL;
}
if (grub_add (grub_le_to_cpu64 (sb.data_offset),
grub_le_to_cpu64 (sb.data_size), &data_end))
{
grub_dprintf ("mdraid1x", "Invalid data end.\n");
return NULL;
}
/* In minor versions 1 and 2, superblock is positioned before data. */
if (minor_version)
{
if (grub_le_to_cpu64 (sb.data_offset) < sb_end)
{
grub_dprintf ("mdraid1x",
"The superblock either overlaps with the data "
"or is behind it.\n");
return NULL;
}
if (data_end > size)
{
grub_dprintf ("mdraid1x",
"The data region ends at %" PRIuGRUB_UINT64_T ", "
"past the end of the disk (%" PRIuGRUB_UINT64_T ")\n",
data_end, size);
return NULL;
}
}
else
{
/* In minor version 0, superblock is at the end of the device. */
if (grub_le_to_cpu64 (sb.super_offset) < data_end)
{
grub_dprintf ("mdraid1x",
"The data either overlaps with the superblock "
"or is behind it.\n");
return NULL;
}
if (sb_end > size)
{
grub_dprintf ("mdraid1x",
"The superblock region ends at "
"%" PRIuGRUB_UINT64_T ", past the end of "
"the disk (%" PRIuGRUB_UINT64_T ")\n",
sb_end, size);
return NULL;
}
}
if (sb.major_version != grub_cpu_to_le32_compile_time (1)) if (sb.major_version != grub_cpu_to_le32_compile_time (1))
/* Unsupported version. */ /* Unsupported version. */
return NULL; return NULL;

View file

@ -23,7 +23,6 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -97,14 +96,8 @@ GRUB_MOD_INIT(memdisk)
grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
if (grub_sub (header->size, sizeof (struct grub_module_header), &memdisk_size)) memdisk_size = header->size - sizeof (struct grub_module_header);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while obtaining memdisk size");
return;
}
memdisk_addr = grub_malloc (memdisk_size); memdisk_addr = grub_malloc (memdisk_size);
if (memdisk_addr == NULL)
return;
grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);

View file

@ -24,7 +24,6 @@
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/partition.h> #include <grub/partition.h>
#include <grub/file.h> #include <grub/file.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -127,7 +126,7 @@ plainmount_configure_password (grub_cryptodisk_t dev, const char *hash,
grub_uint8_t *derived_hash, *dh; grub_uint8_t *derived_hash, *dh;
char *p; char *p;
unsigned int round, i, len, size; unsigned int round, i, len, size;
grub_size_t alloc_size, sz; grub_size_t alloc_size;
grub_err_t err = GRUB_ERR_NONE; grub_err_t err = GRUB_ERR_NONE;
/* Support none (plain) hash */ /* Support none (plain) hash */
@ -146,11 +145,7 @@ plainmount_configure_password (grub_cryptodisk_t dev, const char *hash,
* Allocate buffer for the password and for an added prefix character * Allocate buffer for the password and for an added prefix character
* for each hash round ('alloc_size' may not be a multiple of 'len'). * for each hash round ('alloc_size' may not be a multiple of 'len').
*/ */
if (grub_add (alloc_size, (alloc_size / len), &sz) || p = grub_zalloc (alloc_size + (alloc_size / len) + 1);
grub_add (sz, 1, &sz))
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while allocating size of password buffer"));
p = grub_zalloc (sz);
derived_hash = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN * 2); derived_hash = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN * 2);
if (p == NULL || derived_hash == NULL) if (p == NULL || derived_hash == NULL)
{ {

1
grub-core/extra_deps.lst Normal file
View file

@ -0,0 +1 @@
depends bli part_gpt

View file

@ -26,7 +26,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -704,16 +703,11 @@ static struct grub_fs grub_affs_fs =
GRUB_MOD_INIT(affs) GRUB_MOD_INIT(affs)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_affs_fs);
{
grub_affs_fs.mod = mod;
grub_fs_register (&grub_affs_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI(affs) GRUB_MOD_FINI(affs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_affs_fs);
grub_fs_unregister (&grub_affs_fs);
} }

View file

@ -21,7 +21,6 @@
#include <grub/fs.h> #include <grub/fs.h>
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -69,7 +68,6 @@ handle_symlink (struct grub_archelp_data *data,
char *rest; char *rest;
char *linktarget; char *linktarget;
grub_size_t linktarget_len; grub_size_t linktarget_len;
grub_size_t sz;
*restart = 0; *restart = 0;
@ -100,12 +98,7 @@ handle_symlink (struct grub_archelp_data *data,
if (linktarget[0] == '\0') if (linktarget[0] == '\0')
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
linktarget_len = grub_strlen (linktarget); linktarget_len = grub_strlen (linktarget);
target = grub_malloc (linktarget_len + grub_strlen (*name) + 2);
if (grub_add (linktarget_len, grub_strlen (*name), &sz) ||
grub_add (sz, 2, &sz))
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("link target length overflow"));
target = grub_malloc (sz);
if (!target) if (!target)
return grub_errno; return grub_errno;

View file

@ -30,7 +30,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -809,7 +808,7 @@ find_file (const char *path, grub_disk_t disk,
.disk = disk, .disk = disk,
.sb = sb, .sb = sb,
}; };
struct grub_fshelp_node *found = NULL; struct grub_fshelp_node *found;
err = read_extent (disk, sb, &sb->root_dir, 0, 0, &root.ino, err = read_extent (disk, sb, &sb->root_dir, 0, 0, &root.ino,
sizeof (root.ino)); sizeof (root.ino));
@ -1107,11 +1106,7 @@ GRUB_MOD_INIT (bfs)
{ {
COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE ==
sizeof (struct grub_bfs_extent)); sizeof (struct grub_bfs_extent));
if (!grub_is_lockdown ()) grub_fs_register (&grub_bfs_fs);
{
grub_bfs_fs.mod = mod;
grub_fs_register (&grub_bfs_fs);
}
} }
#ifdef MODE_AFS #ifdef MODE_AFS
@ -1120,6 +1115,5 @@ GRUB_MOD_FINI (afs)
GRUB_MOD_FINI (bfs) GRUB_MOD_FINI (bfs)
#endif #endif
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_bfs_fs);
grub_fs_unregister (&grub_bfs_fs);
} }

View file

@ -1276,8 +1276,8 @@ grub_btrfs_mount (grub_device_t dev)
} }
data->n_devices_allocated = 16; data->n_devices_allocated = 16;
data->devices_attached = grub_calloc (data->n_devices_allocated, data->devices_attached = grub_malloc (sizeof (data->devices_attached[0])
sizeof (data->devices_attached[0])); * data->n_devices_allocated);
if (!data->devices_attached) if (!data->devices_attached)
{ {
grub_free (data); grub_free (data);
@ -1538,10 +1538,7 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
err = lower_bound (data, &key_in, &key_out, tree, err = lower_bound (data, &key_in, &key_out, tree,
&elemaddr, &elemsize, &desc, 0); &elemaddr, &elemsize, &desc, 0);
if (err) if (err)
{ return -1;
grub_free (desc.data);
return -1;
}
if (key_out.object_id != ino if (key_out.object_id != ino
|| key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM)
{ {
@ -1804,7 +1801,6 @@ find_path (struct grub_btrfs_data *data,
char *path_alloc = NULL; char *path_alloc = NULL;
char *origpath = NULL; char *origpath = NULL;
unsigned symlinks_max = 32; unsigned symlinks_max = 32;
grub_size_t sz;
err = get_root (data, key, tree, type); err = get_root (data, key, tree, type);
if (err) if (err)
@ -1895,15 +1891,9 @@ find_path (struct grub_btrfs_data *data,
struct grub_btrfs_dir_item *cdirel; struct grub_btrfs_dir_item *cdirel;
if (elemsize > allocated) if (elemsize > allocated)
{ {
if (grub_mul (2, elemsize, &allocated) || allocated = 2 * elemsize;
grub_add (allocated, 1, &sz))
{
grub_free (path_alloc);
grub_free (origpath);
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory item size overflow"));
}
grub_free (direl); grub_free (direl);
direl = grub_malloc (sz); direl = grub_malloc (allocated + 1);
if (!direl) if (!direl)
{ {
grub_free (path_alloc); grub_free (path_alloc);
@ -1965,16 +1955,8 @@ find_path (struct grub_btrfs_data *data,
grub_free (origpath); grub_free (origpath);
return err; return err;
} }
tmp = grub_malloc (grub_le_to_cpu64 (inode.size)
if (grub_add (grub_le_to_cpu64 (inode.size), grub_strlen (path), &sz) || + grub_strlen (path) + 1);
grub_add (sz, 1, &sz))
{
grub_free (direl);
grub_free (path_alloc);
grub_free (origpath);
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow"));
}
tmp = grub_malloc (sz);
if (!tmp) if (!tmp)
{ {
grub_free (direl); grub_free (direl);
@ -2096,7 +2078,6 @@ grub_btrfs_dir (grub_device_t device, const char *path,
grub_uint64_t tree; grub_uint64_t tree;
grub_uint8_t type; grub_uint8_t type;
grub_size_t est_size = 0; grub_size_t est_size = 0;
grub_size_t sz;
if (!data) if (!data)
return grub_errno; return grub_errno;
@ -2118,7 +2099,6 @@ grub_btrfs_dir (grub_device_t device, const char *path,
if (err) if (err)
{ {
grub_btrfs_unmount (data); grub_btrfs_unmount (data);
grub_free (desc.data);
return err; return err;
} }
if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM
@ -2139,15 +2119,9 @@ grub_btrfs_dir (grub_device_t device, const char *path,
} }
if (elemsize > allocated) if (elemsize > allocated)
{ {
if (grub_mul (2, elemsize, &allocated) || allocated = 2 * elemsize;
grub_add (allocated, 1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory element size overflow"));
r = -grub_errno;
break;
}
grub_free (direl); grub_free (direl);
direl = grub_malloc (sz); direl = grub_malloc (allocated + 1);
if (!direl) if (!direl)
{ {
r = -grub_errno; r = -grub_errno;
@ -2439,7 +2413,6 @@ static struct grub_fs grub_btrfs_fs = {
GRUB_MOD_INIT (btrfs) GRUB_MOD_INIT (btrfs)
{ {
grub_btrfs_fs.mod = mod;
grub_fs_register (&grub_btrfs_fs); grub_fs_register (&grub_btrfs_fs);
} }

View file

@ -26,7 +26,6 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/cbfs_core.h> #include <grub/cbfs_core.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -391,17 +390,12 @@ GRUB_MOD_INIT (cbfs)
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
init_cbfsdisk (); init_cbfsdisk ();
#endif #endif
if (!grub_is_lockdown ()) grub_fs_register (&grub_cbfs_fs);
{
grub_cbfs_fs.mod = mod;
grub_fs_register (&grub_cbfs_fs);
}
} }
GRUB_MOD_FINI (cbfs) GRUB_MOD_FINI (cbfs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_cbfs_fs);
grub_fs_unregister (&grub_cbfs_fs);
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
fini_cbfsdisk (); fini_cbfsdisk ();
#endif #endif

View file

@ -52,7 +52,6 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
GRUB_MOD_INIT (cpio) GRUB_MOD_INIT (cpio)
{ {
grub_cpio_fs.mod = mod;
grub_fs_register (&grub_cpio_fs); grub_fs_register (&grub_cpio_fs);
} }

View file

@ -52,7 +52,6 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
GRUB_MOD_INIT (cpio_be) GRUB_MOD_INIT (cpio_be)
{ {
grub_cpio_fs.mod = mod;
grub_fs_register (&grub_cpio_fs); grub_fs_register (&grub_cpio_fs);
} }

View file

@ -24,7 +24,6 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/archelp.h> #include <grub/archelp.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -49,7 +48,6 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
struct head hd; struct head hd;
grub_size_t namesize; grub_size_t namesize;
grub_uint32_t modeval; grub_uint32_t modeval;
grub_size_t sz;
data->hofs = data->next_hofs; data->hofs = data->next_hofs;
@ -62,21 +60,11 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
#endif #endif
) )
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize));
if (grub_cast (read_number (hd.filesize, ARRAY_SIZE (hd.filesize)), &data->size))
return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow"));
if (mtime) if (mtime)
{ *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime));
if (grub_cast (read_number (hd.mtime, ARRAY_SIZE (hd.mtime)), mtime)) modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow")); namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));
}
if (grub_cast (read_number (hd.mode, ARRAY_SIZE (hd.mode)), &modeval))
return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow"));
if (grub_cast (read_number (hd.namesize, ARRAY_SIZE (hd.namesize)), &namesize))
return grub_error (GRUB_ERR_BAD_FS, N_("namesize overflow"));
/* Don't allow negative numbers. */ /* Don't allow negative numbers. */
if (namesize >= 0x80000000) if (namesize >= 0x80000000)
@ -88,10 +76,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
*mode = modeval; *mode = modeval;
if (grub_add (namesize, 1, &sz)) *name = grub_malloc (namesize + 1);
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("file name size overflow"));
*name = grub_malloc (sz);
if (*name == NULL) if (*name == NULL)
return grub_errno; return grub_errno;
@ -125,17 +110,10 @@ grub_cpio_get_link_target (struct grub_archelp_data *data)
{ {
char *ret; char *ret;
grub_err_t err; grub_err_t err;
grub_size_t sz;
if (data->size == 0) if (data->size == 0)
return grub_strdup (""); return grub_strdup ("");
ret = grub_malloc (data->size + 1);
if (grub_add (data->size, 1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("target data size overflow"));
return NULL;
}
ret = grub_malloc (sz);
if (!ret) if (!ret)
return NULL; return NULL;

File diff suppressed because it is too large Load diff

View file

@ -495,11 +495,6 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
struct grub_ext4_extent *ext; struct grub_ext4_extent *ext;
int i; int i;
grub_disk_addr_t ret; grub_disk_addr_t ret;
grub_uint16_t nent;
/* Maximum number of extent entries in the inode's inline extent area. */
const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */
/* Maximum number of extent entries in the external extent block. */
const grub_uint16_t max_external_ext = EXT2_BLOCK_SIZE (data) / sizeof (*ext) - 1; /* Minus 1 extent header. */
if (grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, if (grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks,
fileblock, &leaf) != GRUB_ERR_NONE) fileblock, &leaf) != GRUB_ERR_NONE)
@ -513,23 +508,7 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
return 0; return 0;
ext = (struct grub_ext4_extent *) (leaf + 1); ext = (struct grub_ext4_extent *) (leaf + 1);
for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++)
nent = grub_le_to_cpu16 (leaf->entries);
/*
* Determine the effective number of extent entries (nent) to process.
* If the extent header (leaf) is stored inline in the inodes block
* area, i.e. at inode->blocks.dir_blocks, then only max_inline_ext
* entries can fit. Otherwise, if the header was read from an external
* extent block use the larger limit, max_external_ext, based on the
* full block size.
*/
if (leaf == (struct grub_ext4_extent_header *) inode->blocks.dir_blocks)
nent = grub_min (nent, max_inline_ext);
else
nent = grub_min (nent, max_external_ext);
for (i = 0; i < nent; i++)
{ {
if (fileblock < grub_le_to_cpu32 (ext[i].block)) if (fileblock < grub_le_to_cpu32 (ext[i].block))
break; break;
@ -1144,7 +1123,6 @@ static struct grub_fs grub_ext2_fs =
GRUB_MOD_INIT(ext2) GRUB_MOD_INIT(ext2)
{ {
grub_ext2_fs.mod = mod;
grub_fs_register (&grub_ext2_fs); grub_fs_register (&grub_ext2_fs);
my_mod = mod; my_mod = mod;
} }

View file

@ -28,7 +28,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -873,9 +872,6 @@ grub_f2fs_mount (grub_disk_t disk)
return data; return data;
fail: fail:
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_FS, "not a F2FS filesystem");
grub_free (data); grub_free (data);
return NULL; return NULL;
@ -959,7 +955,6 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node)
char *symlink; char *symlink;
struct grub_fshelp_node *diro = node; struct grub_fshelp_node *diro = node;
grub_uint64_t filesize; grub_uint64_t filesize;
grub_size_t sz;
if (!diro->inode_read) if (!diro->inode_read)
{ {
@ -970,12 +965,7 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node)
filesize = grub_f2fs_file_size(&diro->inode.i); filesize = grub_f2fs_file_size(&diro->inode.i);
if (grub_add (filesize, 1, &sz)) symlink = grub_malloc (filesize + 1);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
return 0;
}
symlink = grub_malloc (sz);
if (!symlink) if (!symlink)
return 0; return 0;
@ -1004,7 +994,6 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
enum FILE_TYPE ftype; enum FILE_TYPE ftype;
int name_len; int name_len;
int ret; int ret;
int sz;
if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0) if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0)
{ {
@ -1018,12 +1007,7 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
if (name_len >= F2FS_NAME_LEN) if (name_len >= F2FS_NAME_LEN)
return 0; return 0;
if (grub_add (name_len, 1, &sz)) filename = grub_malloc (name_len + 1);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory entry name length overflow"));
return 0;
}
filename = grub_malloc (sz);
if (!filename) if (!filename)
return 0; return 0;
@ -1366,7 +1350,6 @@ static struct grub_fs grub_f2fs_fs = {
GRUB_MOD_INIT (f2fs) GRUB_MOD_INIT (f2fs)
{ {
grub_f2fs_fs.mod = mod;
grub_fs_register (&grub_f2fs_fs); grub_fs_register (&grub_f2fs_fs);
my_mod = mod; my_mod = mod;
} }

View file

@ -1312,7 +1312,6 @@ GRUB_MOD_INIT(fat)
#endif #endif
{ {
COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32); COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32);
grub_fat_fs.mod = mod;
grub_fs_register (&grub_fat_fs); grub_fs_register (&grub_fat_fs);
my_mod = mod; my_mod = mod;
} }

View file

@ -226,10 +226,7 @@ find_file (char *currpath,
return grub_error (GRUB_ERR_SYMLINK_LOOP, return grub_error (GRUB_ERR_SYMLINK_LOOP,
N_("too deep nesting of symlinks")); N_("too deep nesting of symlinks"));
if (read_symlink != NULL) symlink = read_symlink (ctx->currnode->node);
symlink = read_symlink (ctx->currnode->node);
else
return grub_error (GRUB_ERR_BAD_FS, "read_symlink is NULL");
if (!symlink) if (!symlink)
return grub_errno; return grub_errno;

View file

@ -379,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk)
volume name. */ volume name. */
key.parent_dir = grub_cpu_to_be32_compile_time (1); key.parent_dir = grub_cpu_to_be32_compile_time (1);
key.strlen = data->sblock.volname[0]; key.strlen = data->sblock.volname[0];
grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str)); grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
if (grub_hfs_find_node (data, (char *) &key, data->cat_root, if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
0, (char *) &dir, sizeof (dir)) == 0) 0, (char *) &dir, sizeof (dir)) == 0)
@ -1434,7 +1434,6 @@ static struct grub_fs grub_hfs_fs =
GRUB_MOD_INIT(hfs) GRUB_MOD_INIT(hfs)
{ {
grub_hfs_fs.mod = mod;
if (!grub_is_lockdown ()) if (!grub_is_lockdown ())
grub_fs_register (&grub_hfs_fs); grub_fs_register (&grub_hfs_fs);
my_mod = mod; my_mod = mod;

View file

@ -405,7 +405,7 @@ grub_hfsplus_mount (grub_disk_t disk)
fail: fail:
if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
grub_free (data); grub_free (data);
@ -1176,7 +1176,6 @@ static struct grub_fs grub_hfsplus_fs =
GRUB_MOD_INIT(hfsplus) GRUB_MOD_INIT(hfsplus)
{ {
grub_hfsplus_fs.mod = mod;
grub_fs_register (&grub_hfsplus_fs); grub_fs_register (&grub_hfsplus_fs);
my_mod = mod; my_mod = mod;
} }

View file

@ -244,19 +244,14 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node)
return 0; return 0;
} }
node->compress_index_size = grub_le_to_cpu32 (index_size); node->compress_index_size = grub_le_to_cpu32 (index_size);
node->compress_index = grub_calloc (node->compress_index_size, node->compress_index = grub_malloc (node->compress_index_size
sizeof (node->compress_index[0])); * sizeof (node->compress_index[0]));
if (!node->compress_index) if (!node->compress_index)
{ {
node->compressed = 0; node->compressed = 0;
grub_free (attr_node); grub_free (attr_node);
return grub_errno; return grub_errno;
} }
/*
* The node->compress_index_size * sizeof (node->compress_index[0]) is safe here
* due to relevant checks done in grub_calloc() above.
*/
if (grub_hfsplus_read_file (node, 0, 0, if (grub_hfsplus_read_file (node, 0, 0,
0x104 + sizeof (index_size), 0x104 + sizeof (index_size),
node->compress_index_size node->compress_index_size

View file

@ -551,9 +551,6 @@ grub_iso9660_mount (grub_disk_t disk)
return data; return data;
fail: fail:
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
grub_free (data); grub_free (data);
return 0; return 0;
} }
@ -628,19 +625,9 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
filename type is stored. */ filename type is stored. */
/* FIXME: Fix this slightly improper cast. */ /* FIXME: Fix this slightly improper cast. */
if (entry->data[0] & GRUB_ISO9660_RR_DOT) if (entry->data[0] & GRUB_ISO9660_RR_DOT)
{ ctx->filename = (char *) ".";
if (ctx->filename_alloc)
grub_free (ctx->filename);
ctx->filename_alloc = 0;
ctx->filename = (char *) ".";
}
else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
{ ctx->filename = (char *) "..";
if (ctx->filename_alloc)
grub_free (ctx->filename);
ctx->filename_alloc = 0;
ctx->filename = (char *) "..";
}
else if (entry->len >= 5) else if (entry->len >= 5)
{ {
grub_size_t off = 0, csize = 1; grub_size_t off = 0, csize = 1;
@ -1260,7 +1247,6 @@ static struct grub_fs grub_iso9660_fs =
GRUB_MOD_INIT(iso9660) GRUB_MOD_INIT(iso9660)
{ {
grub_iso9660_fs.mod = mod;
grub_fs_register (&grub_iso9660_fs); grub_fs_register (&grub_iso9660_fs);
my_mod = mod; my_mod = mod;
} }

View file

@ -26,7 +26,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -42,13 +41,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define GRUB_JFS_TREE_LEAF 2 #define GRUB_JFS_TREE_LEAF 2
/*
* Define max entries stored in-line in an inode.
* https://jfs.sourceforge.net/project/pub/jfslayout.pdf
*/
#define GRUB_JFS_INODE_INLINE_ENTRIES 8
#define GRUB_JFS_DIR_MAX_SLOTS 128
struct grub_jfs_sblock struct grub_jfs_sblock
{ {
/* The magic for JFS. It should contain the string "JFS1". */ /* The magic for JFS. It should contain the string "JFS1". */
@ -211,9 +203,9 @@ struct grub_jfs_inode
grub_uint8_t freecnt; grub_uint8_t freecnt;
grub_uint8_t freelist; grub_uint8_t freelist;
grub_uint32_t idotdot; grub_uint32_t idotdot;
grub_uint8_t sorted[GRUB_JFS_INODE_INLINE_ENTRIES]; grub_uint8_t sorted[8];
} header; } header;
struct grub_jfs_leaf_dirent dirents[GRUB_JFS_INODE_INLINE_ENTRIES]; struct grub_jfs_leaf_dirent dirents[8];
} GRUB_PACKED dir; } GRUB_PACKED dir;
/* Fast symlink. */ /* Fast symlink. */
struct struct
@ -266,21 +258,7 @@ static grub_dl_t my_mod;
static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino); static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino);
/* static grub_int64_t
* An extent's offset, physical and logical, is represented as a 40-bit value.
* This 40-bit value is split into two parts:
* - offset1: the most signficant 8 bits of the offset,
* - offset2: the least significant 32 bits of the offset.
*
* This function calculates and returns the 64-bit offset of an extent.
*/
static grub_uint64_t
get_ext_offset (grub_uint8_t offset1, grub_uint32_t offset2)
{
return (((grub_uint64_t) offset1 << 32) | grub_le_to_cpu32 (offset2));
}
static grub_uint64_t
getblk (struct grub_jfs_treehead *treehead, getblk (struct grub_jfs_treehead *treehead,
struct grub_jfs_tree_extent *extents, struct grub_jfs_tree_extent *extents,
int max_extents, int max_extents,
@ -289,33 +267,28 @@ getblk (struct grub_jfs_treehead *treehead,
{ {
int found = -1; int found = -1;
int i; int i;
grub_uint64_t ext_offset, ext_blk;
grub_errno = GRUB_ERR_NONE;
for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 && for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 &&
i < max_extents; i++) i < max_extents; i++)
{ {
ext_offset = get_ext_offset (extents[i].offset1, extents[i].offset2);
ext_blk = get_ext_offset (extents[i].extent.blk1, extents[i].extent.blk2);
if (treehead->flags & GRUB_JFS_TREE_LEAF) if (treehead->flags & GRUB_JFS_TREE_LEAF)
{ {
/* Read the leafnode. */ /* Read the leafnode. */
if (ext_offset <= blk if (grub_le_to_cpu32 (extents[i].offset2) <= blk
&& ((grub_le_to_cpu16 (extents[i].extent.length)) && ((grub_le_to_cpu16 (extents[i].extent.length))
+ (extents[i].extent.length2 << 16) + (extents[i].extent.length2 << 16)
+ ext_offset) > blk) + grub_le_to_cpu32 (extents[i].offset2)) > blk)
return (blk - ext_offset + ext_blk); return (blk - grub_le_to_cpu32 (extents[i].offset2)
+ grub_le_to_cpu32 (extents[i].extent.blk2));
} }
else else
if (blk >= ext_offset) if (blk >= grub_le_to_cpu32 (extents[i].offset2))
found = i; found = i;
} }
if (found != -1) if (found != -1)
{ {
grub_uint64_t ret = 0; grub_int64_t ret = -1;
struct struct
{ {
struct grub_jfs_treehead treehead; struct grub_jfs_treehead treehead;
@ -324,12 +297,13 @@ getblk (struct grub_jfs_treehead *treehead,
tree = grub_zalloc (sizeof (*tree)); tree = grub_zalloc (sizeof (*tree));
if (!tree) if (!tree)
return 0; return -1;
if (!grub_disk_read (data->disk, if (!grub_disk_read (data->disk,
(grub_disk_addr_t) ext_blk ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2))
<< (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS), << (grub_le_to_cpu16 (data->sblock.log2_blksz)
0, sizeof (*tree), (char *) tree)) - GRUB_DISK_SECTOR_BITS), 0,
sizeof (*tree), (char *) tree))
{ {
if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) || if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) ||
grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent))) grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent)))
@ -337,20 +311,19 @@ getblk (struct grub_jfs_treehead *treehead,
else else
{ {
grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected"); grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected");
ret = 0; ret = -1;
} }
} }
grub_free (tree); grub_free (tree);
return ret; return ret;
} }
grub_error (GRUB_ERR_READ_ERROR, "jfs: block %" PRIuGRUB_UINT64_T " not found", blk); return -1;
return 0;
} }
/* Get the block number for the block BLK in the node INODE in the /* Get the block number for the block BLK in the node INODE in the
mounted filesystem DATA. */ mounted filesystem DATA. */
static grub_uint64_t static grub_int64_t
grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
grub_uint64_t blk) grub_uint64_t blk)
{ {
@ -381,7 +354,7 @@ grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino,
sizeof (iag_inodes), &iag_inodes)) sizeof (iag_inodes), &iag_inodes))
return grub_errno; return grub_errno;
inoblk = get_ext_offset (iag_inodes[inoext].blk1, iag_inodes[inoext].blk2); inoblk = grub_le_to_cpu32 (iag_inodes[inoext].blk2);
inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS); - GRUB_DISK_SECTOR_BITS);
inoblk += inonum; inoblk += inonum;
@ -480,13 +453,6 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
/* Check if the entire tree is contained within the inode. */ /* Check if the entire tree is contained within the inode. */
if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF) if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
{ {
if (inode->dir.header.count > GRUB_JFS_INODE_INLINE_ENTRIES)
{
grub_free (diro);
grub_error (GRUB_ERR_BAD_FS, N_("invalid JFS inode"));
return 0;
}
diro->leaf = inode->dir.dirents; diro->leaf = inode->dir.dirents;
diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de; diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
diro->sorted = inode->dir.header.sorted; diro->sorted = inode->dir.header.sorted;
@ -502,16 +468,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
return 0; return 0;
} }
if (inode->dir.header.sorted[0] >= GRUB_JFS_DIR_MAX_SLOTS) blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
{
grub_error (GRUB_ERR_BAD_FS, N_("invalid directory slot index"));
grub_free (diro->dirpage);
grub_free (diro);
return 0;
}
blk = get_ext_offset (de[inode->dir.header.sorted[0]].ex.blk1,
de[inode->dir.header.sorted[0]].ex.blk2);
blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS); blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
/* Read in the nodes until we are on the leaf node level. */ /* Read in the nodes until we are on the leaf node level. */
@ -529,7 +486,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent; de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent;
index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32]; index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
blk = (get_ext_offset (de[index].ex.blk1, de[index].ex.blk2) blk = (grub_le_to_cpu32 (de[index].ex.blk2)
<< (grub_le_to_cpu16 (data->sblock.log2_blksz) << (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS)); - GRUB_DISK_SECTOR_BITS));
} while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF)); } while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF));
@ -759,6 +716,7 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path,
grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode); grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode);
grub_jfs_closedir (diro); grub_jfs_closedir (diro);
diro = 0;
if (grub_jfs_read_inode (data, ino, &data->currinode)) if (grub_jfs_read_inode (data, ino, &data->currinode))
break; break;
@ -1005,16 +963,11 @@ static struct grub_fs grub_jfs_fs =
GRUB_MOD_INIT(jfs) GRUB_MOD_INIT(jfs)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_jfs_fs);
{
grub_jfs_fs.mod = mod;
grub_fs_register (&grub_jfs_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI(jfs) GRUB_MOD_FINI(jfs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_jfs_fs);
grub_fs_unregister (&grub_jfs_fs);
} }

View file

@ -25,7 +25,6 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -735,11 +734,7 @@ GRUB_MOD_INIT(minix)
#endif #endif
#endif #endif
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_minix_fs);
{
grub_minix_fs.mod = mod;
grub_fs_register (&grub_minix_fs);
}
my_mod = mod; my_mod = mod;
} }
@ -761,6 +756,5 @@ GRUB_MOD_FINI(minix)
#endif #endif
#endif #endif
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_minix_fs);
grub_fs_unregister (&grub_minix_fs);
} }

View file

@ -64,7 +64,6 @@ read_number (const char *str, grub_size_t size)
GRUB_MOD_INIT (newc) GRUB_MOD_INIT (newc)
{ {
grub_cpio_fs.mod = mod;
grub_fs_register (&grub_cpio_fs); grub_fs_register (&grub_cpio_fs);
} }

View file

@ -34,7 +34,6 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -1232,16 +1231,11 @@ GRUB_MOD_INIT (nilfs2)
grub_nilfs2_dat_entry)); grub_nilfs2_dat_entry));
COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE
== sizeof (struct grub_nilfs2_inode)); == sizeof (struct grub_nilfs2_inode));
if (!grub_is_lockdown ()) grub_fs_register (&grub_nilfs2_fs);
{
grub_nilfs2_fs.mod = mod;
grub_fs_register (&grub_nilfs2_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI (nilfs2) GRUB_MOD_FINI (nilfs2)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_nilfs2_fs);
grub_fs_unregister (&grub_nilfs2_fs);
} }

View file

@ -27,7 +27,6 @@
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/ntfs.h> #include <grub/ntfs.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -71,175 +70,6 @@ res_attr_data_len (void *res_attr_ptr)
return u32at (res_attr_ptr, 0x10); return u32at (res_attr_ptr, 0x10);
} }
/*
* Check if the attribute is valid and doesn't exceed the allocated region.
* This accounts for resident and non-resident data.
*
* This is based off the documentation from the linux-ntfs project:
* https://flatcap.github.io/linux-ntfs/ntfs/concepts/attribute_header.html
*/
static bool
validate_attribute (grub_uint8_t *attr, void *end)
{
grub_size_t attr_size = 0;
grub_size_t min_size = 0;
grub_size_t run_size = 0;
grub_size_t spare = (grub_uint8_t *) end - attr;
/*
* Just used as a temporary variable to try and deal with cases where someone
* tries to overlap fields.
*/
grub_size_t curr = 0;
/* Need verify we can entirely read the attributes header. */
if (attr + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end)
goto fail;
/*
* So, the rest of this code uses a 16bit int for the attribute length but
* from reading the all the documentation I could find it says this field is
* actually 32bit. But let's be consistent with the rest of the code.
*
* https://elixir.bootlin.com/linux/v6.10.7/source/fs/ntfs3/ntfs.h#L370
*/
attr_size = u16at (attr, GRUB_NTFS_ATTRIBUTE_LENGTH);
if (attr_size > spare)
goto fail;
/* Not an error case, just reached the end of the attributes. */
if (attr_size == 0)
return false;
/*
* Extra validation by trying to calculate a minimum possible size for this
* attribute. +8 from the size of the resident data struct which is the
* minimum that can be added.
*/
min_size = GRUB_NTFS_ATTRIBUTE_HEADER_SIZE + 8;
if (min_size > attr_size)
goto fail;
/* Is the data is resident (0) or not (1). */
if (attr[GRUB_NTFS_ATTRIBUTE_RESIDENT] == 0)
{
/* Read the offset and size of the attribute. */
curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_RES_OFFSET);
curr += u32at (attr, GRUB_NTFS_ATTRIBUTE_RES_LENGTH);
if (curr > min_size)
min_size = curr;
}
else
{
/*
* If the data is non-resident, the minimum size is 64 which is where
* the data runs start. We already have a minimum size of 24. So, just
* adding 40 to get to the real value.
*/
min_size += 40;
if (min_size > attr_size)
goto fail;
/* If the compression unit size is > 0, +8 bytes*/
if (u16at (attr, GRUB_NTFS_ATTRIBUTE_COMPRESSION_UNIT_SIZE) > 0)
min_size += 8;
/*
* Need to consider the data runs now. Each member of the run has byte
* that describes the size of the data length and offset. Each being
* 4 bits in the byte.
*/
curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_DATA_RUNS);
if (curr + 1 > min_size)
min_size = curr + 1;
if (min_size > attr_size)
goto fail;
/*
* Each attribute can store multiple data runs which are stored
* continuously in the attribute. They exist as one header byte
* with up to 14 bytes following it depending on the lengths.
* We stop when we hit a header that is just a NUL byte.
*
* https://flatcap.github.io/linux-ntfs/ntfs/concepts/data_runs.html
*/
while (attr[curr] != 0)
{
/*
* We stop when we hit a header that is just a NUL byte. The data
* run header is stored as a single byte where the top 4 bits refer
* to the number of bytes used to store the total length of the
* data run, and the number of bytes used to store the offset.
* These directly follow the header byte, so we use them to update
* the minimum size. Increment by one more than run size to move on
* to the next run size header byte. An example is a run size field
* value of 0x32, 3 + 2 = 5 bytes follow the run size. Increment
* by 5 to get to the end of this data run then one more to get to
* the start of the next run size byte.
*/
run_size = (attr[curr] & 0x7) + ((attr[curr] >> 4) & 0x7);
curr += (run_size + 1);
min_size += (run_size + 1);
if (min_size > attr_size)
goto fail;
}
}
/* Name offset, doing this after data residence checks. */
if (u16at (attr, GRUB_NTFS_ATTRIBUTE_NAME_OFFSET) != 0)
{
curr = u16at (attr, GRUB_NTFS_ATTRIBUTE_NAME_OFFSET);
/*
* Multiple the name length by 2 as its UTF-16. Can be zero if this in an
* unamed attribute.
*/
curr += attr[GRUB_NTFS_ATTRIBUTE_NAME_LENGTH] * 2;
if (curr > min_size)
min_size = curr;
}
/* Padded to 8 bytes. */
if (min_size % 8 != 0)
min_size += 8 - (min_size % 8);
/*
* At this point min_size should be exactly attr_size but being flexible
* here to avoid any issues.
*/
if (min_size > attr_size)
goto fail;
return true;
fail:
grub_dprintf ("ntfs", "spare=%" PRIuGRUB_SIZE " min_size=%" PRIuGRUB_SIZE " attr_size=%" PRIuGRUB_SIZE "\n",
spare, min_size, attr_size);
return false;
}
/* Return the next attribute if it exists, otherwise return NULL. */
static grub_uint8_t *
next_attribute (grub_uint8_t *curr_attribute, void *end, bool validate)
{
grub_uint8_t *next = curr_attribute;
/*
* Need to verify we aren't exceeding the end of the buffer by reading the
* header for the current attribute
*/
if (curr_attribute + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end)
return NULL;
next += u16at (curr_attribute, 4);
if (validate && validate_attribute (next, end) == false)
return NULL;
return next;
}
grub_ntfscomp_func_t grub_ntfscomp_func; grub_ntfscomp_func_t grub_ntfscomp_func;
static grub_err_t static grub_err_t
@ -248,7 +78,6 @@ fixup (grub_uint8_t *buf, grub_size_t len, const grub_uint8_t *magic)
grub_uint16_t ss; grub_uint16_t ss;
grub_uint8_t *pu; grub_uint8_t *pu;
grub_uint16_t us; grub_uint16_t us;
grub_uint16_t pu_offset;
COMPILE_TIME_ASSERT ((1 << GRUB_NTFS_BLK_SHR) == GRUB_DISK_SECTOR_SIZE); COMPILE_TIME_ASSERT ((1 << GRUB_NTFS_BLK_SHR) == GRUB_DISK_SECTOR_SIZE);
@ -258,10 +87,7 @@ fixup (grub_uint8_t *buf, grub_size_t len, const grub_uint8_t *magic)
ss = u16at (buf, 6) - 1; ss = u16at (buf, 6) - 1;
if (ss != len) if (ss != len)
return grub_error (GRUB_ERR_BAD_FS, "size not match"); return grub_error (GRUB_ERR_BAD_FS, "size not match");
pu_offset = u16at (buf, 4); pu = buf + u16at (buf, 4);
if (pu_offset >= (len * GRUB_DISK_SECTOR_SIZE - (2 * ss)))
return grub_error (GRUB_ERR_BAD_FS, "pu offset size incorrect");
pu = buf + pu_offset;
us = u16at (pu, 0); us = u16at (pu, 0);
buf -= 2; buf -= 2;
while (ss > 0) while (ss > 0)
@ -293,20 +119,13 @@ static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa,
grub_disk_read_hook_t read_hook, grub_disk_read_hook_t read_hook,
void *read_hook_data); void *read_hook_data);
static grub_err_t static void
init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
{ {
at->mft = mft; at->mft = mft;
at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0; at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0;
at->attr_nxt = mft->buf + first_attr_off (mft->buf); at->attr_nxt = mft->buf + first_attr_off (mft->buf);
at->end = mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR);
if (at->attr_nxt > at->end)
return grub_error (GRUB_ERR_BAD_FS, "attributes start outside the MFT");
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
return GRUB_ERR_NONE;
} }
static void static void
@ -320,26 +139,16 @@ free_attr (struct grub_ntfs_attr *at)
static grub_uint8_t * static grub_uint8_t *
find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
{ {
grub_uint8_t *mft_end;
grub_uint16_t nsize;
grub_uint16_t nxt_offset;
grub_uint32_t edat_offset;
/* GRUB_NTFS_AF_ALST indicates the attribute list type */
if (at->flags & GRUB_NTFS_AF_ALST) if (at->flags & GRUB_NTFS_AF_ALST)
{ {
retry: retry:
while (at->attr_nxt) while (at->attr_nxt < at->attr_end)
{ {
at->attr_cur = at->attr_nxt; at->attr_cur = at->attr_nxt;
/* at->attr_nxt += u16at (at->attr_cur, 4);
* Go to the next attribute in the list but do not validate
* because this is the attribute list type.
*/
at->attr_nxt = next_attribute (at->attr_cur, at->attr_end, false);
if ((*at->attr_cur == attr) || (attr == 0)) if ((*at->attr_cur == attr) || (attr == 0))
{ {
grub_uint8_t *new_pos, *end; grub_uint8_t *new_pos;
if (at->flags & GRUB_NTFS_AF_MMFT) if (at->flags & GRUB_NTFS_AF_MMFT)
{ {
@ -363,41 +172,15 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
return NULL; return NULL;
} }
/*
* Only time emft_bufs is defined is in this function, with this
* size.
*/
grub_size_t emft_buf_size =
at->mft->data->mft_size << GRUB_NTFS_BLK_SHR;
/*
* Needs to be enough space for the successful case to even
* bother.
*/
if (first_attr_off (at->emft_buf) >= (emft_buf_size - 0x18 - 2))
{
grub_error (GRUB_ERR_BAD_FS,
"can\'t find 0x%X in attribute list",
(unsigned char) *at->attr_cur);
return NULL;
}
new_pos = &at->emft_buf[first_attr_off (at->emft_buf)]; new_pos = &at->emft_buf[first_attr_off (at->emft_buf)];
end = &at->emft_buf[emft_buf_size]; while (*new_pos != 0xFF)
at->end = end;
while (new_pos && *new_pos != 0xFF)
{ {
if ((*new_pos == *at->attr_cur) if ((*new_pos == *at->attr_cur)
&& (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18))) && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
{ {
return new_pos; return new_pos;
} }
/* new_pos += u16at (new_pos, 4);
* Go to the next attribute in the list but do not validate
* because this is the attribute list type.
*/
new_pos = next_attribute (new_pos, end, false);
} }
grub_error (GRUB_ERR_BAD_FS, grub_error (GRUB_ERR_BAD_FS,
"can\'t find 0x%X in attribute list", "can\'t find 0x%X in attribute list",
@ -408,27 +191,12 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
return NULL; return NULL;
} }
at->attr_cur = at->attr_nxt; at->attr_cur = at->attr_nxt;
mft_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); while (*at->attr_cur != 0xFF)
while (at->attr_cur >= at->mft->buf && at->attr_cur < (mft_end - 4)
&& *at->attr_cur != 0xFF)
{ {
/* at->attr_nxt += u16at (at->attr_cur, 4);
* We can't use validate_attribute here because this logic
* seems to be used for both parsing through attributes
* and attribute lists.
*/
nsize = u16at (at->attr_cur, 4);
if (at->attr_cur + grub_max (GRUB_NTFS_ATTRIBUTE_HEADER_SIZE, nsize) >= at->end)
{
at->attr_nxt = at->attr_cur;
break;
}
else
at->attr_nxt = at->attr_cur + nsize;
if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
at->attr_end = at->attr_cur; at->attr_end = at->attr_cur;
if ((*at->attr_cur == attr) || (attr == 0) || (nsize == 0)) if ((*at->attr_cur == attr) || (attr == 0))
return at->attr_cur; return at->attr_cur;
at->attr_cur = at->attr_nxt; at->attr_cur = at->attr_nxt;
} }
@ -458,54 +226,23 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
return NULL; return NULL;
} }
at->attr_nxt = at->edat_buf; at->attr_nxt = at->edat_buf;
edat_offset = u32at (pa, 0x30); at->attr_end = at->edat_buf + u32at (pa, 0x30);
if (edat_offset >= n)
{
grub_error (GRUB_ERR_BAD_FS, "edat offset is out of bounds");
return NULL;
}
at->attr_end = at->edat_buf + edat_offset;
pa_end = at->edat_buf + n; pa_end = at->edat_buf + n;
} }
else else
{ {
at->attr_nxt = at->attr_end + res_attr_data_off (pa); at->attr_nxt = at->attr_end + res_attr_data_off (pa);
edat_offset = u32at (pa, 4); at->attr_end = at->attr_end + u32at (pa, 4);
if ((at->attr_end + edat_offset) >= (at->end))
{
grub_error (GRUB_ERR_BAD_FS, "edat offset is out of bounds");
return NULL;
}
at->attr_end = at->attr_end + edat_offset;
pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
} }
at->flags |= GRUB_NTFS_AF_ALST; at->flags |= GRUB_NTFS_AF_ALST;
while (at->attr_nxt < at->attr_end)
/* From this point on pa_end is the end of the buffer */
at->end = pa_end;
if (at->attr_end >= pa_end || at->attr_nxt >= pa_end)
return NULL;
while (at->attr_nxt)
{ {
if ((*at->attr_nxt == attr) || (attr == 0)) if ((*at->attr_nxt == attr) || (attr == 0))
break; break;
at->attr_nxt += u16at (at->attr_nxt, 4);
nxt_offset = u16at (at->attr_nxt, 4);
at->attr_nxt += nxt_offset;
/*
* Stop and set attr_nxt to NULL when either the next offset is zero,
* or when the pointer is within four bytes of the end of the buffer
* since we could attempt to access attr_nxt + 4 bytes offset above to
* get the next 16-bit 'nxt_offset' value.
*/
if (nxt_offset == 0 || at->attr_nxt >= (pa_end - 4))
at->attr_nxt = NULL;
} }
if (at->attr_nxt >= at->attr_end)
if ((at->attr_nxt + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE) >= at->attr_end || at->attr_nxt == NULL)
return NULL; return NULL;
if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA)) if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA))
@ -526,11 +263,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
grub_cpu_to_le32 (at->mft->data->mft_start grub_cpu_to_le32 (at->mft->data->mft_start
+ 1)); + 1));
pa = at->attr_nxt + u16at (pa, 4); pa = at->attr_nxt + u16at (pa, 4);
while (pa < at->attr_end)
if (pa >= pa_end)
pa = NULL;
while (pa)
{ {
if (*pa != attr) if (*pa != attr)
break; break;
@ -547,8 +280,6 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0))
return NULL; return NULL;
pa += u16at (pa, 4); pa += u16at (pa, 4);
if (pa >= pa_end)
pa = NULL;
} }
at->attr_nxt = at->attr_cur; at->attr_nxt = at->attr_cur;
at->flags &= ~GRUB_NTFS_AF_GPOS; at->flags &= ~GRUB_NTFS_AF_GPOS;
@ -563,31 +294,24 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
grub_uint8_t attr) grub_uint8_t attr)
{ {
grub_uint8_t *pa; grub_uint8_t *pa;
grub_uint8_t *last_pa;
if (init_attr (at, mft) != GRUB_ERR_NONE)
return NULL;
init_attr (at, mft);
pa = find_attr (at, attr); pa = find_attr (at, attr);
if (pa == NULL) if (pa == NULL)
return NULL; return NULL;
if ((at->flags & GRUB_NTFS_AF_ALST) == 0) if ((at->flags & GRUB_NTFS_AF_ALST) == 0)
{ {
/* Used to make sure we're not stuck in a loop. */
last_pa = NULL;
while (1) while (1)
{ {
pa = find_attr (at, attr); pa = find_attr (at, attr);
if (pa == NULL || pa == last_pa) if (pa == NULL)
break; break;
if (at->flags & GRUB_NTFS_AF_ALST) if (at->flags & GRUB_NTFS_AF_ALST)
return pa; return pa;
last_pa = pa;
} }
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
free_attr (at); free_attr (at);
if (init_attr (at, mft) != GRUB_ERR_NONE) init_attr (at, mft);
return NULL;
pa = find_attr (at, attr); pa = find_attr (at, attr);
} }
return pa; return pa;
@ -639,7 +363,7 @@ retry:
goto retry; goto retry;
} }
} }
return grub_error (GRUB_ERR_BAD_FS, "run list overflow"); return grub_error (GRUB_ERR_BAD_FS, "run list overflown");
} }
ctx->curr_vcn = ctx->next_vcn; ctx->curr_vcn = ctx->next_vcn;
ctx->next_vcn += read_run_data (run, c1, 0); /* length of current VCN */ ctx->next_vcn += read_run_data (run, c1, 0); /* length of current VCN */
@ -678,8 +402,6 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
grub_disk_read_hook_t read_hook, void *read_hook_data) grub_disk_read_hook_t read_hook, void *read_hook_data)
{ {
struct grub_ntfs_rlst cc, *ctx; struct grub_ntfs_rlst cc, *ctx;
grub_uint8_t *end_ptr = (pa + len);
grub_uint16_t run_offset;
if (len == 0) if (len == 0)
return 0; return 0;
@ -712,11 +434,7 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
return 0; return 0;
} }
run_offset = u16at (pa, 0x20); ctx->cur_run = pa + u16at (pa, 0x20);
if ((run_offset + pa) >= end_ptr || ((run_offset + pa) >= (at->end)))
return grub_error (GRUB_ERR_BAD_FS, "run offset out of range");
ctx->cur_run = pa + run_offset;
ctx->next_vcn = u32at (pa, 0x10); ctx->next_vcn = u32at (pa, 0x10);
ctx->curr_lcn = 0; ctx->curr_lcn = 0;
@ -779,8 +497,6 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
grub_uint8_t *pp; grub_uint8_t *pp;
grub_err_t ret; grub_err_t ret;
if (at == NULL || at->attr_cur == NULL)
return grub_error (GRUB_ERR_BAD_FS, "attribute not found");
save_cur = at->attr_cur; save_cur = at->attr_cur;
at->attr_nxt = at->attr_cur; at->attr_nxt = at->attr_cur;
attr = *at->attr_nxt; attr = *at->attr_nxt;
@ -797,17 +513,14 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
else else
vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR); vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR);
pa = at->attr_nxt + u16at (at->attr_nxt, 4); pa = at->attr_nxt + u16at (at->attr_nxt, 4);
if (validate_attribute (pa, at->attr_end) == false) while (pa < at->attr_end)
pa = NULL;
while (pa)
{ {
if (*pa != attr) if (*pa != attr)
break; break;
if (u32at (pa, 8) > vcn) if (u32at (pa, 8) > vcn)
break; break;
at->attr_nxt = pa; at->attr_nxt = pa;
pa = next_attribute (pa, at->attr_end, true); pa += u16at (pa, 4);
} }
} }
pp = find_attr (at, attr); pp = find_attr (at, attr);
@ -869,7 +582,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno)
mft->attr.attr_end = 0; /* Don't jump to attribute list */ mft->attr.attr_end = 0; /* Don't jump to attribute list */
} }
else else
return init_attr (&mft->attr, mft); init_attr (&mft->attr, mft);
return 0; return 0;
} }
@ -877,11 +590,8 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno)
static void static void
free_file (struct grub_ntfs_file *mft) free_file (struct grub_ntfs_file *mft)
{ {
if (mft) free_attr (&mft->attr);
{ grub_free (mft->buf);
free_attr (&mft->attr);
grub_free (mft->buf);
}
} }
static char * static char *
@ -912,7 +622,6 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos
{ {
grub_uint8_t *np; grub_uint8_t *np;
int ns; int ns;
grub_uint16_t pos_incr;
while (1) while (1)
{ {
@ -975,12 +684,7 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos
grub_free (ustr); grub_free (ustr);
} }
pos_incr = u16at (pos, 8); pos += u16at (pos, 8);
if (pos_incr > 0)
pos += pos_incr;
else
return 0;
} }
return 0; return 0;
} }
@ -1091,9 +795,6 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
int ret = 0; int ret = 0;
grub_size_t bitmap_len; grub_size_t bitmap_len;
struct grub_ntfs_file *mft; struct grub_ntfs_file *mft;
/* Used to make sure we're not stuck in a loop. */
grub_uint8_t *last_pos = NULL;
grub_uint32_t tmp_len;
mft = (struct grub_ntfs_file *) dir; mft = (struct grub_ntfs_file *) dir;
@ -1107,18 +808,15 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
bmp = NULL; bmp = NULL;
at = &attr; at = &attr;
if (init_attr (at, mft) != GRUB_ERR_NONE) init_attr (at, mft);
return 0;
while (1) while (1)
{ {
cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT); cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT);
if (cur_pos == NULL || cur_pos == last_pos) if (cur_pos == NULL)
{ {
grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT");
goto done; goto done;
} }
last_pos = cur_pos;
/* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */ /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */
if ((u32at (cur_pos, 8) != 0x180400) || if ((u32at (cur_pos, 8) != 0x180400) ||
@ -1126,8 +824,6 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
(u32at (cur_pos, 0x1C) != 0x300033)) (u32at (cur_pos, 0x1C) != 0x300033))
continue; continue;
cur_pos += res_attr_data_off (cur_pos); cur_pos += res_attr_data_off (cur_pos);
if(cur_pos >= at->end)
continue;
if (*cur_pos != 0x30) /* Not filename index */ if (*cur_pos != 0x30) /* Not filename index */
continue; continue;
break; break;
@ -1143,21 +839,11 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
bitmap = NULL; bitmap = NULL;
bitmap_len = 0; bitmap_len = 0;
free_attr (at); free_attr (at);
/* No need to check errors here, as it will already be fine */
init_attr (at, mft); init_attr (at, mft);
last_pos = NULL;
while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL)
{ {
int ofs; int ofs;
if (cur_pos == last_pos)
{
grub_error (GRUB_ERR_BAD_FS, "bitmap attribute loop");
goto done;
}
last_pos = cur_pos;
ofs = cur_pos[0xA]; ofs = cur_pos[0xA];
/* Namelen=4, Name="$I30" */ /* Namelen=4, Name="$I30" */
if ((cur_pos[9] == 4) && if ((cur_pos[9] == 4) &&
@ -1205,15 +891,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
"fails to read non-resident $BITMAP"); "fails to read non-resident $BITMAP");
goto done; goto done;
} }
tmp_len = u32at (cur_pos, 0x30); bitmap_len = u32at (cur_pos, 0x30);
if (tmp_len <= bitmap_len)
bitmap_len = tmp_len;
else
{
grub_error (GRUB_ERR_BAD_FS,
"bitmap len too large for non-resident $BITMAP");
goto done;
}
} }
bitmap = bmp; bitmap = bmp;
@ -1222,7 +900,6 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
} }
free_attr (at); free_attr (at);
last_pos = NULL;
cur_pos = locate_attr (at, mft, GRUB_NTFS_AT_INDEX_ALLOCATION); cur_pos = locate_attr (at, mft, GRUB_NTFS_AT_INDEX_ALLOCATION);
while (cur_pos != NULL) while (cur_pos != NULL)
{ {
@ -1232,9 +909,6 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
(u32at (cur_pos, 0x44) == 0x300033)) (u32at (cur_pos, 0x44) == 0x300033))
break; break;
cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ALLOCATION); cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ALLOCATION);
if (cur_pos == last_pos)
break;
last_pos = cur_pos;
} }
if ((!cur_pos) && (bitmap)) if ((!cur_pos) && (bitmap))
@ -1530,7 +1204,6 @@ grub_ntfs_label (grub_device_t device, char **label)
struct grub_ntfs_data *data = 0; struct grub_ntfs_data *data = 0;
struct grub_fshelp_node *mft = 0; struct grub_fshelp_node *mft = 0;
grub_uint8_t *pa; grub_uint8_t *pa;
grub_err_t err;
grub_dl_ref (my_mod); grub_dl_ref (my_mod);
@ -1556,13 +1229,10 @@ grub_ntfs_label (grub_device_t device, char **label)
goto fail; goto fail;
} }
err = init_attr (&mft->attr, mft); init_attr (&mft->attr, mft);
if (err != GRUB_ERR_NONE)
return err;
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
if (pa == NULL || pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR)) if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR))
{ {
grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
goto fail; goto fail;
@ -1580,8 +1250,7 @@ grub_ntfs_label (grub_device_t device, char **label)
len = res_attr_data_len (pa) / 2; len = res_attr_data_len (pa) / 2;
pa += res_attr_data_off (pa); pa += res_attr_data_off (pa);
if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len && if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
pa >= mft->buf && (pa + len < (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR))))
*label = get_utf8 (pa, len); *label = get_utf8 (pa, len);
else else
grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
@ -1651,16 +1320,11 @@ static struct grub_fs grub_ntfs_fs =
GRUB_MOD_INIT (ntfs) GRUB_MOD_INIT (ntfs)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_ntfs_fs);
{
grub_ntfs_fs.mod = mod;
grub_fs_register (&grub_ntfs_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI (ntfs) GRUB_MOD_FINI (ntfs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_ntfs_fs);
grub_fs_unregister (&grub_ntfs_fs);
} }

View file

@ -22,7 +22,6 @@
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/ntfs.h> #include <grub/ntfs.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -30,7 +29,7 @@ static grub_err_t
decomp_nextvcn (struct grub_ntfs_comp *cc) decomp_nextvcn (struct grub_ntfs_comp *cc)
{ {
if (cc->comp_head >= cc->comp_tail) if (cc->comp_head >= cc->comp_tail)
return grub_error (GRUB_ERR_BAD_FS, "compression block overflow"); return grub_error (GRUB_ERR_BAD_FS, "compression block overflown");
if (grub_disk_read if (grub_disk_read
(cc->disk, (cc->disk,
(cc->comp_table[cc->comp_head].next_lcn - (cc->comp_table[cc->comp_head].next_lcn -
@ -311,7 +310,6 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
{ {
grub_err_t ret; grub_err_t ret;
grub_disk_addr_t vcn; grub_disk_addr_t vcn;
int log_sz;
if (ctx->attr->sbuf) if (ctx->attr->sbuf)
{ {
@ -351,12 +349,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
} }
ctx->comp.comp_head = ctx->comp.comp_tail = 0; ctx->comp.comp_head = ctx->comp.comp_tail = 0;
if (grub_add (ctx->comp.log_spc, GRUB_NTFS_BLK_SHR, &log_sz)) ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR));
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("compression buffer size overflow"));
return 0;
}
ctx->comp.cbuf = grub_malloc (1 << log_sz);
if (!ctx->comp.cbuf) if (!ctx->comp.cbuf)
return 0; return 0;

View file

@ -52,7 +52,6 @@ read_number (const char *str, grub_size_t size)
GRUB_MOD_INIT (odc) GRUB_MOD_INIT (odc)
{ {
grub_cpio_fs.mod = mod;
grub_fs_register (&grub_cpio_fs); grub_fs_register (&grub_cpio_fs);
} }

View file

@ -192,7 +192,6 @@ static struct grub_fs grub_procfs_fs =
GRUB_MOD_INIT (procfs) GRUB_MOD_INIT (procfs)
{ {
grub_procfs_fs.mod = mod;
grub_disk_dev_register (&grub_procfs_dev); grub_disk_dev_register (&grub_procfs_dev);
grub_fs_register (&grub_procfs_fs); grub_fs_register (&grub_procfs_fs);
} }

View file

@ -39,7 +39,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -1418,16 +1417,11 @@ static struct grub_fs grub_reiserfs_fs =
GRUB_MOD_INIT(reiserfs) GRUB_MOD_INIT(reiserfs)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_reiserfs_fs);
{
grub_reiserfs_fs.mod = mod;
grub_fs_register (&grub_reiserfs_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI(reiserfs) GRUB_MOD_FINI(reiserfs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_reiserfs_fs);
grub_fs_unregister (&grub_reiserfs_fs);
} }

View file

@ -23,7 +23,6 @@
#include <grub/disk.h> #include <grub/disk.h>
#include <grub/fs.h> #include <grub/fs.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -476,15 +475,10 @@ static struct grub_fs grub_romfs_fs =
GRUB_MOD_INIT(romfs) GRUB_MOD_INIT(romfs)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_romfs_fs);
{
grub_romfs_fs.mod = mod;
grub_fs_register (&grub_romfs_fs);
}
} }
GRUB_MOD_FINI(romfs) GRUB_MOD_FINI(romfs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_romfs_fs);
grub_fs_unregister (&grub_romfs_fs);
} }

View file

@ -26,7 +26,6 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/lockdown.h>
#include <grub/safemath.h> #include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -429,9 +428,6 @@ grub_sfs_mount (grub_disk_t disk)
- 24 /* offsetof (struct grub_sfs_objc, objects) */ - 24 /* offsetof (struct grub_sfs_objc, objects) */
- 25); /* offsetof (struct grub_sfs_obj, filename) */ - 25); /* offsetof (struct grub_sfs_obj, filename) */
data->label = grub_zalloc (max_len + 1); data->label = grub_zalloc (max_len + 1);
if (data->label == NULL)
goto fail;
grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len); grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len);
grub_free (rootobjc_data); grub_free (rootobjc_data);
@ -783,16 +779,11 @@ static struct grub_fs grub_sfs_fs =
GRUB_MOD_INIT(sfs) GRUB_MOD_INIT(sfs)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_sfs_fs);
{
grub_sfs_fs.mod = mod;
grub_fs_register (&grub_sfs_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI(sfs) GRUB_MOD_FINI(sfs)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_sfs_fs);
grub_fs_unregister (&grub_sfs_fs);
} }

View file

@ -460,11 +460,11 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
{ {
char *ret; char *ret;
grub_err_t err; grub_err_t err;
grub_uint32_t sz; grub_size_t sz;
if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz)) if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
{ {
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink name length overflow")); grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
return NULL; return NULL;
} }
@ -580,7 +580,6 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
struct grub_squash_dirent di; struct grub_squash_dirent di;
struct grub_squash_inode ino; struct grub_squash_inode ino;
grub_size_t sz; grub_size_t sz;
grub_uint16_t nlen;
err = read_chunk (dir->data, &di, sizeof (di), err = read_chunk (dir->data, &di, sizeof (di),
grub_le_to_cpu64 (dir->data->sb.diroffset) grub_le_to_cpu64 (dir->data->sb.diroffset)
@ -596,12 +595,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
if (err) if (err)
return 0; return 0;
if (grub_add (grub_le_to_cpu16 (di.namelen), 2, &nlen)) buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
return 0;
}
buf = grub_malloc (nlen);
if (!buf) if (!buf)
return 0; return 0;
err = read_chunk (dir->data, buf, err = read_chunk (dir->data, buf,
@ -822,10 +816,10 @@ direct_read (struct grub_squash_data *data,
break; break;
} }
total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz); total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz);
ino->block_sizes = grub_calloc (total_blocks, ino->block_sizes = grub_malloc (total_blocks
sizeof (ino->block_sizes[0])); * sizeof (ino->block_sizes[0]));
ino->cumulated_block_sizes = grub_calloc (total_blocks, ino->cumulated_block_sizes = grub_malloc (total_blocks
sizeof (ino->cumulated_block_sizes[0])); * sizeof (ino->cumulated_block_sizes[0]));
if (!ino->block_sizes || !ino->cumulated_block_sizes) if (!ino->block_sizes || !ino->cumulated_block_sizes)
{ {
grub_free (ino->block_sizes); grub_free (ino->block_sizes);
@ -1050,7 +1044,6 @@ static struct grub_fs grub_squash_fs =
GRUB_MOD_INIT(squash4) GRUB_MOD_INIT(squash4)
{ {
grub_squash_fs.mod = mod;
grub_fs_register (&grub_squash_fs); grub_fs_register (&grub_squash_fs);
} }

View file

@ -25,7 +25,6 @@
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -77,10 +76,8 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
{ {
struct head hd; struct head hd;
int reread = 0, have_longname = 0, have_longlink = 0; int reread = 0, have_longname = 0, have_longlink = 0;
grub_size_t sz;
data->hofs = data->next_hofs; data->hofs = data->next_hofs;
*name = NULL;
for (reread = 0; reread < 3; reread++) for (reread = 0; reread < 3; reread++)
{ {
@ -99,13 +96,8 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
if (hd.typeflag == 'L') if (hd.typeflag == 'L')
{ {
grub_err_t err; grub_err_t err;
grub_size_t namesize; grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
*name = grub_malloc (namesize + 1);
if (grub_cast (read_number (hd.size, sizeof (hd.size)), &namesize) ||
grub_add (namesize, 1, &sz))
return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow"));
*name = grub_malloc (sz);
if (*name == NULL) if (*name == NULL)
return grub_errno; return grub_errno;
err = grub_disk_read (data->disk, 0, err = grub_disk_read (data->disk, 0,
@ -124,21 +116,16 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
if (hd.typeflag == 'K') if (hd.typeflag == 'K')
{ {
grub_err_t err; grub_err_t err;
grub_size_t linksize; grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
if (data->linkname_alloc < linksize + 1)
if (grub_cast (read_number (hd.size, sizeof (hd.size)), &linksize) ||
grub_add (linksize, 1, &sz))
return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow"));
if (data->linkname_alloc < sz)
{ {
char *n; char *n;
n = grub_calloc (2, sz); n = grub_calloc (2, linksize + 1);
if (!n) if (!n)
return grub_errno; return grub_errno;
grub_free (data->linkname); grub_free (data->linkname);
data->linkname = n; data->linkname = n;
data->linkname_alloc = 2 * (sz); data->linkname_alloc = 2 * (linksize + 1);
} }
err = grub_disk_read (data->disk, 0, err = grub_disk_read (data->disk, 0,
@ -161,10 +148,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
while (extra_size < sizeof (hd.prefix) while (extra_size < sizeof (hd.prefix)
&& hd.prefix[extra_size]) && hd.prefix[extra_size])
extra_size++; extra_size++;
*name = grub_malloc (sizeof (hd.name) + extra_size + 2);
if (grub_add (sizeof (hd.name) + 2, extra_size, &sz))
return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow"));
*name = grub_malloc (sz);
if (*name == NULL) if (*name == NULL)
return grub_errno; return grub_errno;
if (hd.prefix[0]) if (hd.prefix[0])
@ -176,22 +160,15 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
(*name)[extra_size + sizeof (hd.name)] = 0; (*name)[extra_size + sizeof (hd.name)] = 0;
} }
if (grub_cast (read_number (hd.size, sizeof (hd.size)), &data->size)) data->size = read_number (hd.size, sizeof (hd.size));
return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow"));
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
data->next_hofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & data->next_hofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
~(GRUB_DISK_SECTOR_SIZE - 1)); ~(GRUB_DISK_SECTOR_SIZE - 1));
if (mtime) if (mtime)
{ *mtime = read_number (hd.mtime, sizeof (hd.mtime));
if (grub_cast (read_number (hd.mtime, sizeof (hd.mtime)), mtime))
return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow"));
}
if (mode) if (mode)
{ {
if (grub_cast (read_number (hd.mode, sizeof (hd.mode)), mode)) *mode = read_number (hd.mode, sizeof (hd.mode));
return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow"));
switch (hd.typeflag) switch (hd.typeflag)
{ {
/* Hardlink. */ /* Hardlink. */
@ -225,10 +202,6 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
if (*name == NULL)
return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -363,7 +336,6 @@ static struct grub_fs grub_cpio_fs = {
GRUB_MOD_INIT (tar) GRUB_MOD_INIT (tar)
{ {
grub_cpio_fs.mod = mod;
grub_fs_register (&grub_cpio_fs); grub_fs_register (&grub_cpio_fs);
} }

View file

@ -27,7 +27,6 @@
#include <grub/fshelp.h> #include <grub/fshelp.h>
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/datetime.h> #include <grub/datetime.h>
#include <grub/lockdown.h>
#include <grub/udf.h> #include <grub/udf.h>
#include <grub/safemath.h> #include <grub/safemath.h>
@ -1456,16 +1455,11 @@ static struct grub_fs grub_udf_fs = {
GRUB_MOD_INIT (udf) GRUB_MOD_INIT (udf)
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_udf_fs);
{
grub_udf_fs.mod = mod;
grub_fs_register (&grub_udf_fs);
}
my_mod = mod; my_mod = mod;
} }
GRUB_MOD_FINI (udf) GRUB_MOD_FINI (udf)
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_udf_fs);
grub_fs_unregister (&grub_udf_fs);
} }

View file

@ -25,7 +25,6 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -464,7 +463,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
/* Check against zero is paylindromic, no need to swap. */ /* Check against zero is paylindromic, no need to swap. */
if (data->inode.nblocks == 0 if (data->inode.nblocks == 0
&& INODE_SIZE (data) <= sizeof (data->inode.symlink)) && INODE_SIZE (data) <= sizeof (data->inode.symlink))
grub_strlcpy (symlink, (char *) data->inode.symlink, sz); grub_strcpy (symlink, (char *) data->inode.symlink);
else else
{ {
if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0) if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0)
@ -900,11 +899,7 @@ GRUB_MOD_INIT(ufs1)
#endif #endif
#endif #endif
{ {
if (!grub_is_lockdown ()) grub_fs_register (&grub_ufs_fs);
{
grub_ufs_fs.mod = mod;
grub_fs_register (&grub_ufs_fs);
}
my_mod = mod; my_mod = mod;
} }
@ -918,7 +913,6 @@ GRUB_MOD_FINI(ufs1)
#endif #endif
#endif #endif
{ {
if (!grub_is_lockdown ()) grub_fs_unregister (&grub_ufs_fs);
grub_fs_unregister (&grub_ufs_fs);
} }

View file

@ -88,10 +88,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */ #define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */ #define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */ #define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
#define XFS_SB_FEAT_INCOMPAT_EXCHRANGE (1 << 6) /* exchangerange supported */
#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 7) /* parent pointers */
#define XFS_SB_FEAT_INCOMPAT_METADIR (1 << 8) /* metadata dir tree */
/* /*
* Directory entries with ftype are explicitly handled by GRUB code. * Directory entries with ftype are explicitly handled by GRUB code.
@ -101,15 +98,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
* *
* We do not currently verify metadata UUID, so it is safe to read filesystems * We do not currently verify metadata UUID, so it is safe to read filesystems
* with the XFS_SB_FEAT_INCOMPAT_META_UUID feature. * with the XFS_SB_FEAT_INCOMPAT_META_UUID feature.
*
* We do not currently replay the log, so it is safe to read filesystems
* with the XFS_SB_FEAT_INCOMPAT_EXCHRANGE feature.
*
* We do not currently read directory parent pointers, so it is safe to read
* filesystems with the XFS_SB_FEAT_INCOMPAT_PARENT feature.
*
* We do not currently look at realtime or quota metadata, so it is safe to
* read filesystems with the XFS_SB_FEAT_INCOMPAT_METADIR feature.
*/ */
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \ #define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
(XFS_SB_FEAT_INCOMPAT_FTYPE | \ (XFS_SB_FEAT_INCOMPAT_FTYPE | \
@ -117,10 +105,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
XFS_SB_FEAT_INCOMPAT_META_UUID | \ XFS_SB_FEAT_INCOMPAT_META_UUID | \
XFS_SB_FEAT_INCOMPAT_BIGTIME | \ XFS_SB_FEAT_INCOMPAT_BIGTIME | \
XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
XFS_SB_FEAT_INCOMPAT_NREXT64 | \ XFS_SB_FEAT_INCOMPAT_NREXT64)
XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \
XFS_SB_FEAT_INCOMPAT_PARENT | \
XFS_SB_FEAT_INCOMPAT_METADIR)
struct grub_xfs_sblock struct grub_xfs_sblock
{ {
@ -342,8 +327,6 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data)
} }
return 1; return 1;
} }
grub_error (GRUB_ERR_BAD_FS, "unsupported XFS filesystem version");
return 0; return 0;
} }
@ -612,17 +595,6 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
do do
{ {
grub_uint64_t i; grub_uint64_t i;
grub_addr_t keys_end, data_end;
if (grub_mul (sizeof (grub_uint64_t), nrec, &keys_end) ||
grub_add ((grub_addr_t) keys, keys_end, &keys_end) ||
grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) ||
keys_end > data_end)
{
grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS root keys");
grub_free (leaf);
return 0;
}
for (i = 0; i < nrec; i++) for (i = 0; i < nrec; i++)
{ {
@ -733,7 +705,6 @@ static char *
grub_xfs_read_symlink (grub_fshelp_node_t node) grub_xfs_read_symlink (grub_fshelp_node_t node)
{ {
grub_ssize_t size = grub_be_to_cpu64 (node->inode.size); grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);
grub_size_t sz;
if (size < 0) if (size < 0)
{ {
@ -755,12 +726,7 @@ grub_xfs_read_symlink (grub_fshelp_node_t node)
if (node->data->hascrc) if (node->data->hascrc)
off = 56; off = 56;
if (grub_add (size, 1, &sz)) symlink = grub_malloc (size + 1);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
return 0;
}
symlink = grub_malloc (sz);
if (!symlink) if (!symlink)
return 0; return 0;
@ -810,15 +776,8 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
{ {
struct grub_fshelp_node *fdiro; struct grub_fshelp_node *fdiro;
grub_err_t err; grub_err_t err;
grub_size_t sz;
if (grub_add (grub_xfs_fshelp_size(ctx->diro->data), 1, &sz)) fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory data size overflow"));
grub_print_error ();
return 0;
}
fdiro = grub_malloc (sz);
if (!fdiro) if (!fdiro)
{ {
grub_print_error (); grub_print_error ();
@ -885,11 +844,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
grub_uint8_t c; grub_uint8_t c;
if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)) if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
{ return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");
grub_error (GRUB_ERR_BAD_FS, "invalid XFS inode");
return 0;
}
/* inopos might be unaligned. */ /* inopos might be unaligned. */
if (smallino) if (smallino)
@ -947,7 +902,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
grub_xfs_first_de(dir->data, dirblock); grub_xfs_first_de(dir->data, dirblock);
int entries = -1; int entries = -1;
char *end = dirblock + dirblk_size; char *end = dirblock + dirblk_size;
grub_uint32_t magic;
numread = grub_xfs_read_file (dir, 0, 0, numread = grub_xfs_read_file (dir, 0, 0,
blk << dirblk_log2, blk << dirblk_log2,
@ -958,20 +912,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
return 0; return 0;
} }
/*
* If this data block isn't actually part of the extent list then
* grub_xfs_read_file() returns a block of zeros. So, if the magic
* number field is all zeros then this block should be skipped.
*/
magic = *(grub_uint32_t *)(void *) dirblock;
if (!magic)
continue;
/* /*
* Leaf and tail information are only in the data block if the number * Leaf and tail information are only in the data block if the number
* of extents is 1. * of extents is 1.
*/ */
if (grub_xfs_get_inode_nextents (&dir->inode) == 1) if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
{ {
struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock); struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
@ -1008,10 +953,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
filename = (char *)(direntry + 1); filename = (char *)(direntry + 1);
if (filename + direntry->len + 1 > (char *) end) if (filename + direntry->len + 1 > (char *) end)
{ return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
return 0;
}
/* The byte after the filename is for the filetype, padding, or /* The byte after the filename is for the filetype, padding, or
tag, which is not used by GRUB. So it can be overwritten. */ tag, which is not used by GRUB. So it can be overwritten. */
@ -1028,7 +970,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
* The expected number of directory entries is only tracked for the * The expected number of directory entries is only tracked for the
* single extent case. * single extent case.
*/ */
if (grub_xfs_get_inode_nextents (&dir->inode) == 1) if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
{ {
/* Check if last direntry in this block is reached. */ /* Check if last direntry in this block is reached. */
entries--; entries--;
@ -1105,7 +1047,7 @@ grub_xfs_mount (grub_disk_t disk)
return data; return data;
fail: fail:
if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem"); grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem");
grub_free (data); grub_free (data);
@ -1339,7 +1281,6 @@ static struct grub_fs grub_xfs_fs =
GRUB_MOD_INIT(xfs) GRUB_MOD_INIT(xfs)
{ {
grub_xfs_fs.mod = mod;
grub_fs_register (&grub_xfs_fs); grub_fs_register (&grub_xfs_fs);
my_mod = mod; my_mod = mod;
} }

View file

@ -57,8 +57,6 @@
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/safemath.h> #include <grub/safemath.h>
#include <zstd.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
#define ZPOOL_PROP_BOOTFS "bootfs" #define ZPOOL_PROP_BOOTFS "bootfs"
@ -293,9 +291,6 @@ static const char *spa_feature_names[] = {
"com.delphix:embedded_data", "com.delphix:embedded_data",
"com.delphix:extensible_dataset", "com.delphix:extensible_dataset",
"org.open-zfs:large_blocks", "org.open-zfs:large_blocks",
"com.klarasystems:vdev_zaps_v2",
"com.delphix:head_errlog",
"org.freebsd:zstd_compress",
NULL NULL
}; };
@ -317,40 +312,6 @@ zlib_decompress (void *s, void *d,
return grub_errno; return grub_errno;
} }
static grub_err_t
zstd_decompress (void *ibuf, void *obuf, grub_size_t isize,
grub_size_t osize)
{
grub_size_t zstd_ret;
grub_uint32_t c_len;
grub_uint8_t *byte_buf = (grub_uint8_t *) ibuf;
if (isize < 8)
return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data too short");
c_len = grub_be_to_cpu32 (grub_get_unaligned32 (byte_buf));
if (c_len > isize - 8)
return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
"zstd data announced size overflow");
/*
* ZFS uses non-stadard magic for zstd streams. Rather than adjusting
* library functions, replace non-standard magic with standard one.
*/
byte_buf[4] = 0x28;
byte_buf[5] = 0xb5;
byte_buf[6] = 0x2f;
byte_buf[7] = 0xfd;
zstd_ret = ZSTD_decompress (obuf, osize, byte_buf + 4, c_len + 4);
if (ZSTD_isError (zstd_ret))
return grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
"zstd data corrupted (error %d)", (int) zstd_ret);
return GRUB_ERR_NONE;
}
static grub_err_t static grub_err_t
zle_decompress (void *s, void *d, zle_decompress (void *s, void *d,
grub_size_t slen, grub_size_t dlen) grub_size_t slen, grub_size_t dlen)
@ -401,7 +362,6 @@ static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = {
{"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */ {"gzip-9", zlib_decompress}, /* ZIO_COMPRESS_GZIP9 */
{"zle", zle_decompress}, /* ZIO_COMPRESS_ZLE */ {"zle", zle_decompress}, /* ZIO_COMPRESS_ZLE */
{"lz4", lz4_decompress}, /* ZIO_COMPRESS_LZ4 */ {"lz4", lz4_decompress}, /* ZIO_COMPRESS_LZ4 */
{"zstd", zstd_decompress}, /* ZIO_COMPRESS_ZSTD */
}; };
static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, static grub_err_t zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian,
@ -654,8 +614,6 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist)
return grub_error (GRUB_ERR_BUG, "member drive unknown"); return grub_error (GRUB_ERR_BUG, "member drive unknown");
*nvlist = grub_malloc (VDEV_PHYS_SIZE); *nvlist = grub_malloc (VDEV_PHYS_SIZE);
if (!*nvlist)
return grub_errno;
/* Read in the vdev name-value pair list (112K). */ /* Read in the vdev name-value pair list (112K). */
err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0, err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0,
@ -765,13 +723,8 @@ fill_vdev_info_real (struct grub_zfs_data *data,
{ {
fill->n_children = nelm; fill->n_children = nelm;
fill->children = grub_calloc (fill->n_children, fill->children = grub_zalloc (fill->n_children
sizeof (fill->children[0])); * sizeof (fill->children[0]));
if (!fill->children)
{
grub_free (type);
return grub_errno;
}
} }
for (i = 0; i < nelm; i++) for (i = 0; i < nelm; i++)
@ -1057,10 +1010,8 @@ check_pool_label (struct grub_zfs_data *data,
ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0); ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0);
err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian, err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian,
nvlist, VDEV_PHYS_SIZE); nvlist, VDEV_PHYS_SIZE);
if (err) { if (err)
grub_free (nvlist);
return err; return err;
}
grub_dprintf ("zfs", "check 2 passed\n"); grub_dprintf ("zfs", "check 2 passed\n");
@ -1146,10 +1097,8 @@ check_pool_label (struct grub_zfs_data *data,
if (original) if (original)
data->guid = poolguid; data->guid = poolguid;
if (data->guid != poolguid) { if (data->guid != poolguid)
grub_free (nvlist);
return grub_error (GRUB_ERR_BAD_FS, "another zpool"); return grub_error (GRUB_ERR_BAD_FS, "another zpool");
}
{ {
char *nv; char *nv;
@ -1190,12 +1139,9 @@ check_pool_label (struct grub_zfs_data *data,
{ {
grub_dprintf("zfs","feature missing in check_pool_label:%s\n",name); grub_dprintf("zfs","feature missing in check_pool_label:%s\n",name);
err= grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET," check_pool_label missing feature '%s' for read",name); err= grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET," check_pool_label missing feature '%s' for read",name);
grub_free(features);
grub_free(nvlist);
return err; return err;
} }
} }
grub_free(features);
} }
grub_dprintf ("zfs", "check 12 passed (feature flags)\n"); grub_dprintf ("zfs", "check 12 passed (feature flags)\n");
grub_free (nvlist); grub_free (nvlist);
@ -2441,7 +2387,6 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
zap_dnode->endian) << DNODE_SHIFT); zap_dnode->endian) << DNODE_SHIFT);
grub_err_t err; grub_err_t err;
grub_zfs_endian_t endian; grub_zfs_endian_t endian;
grub_size_t sz;
if (zap_verify (zap, zap_dnode->endian)) if (zap_verify (zap, zap_dnode->endian))
return 0; return 0;
@ -2503,19 +2448,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
if (le->le_type != ZAP_CHUNK_ENTRY) if (le->le_type != ZAP_CHUNK_ENTRY)
continue; continue;
if (grub_mul (grub_zfs_to_cpu16 (le->le_name_length, endian), name_elem_length, &sz) || buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian)
grub_add (sz, 1, &sz)) * name_elem_length + 1);
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow"));
grub_free (l);
return grub_errno;
}
buf = grub_malloc (sz);
if (!buf)
{
grub_free (l);
return grub_errno;
}
if (zap_leaf_array_get (l, endian, blksft, if (zap_leaf_array_get (l, endian, blksft,
grub_zfs_to_cpu16 (le->le_name_chunk, grub_zfs_to_cpu16 (le->le_name_chunk,
endian), endian),
@ -2531,12 +2465,6 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
val_length = ((int) le->le_value_length val_length = ((int) le->le_value_length
* (int) le->le_int_size); * (int) le->le_int_size);
val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian)); val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian));
if (!val)
{
grub_free (l);
grub_free (buf);
return grub_errno;
}
if (zap_leaf_array_get (l, endian, blksft, if (zap_leaf_array_get (l, endian, blksft,
grub_zfs_to_cpu16 (le->le_value_chunk, grub_zfs_to_cpu16 (le->le_value_chunk,
endian), endian),
@ -2608,7 +2536,6 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
return err; return err;
} }
grub_free (zapbuf);
return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
} }
@ -2679,7 +2606,6 @@ zap_iterate_u64 (dnode_end_t * zap_dnode,
grub_free (zapbuf); grub_free (zapbuf);
return ret; return ret;
} }
grub_free (zapbuf);
grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
return 0; return 0;
} }
@ -2710,7 +2636,6 @@ zap_iterate (dnode_end_t * zap_dnode,
if (block_type == ZBT_MICRO) if (block_type == ZBT_MICRO)
{ {
grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected"); grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected");
grub_free (zapbuf);
return 0; return 0;
} }
if (block_type == ZBT_HEADER) if (block_type == ZBT_HEADER)
@ -2722,7 +2647,6 @@ zap_iterate (dnode_end_t * zap_dnode,
grub_free (zapbuf); grub_free (zapbuf);
return ret; return ret;
} }
grub_free (zapbuf);
grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type");
return 0; return 0;
} }
@ -2796,9 +2720,6 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
} }
grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE); grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE);
if (data->dnode_buf == 0)
/* dnbuf not used anymore if data->dnode_mdn malloc failed */
grub_free (dnbuf);
buf->endian = endian; buf->endian = endian;
if (type && buf->dn.dn_type != type) if (type && buf->dn.dn_type != type)
return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type");
@ -2951,7 +2872,6 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
&& ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) && ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
{ {
char *sym_value; char *sym_value;
grub_size_t sz;
grub_size_t sym_sz; grub_size_t sym_sz;
int free_symval = 0; int free_symval = 0;
char *oldpath = path, *oldpathbuf = path_buf; char *oldpath = path, *oldpathbuf = path_buf;
@ -3003,18 +2923,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
break; break;
free_symval = 1; free_symval = 1;
} }
path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
if (grub_add (sym_sz, grub_strlen (oldpath), &sz) ||
grub_add (sz, 1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("path buffer size overflow"));
grub_free (oldpathbuf);
if (free_symval)
grub_free (sym_value);
err = grub_errno;
break;
}
path = path_buf = grub_malloc (sz);
if (!path_buf) if (!path_buf)
{ {
grub_free (oldpathbuf); grub_free (oldpathbuf);
@ -3051,8 +2960,6 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
{ {
void *sahdrp; void *sahdrp;
int hdrsize; int hdrsize;
grub_size_t sz;
bool free_sahdrp = false;
if (dnode_path->dn.dn.dn_bonuslen != 0) if (dnode_path->dn.dn.dn_bonuslen != 0)
{ {
@ -3065,7 +2972,6 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data); err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data);
if (err) if (err)
break; break;
free_sahdrp = true;
} }
else else
{ {
@ -3087,15 +2993,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
+ SA_SIZE_OFFSET), + SA_SIZE_OFFSET),
dnode_path->dn.endian); dnode_path->dn.endian);
char *oldpath = path, *oldpathbuf = path_buf; char *oldpath = path, *oldpathbuf = path_buf;
if (grub_add (sym_sz, grub_strlen (oldpath), &sz) || path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
grub_add (sz, 1, &sz))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("path buffer size overflow"));
grub_free (oldpathbuf);
err = grub_errno;
break;
}
path = path_buf = grub_malloc (sz);
if (!path_buf) if (!path_buf)
{ {
grub_free (oldpathbuf); grub_free (oldpathbuf);
@ -3124,9 +3022,6 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
} }
dn_new = dnode_path; dn_new = dnode_path;
} }
if (free_sahdrp == true)
grub_free (sahdrp);
} }
} }
@ -3368,8 +3263,6 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
filename = 0; filename = 0;
snapname = 0; snapname = 0;
fsname = grub_strdup (fullpath); fsname = grub_strdup (fullpath);
if (!fsname)
return grub_errno;
} }
else else
{ {
@ -3455,8 +3348,6 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
if (err) if (err)
{ {
grub_dprintf ("zfs", "failed here\n"); grub_dprintf ("zfs", "failed here\n");
grub_free (fsname);
grub_free (snapname);
return err; return err;
} }
@ -3493,11 +3384,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
if (!err) if (!err)
err = dnode_get (&(data->mos), headobj, 0, err = dnode_get (&(data->mos), headobj, 0,
&subvol->mdn, data); &subvol->mdn, data);
if (!err && subvol->mdn.dn.dn_type != DMU_OT_DSL_DATASET && subvol->mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET) { if (!err && subvol->mdn.dn.dn_type != DMU_OT_DSL_DATASET && subvol->mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET)
grub_free (fsname);
grub_free (snapname);
return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type"); return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type");
}
if (err) if (err)
{ {
@ -3680,7 +3568,6 @@ grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name,
unsigned i; unsigned i;
grub_size_t nelm; grub_size_t nelm;
int elemsize = 0; int elemsize = 0;
int sz;
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair,
&size, &nelm); &size, &nelm);
@ -3715,12 +3602,7 @@ grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name,
return 0; return 0;
} }
if (grub_add (elemsize, sizeof (grub_uint32_t), &sz)) ret = grub_zalloc (elemsize + sizeof (grub_uint32_t));
{
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("elemsize overflow"));
return 0;
}
ret = grub_zalloc (sz);
if (!ret) if (!ret)
return 0; return 0;
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
@ -3796,13 +3678,8 @@ zfs_mount (grub_device_t dev)
#endif #endif
data->n_devices_allocated = 16; data->n_devices_allocated = 16;
data->devices_attached = grub_calloc (data->n_devices_allocated, data->devices_attached = grub_malloc (sizeof (data->devices_attached[0])
sizeof (data->devices_attached[0])); * data->n_devices_allocated);
if (!data->devices_attached)
{
grub_free (data);
return NULL;
}
data->n_devices_attached = 0; data->n_devices_attached = 0;
err = scan_disk (dev, data, 1, &inserted); err = scan_disk (dev, data, 1, &inserted);
if (err) if (err)
@ -3976,7 +3853,6 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
{ {
void *sahdrp; void *sahdrp;
int hdrsize; int hdrsize;
bool free_sahdrp = false;
if (data->dnode.dn.dn_bonuslen != 0) if (data->dnode.dn.dn_bonuslen != 0)
{ {
@ -3989,7 +3865,6 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data); err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data);
if (err) if (err)
return err; return err;
free_sahdrp = true;
} }
else else
{ {
@ -3998,8 +3873,6 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian);
if (free_sahdrp)
grub_free(sahdrp);
} }
else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE) else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE)
{ {
@ -4185,7 +4058,6 @@ fill_fs_info (struct grub_dirhook_info *info,
{ {
void *sahdrp; void *sahdrp;
int hdrsize; int hdrsize;
bool free_sahdrp = false;
if (dn.dn.dn_bonuslen != 0) if (dn.dn.dn_bonuslen != 0)
{ {
@ -4198,7 +4070,6 @@ fill_fs_info (struct grub_dirhook_info *info,
err = zio_read (bp, dn.endian, &sahdrp, NULL, data); err = zio_read (bp, dn.endian, &sahdrp, NULL, data);
if (err) if (err)
return err; return err;
free_sahdrp = true;
} }
else else
{ {
@ -4209,8 +4080,6 @@ fill_fs_info (struct grub_dirhook_info *info,
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
info->mtimeset = 1; info->mtimeset = 1;
info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
if (free_sahdrp)
grub_free (sahdrp);
} }
if (dn.dn.dn_bonustype == DMU_OT_ZNODE) if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
@ -4242,7 +4111,6 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx)
{ {
void *sahdrp; void *sahdrp;
int hdrsize; int hdrsize;
bool free_sahdrp = false;
if (dn.dn.dn_bonuslen != 0) if (dn.dn.dn_bonuslen != 0)
{ {
@ -4258,7 +4126,6 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx)
grub_print_error (); grub_print_error ();
return 0; return 0;
} }
free_sahdrp = true;
} }
else else
{ {
@ -4271,8 +4138,6 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx)
info.mtimeset = 1; info.mtimeset = 1;
info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian);
info.case_insensitive = ctx->data->subvol.case_insensitive; info.case_insensitive = ctx->data->subvol.case_insensitive;
if (free_sahdrp)
grub_free (sahdrp);
} }
if (dn.dn.dn_bonustype == DMU_OT_ZNODE) if (dn.dn.dn_bonustype == DMU_OT_ZNODE)
@ -4328,7 +4193,6 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
struct grub_dirhook_info info; struct grub_dirhook_info info;
char *name2; char *name2;
int ret; int ret;
grub_size_t sz;
dnode_end_t mdn; dnode_end_t mdn;
@ -4349,13 +4213,7 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
return 0; return 0;
} }
if (grub_add (grub_strlen (name), 2, &sz)) name2 = grub_malloc (grub_strlen (name) + 2);
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
name2 = grub_malloc (sz);
if (!name2)
return grub_errno;
name2[0] = '@'; name2[0] = '@';
grub_memcpy (name2 + 1, name, grub_strlen (name) + 1); grub_memcpy (name2 + 1, name, grub_strlen (name) + 1);
ret = ctx->hook (name2, &info, ctx->hook_data); ret = ctx->hook (name2, &info, ctx->hook_data);
@ -4484,7 +4342,7 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru
dnode_end_t dn,mosmdn; dnode_end_t dn,mosmdn;
mzap_phys_t* mzp; mzap_phys_t* mzp;
grub_zfs_endian_t endianzap; grub_zfs_endian_t endianzap;
int size, ret; int size;
grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t)); grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t));
mosmdn.endian=endian; mosmdn.endian=endian;
errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT, errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT,
@ -4510,9 +4368,7 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru
return errnum; return errnum;
size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) << SPA_MINBLOCKSHIFT; size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) << SPA_MINBLOCKSHIFT;
ret = mzap_iterate (mzp,endianzap, size, check_feature,NULL); return mzap_iterate (mzp,endianzap, size, check_feature,NULL);
grub_free(mzp);
return ret;
} }
@ -4568,7 +4424,6 @@ static struct grub_fs grub_zfs_fs = {
GRUB_MOD_INIT (zfs) GRUB_MOD_INIT (zfs)
{ {
COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE); COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE);
grub_zfs_fs.mod = mod;
grub_fs_register (&grub_zfs_fs); grub_fs_register (&grub_zfs_fs);
#ifndef GRUB_UTIL #ifndef GRUB_UTIL
my_mod = mod; my_mod = mod;

View file

@ -379,17 +379,14 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
grub_device_close (dev); grub_device_close (dev);
if (err) { if (err)
grub_free (nvlist);
return err; return err;
}
poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME);
if (!poolname) if (!poolname)
{ {
if (!grub_errno) if (!grub_errno)
grub_error (GRUB_ERR_BAD_FS, "No poolname found"); grub_error (GRUB_ERR_BAD_FS, "No poolname found");
grub_free (nvlist);
return grub_errno; return grub_errno;
} }

View file

@ -10,7 +10,7 @@ gdb.prompt_hook = prompt_hook
class IsGrubLoaded (gdb.Function): class IsGrubLoaded (gdb.Function):
"""Return 1 if GRUB has been loaded in memory, otherwise 0. """Return 1 if GRUB has been loaded in memory, otherwise 0.
The heuristic used is checking if the first 4 bytes of the memory pointed The hueristic used is checking if the first 4 bytes of the memory pointed
to by the _start symbol are not 0. This is true for QEMU on the first run to by the _start symbol are not 0. This is true for QEMU on the first run
of GRUB. This may not be true on physical hardware, where memory is not of GRUB. This may not be true on physical hardware, where memory is not
necessarily cleared on soft reset. This may not also be true in QEMU on necessarily cleared on soft reset. This may not also be true in QEMU on

View file

@ -57,11 +57,8 @@ if test x@TARGET_APPLE_LINKER@ != x1; then
@TARGET_STRIP@ --strip-unneeded \ @TARGET_STRIP@ --strip-unneeded \
-K grub_mod_init -K grub_mod_fini \ -K grub_mod_init -K grub_mod_fini \
-K _grub_mod_init -K _grub_mod_fini \ -K _grub_mod_init -K _grub_mod_fini \
-R .note.GNU-stack \ -R .note.gnu.gold-version -R .note.GNU-stack \
-R .note.gnu.gold-version \
-R .note.gnu.property \
-R .gnu.build.attributes \ -R .gnu.build.attributes \
-R '.llvm*' \
-R .rel.gnu.build.attributes \ -R .rel.gnu.build.attributes \
-R .rela.gnu.build.attributes \ -R .rela.gnu.build.attributes \
-R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \ -R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \

View file

@ -35,7 +35,7 @@ BEGIN {
for (i = 3; i <= NF; i++) { for (i = 3; i <= NF; i++) {
modtab[$2] = modtab[$2] " " $i; modtab[$2] = modtab[$2] " " $i;
} }
} else if ($1 == "") {} #Skip empty lines }
else { else {
printf "error: %u: unrecognized input format\n", NR >"/dev/stderr"; printf "error: %u: unrecognized input format\n", NR >"/dev/stderr";
error++; error++;

View file

@ -26,7 +26,6 @@
#include <grub/file.h> #include <grub/file.h>
#include <grub/kernel.h> #include <grub/kernel.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -100,7 +99,6 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
char *translation; char *translation;
struct string_descriptor desc; struct string_descriptor desc;
grub_err_t err; grub_err_t err;
grub_size_t alloc_sz;
internal_position = (off + position * sizeof (desc)); internal_position = (off + position * sizeof (desc));
@ -111,10 +109,7 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
length = grub_cpu_to_le32 (desc.length); length = grub_cpu_to_le32 (desc.length);
offset = grub_cpu_to_le32 (desc.offset); offset = grub_cpu_to_le32 (desc.offset);
if (grub_add (length, 1, &alloc_sz)) translation = grub_malloc (length + 1);
return NULL;
translation = grub_malloc (alloc_sz);
if (!translation) if (!translation)
return NULL; return NULL;
@ -328,8 +323,8 @@ grub_mofile_open (struct grub_gettext_context *ctx,
for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log; for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log;
ctx->grub_gettext_max_log++); ctx->grub_gettext_max_log++);
ctx->grub_gettext_msg_list = grub_calloc (ctx->grub_gettext_max, ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max
sizeof (ctx->grub_gettext_msg_list[0])); * sizeof (ctx->grub_gettext_msg_list[0]));
if (!ctx->grub_gettext_msg_list) if (!ctx->grub_gettext_msg_list)
{ {
grub_file_close (fd); grub_file_close (fd);
@ -540,10 +535,6 @@ GRUB_MOD_INIT (gettext)
GRUB_MOD_FINI (gettext) GRUB_MOD_FINI (gettext)
{ {
grub_register_variable_hook ("locale_dir", NULL, NULL);
grub_register_variable_hook ("secondary_locale_dir", NULL, NULL);
grub_register_variable_hook ("lang", NULL, NULL);
grub_gettext_delete_list (&main_context); grub_gettext_delete_list (&main_context);
grub_gettext_delete_list (&secondary_context); grub_gettext_delete_list (&secondary_context);

View file

@ -553,18 +553,10 @@ init_terminal (grub_gfxmenu_view_t view)
static void static void
init_background (grub_gfxmenu_view_t view) init_background (grub_gfxmenu_view_t view)
{ {
struct grub_video_bitmap *scaled_bitmap;
/*
* You don't have to scale a raw image if it's not present. This prevents
* setting grub_errno and disrupting a command execution.
*/
if (view->raw_desktop_image == NULL)
return;
if (view->scaled_desktop_image) if (view->scaled_desktop_image)
return; return;
struct grub_video_bitmap *scaled_bitmap;
if (view->desktop_image_scale_method == if (view->desktop_image_scale_method ==
GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH) GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH)
grub_video_bitmap_create_scaled (&scaled_bitmap, grub_video_bitmap_create_scaled (&scaled_bitmap,

View file

@ -366,10 +366,6 @@ static int dbits = 6; /* bits in base distance lookup table */
lookup of seven bits, the EOB code will be found in that first lookup of seven bits, the EOB code will be found in that first
lookup, and so will not require that too many bits be pulled from lookup, and so will not require that too many bits be pulled from
the stream. the stream.
Note that NEEDBITS() can fail if the file is corrupt/truncated.
The GOTOFAILIFERROR, RETURNIFERROR and RETURN1IFERROR macros can
help.
*/ */
static ush mask_bits[] = static ush mask_bits[] =
@ -381,14 +377,10 @@ static ush mask_bits[] =
#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(gzio))<<k;k+=8;}} while (0) #define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(gzio))<<k;k+=8;}} while (0)
#define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0) #define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0)
#define RETURNIFERROR if (grub_errno != GRUB_ERR_NONE) return
#define RETURN1IFERROR if (grub_errno != GRUB_ERR_NONE) return 1
#define GOTOFAILIFERROR if (grub_errno != GRUB_ERR_NONE) goto fail
static int static int
get_byte (grub_gzio_t gzio) get_byte (grub_gzio_t gzio)
{ {
grub_ssize_t bytes_read;
if (gzio->mem_input) if (gzio->mem_input)
{ {
if (gzio->mem_input_off < gzio->mem_input_size) if (gzio->mem_input_off < gzio->mem_input_size)
@ -401,16 +393,7 @@ get_byte (grub_gzio_t gzio)
|| gzio->inbuf_d == INBUFSIZ)) || gzio->inbuf_d == INBUFSIZ))
{ {
gzio->inbuf_d = 0; gzio->inbuf_d = 0;
bytes_read = grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ); grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
/*
* Only trigger if we get 0 bytes. If we get negative bytes there should
* be an existing GRUB error code that we don't want to overwrite.
*/
if (bytes_read == 0)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "File is too short");
return 0;
}
} }
return gzio->inbuf[gzio->inbuf_d++]; return gzio->inbuf[gzio->inbuf_d++];
@ -524,7 +507,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
} }
/* Make a table of values in order of bit lengths */ /* Make a table of values in order of bit lengths */
grub_memset (v, N_MAX, sizeof (v)); grub_memset (v, N_MAX, ARRAY_SIZE (v));
p = b; p = b;
i = 0; i = 0;
do do
@ -701,7 +684,7 @@ inflate_codes_in_window (grub_gzio_t gzio)
return 1; return 1;
} }
NEEDBITS ((unsigned) gzio->bl); RETURN1IFERROR; NEEDBITS ((unsigned) gzio->bl);
if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16) if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16)
do do
{ {
@ -713,7 +696,7 @@ inflate_codes_in_window (grub_gzio_t gzio)
} }
DUMPBITS (t->b); DUMPBITS (t->b);
e -= 16; e -= 16;
NEEDBITS (e); RETURN1IFERROR; NEEDBITS (e);
} }
while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
DUMPBITS (t->b); DUMPBITS (t->b);
@ -735,7 +718,7 @@ inflate_codes_in_window (grub_gzio_t gzio)
} }
/* get length of block to copy */ /* get length of block to copy */
NEEDBITS (e); RETURN1IFERROR; NEEDBITS (e);
n = t->v.n + ((unsigned) b & mask_bits[e]); n = t->v.n + ((unsigned) b & mask_bits[e]);
DUMPBITS (e); DUMPBITS (e);
@ -746,7 +729,7 @@ inflate_codes_in_window (grub_gzio_t gzio)
} }
/* decode distance of block to copy */ /* decode distance of block to copy */
NEEDBITS ((unsigned) gzio->bd); RETURN1IFERROR; NEEDBITS ((unsigned) gzio->bd);
if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16) if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16)
do do
{ {
@ -758,12 +741,12 @@ inflate_codes_in_window (grub_gzio_t gzio)
} }
DUMPBITS (t->b); DUMPBITS (t->b);
e -= 16; e -= 16;
NEEDBITS (e); RETURN1IFERROR; NEEDBITS (e);
} }
while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e)
> 16); > 16);
DUMPBITS (t->b); DUMPBITS (t->b);
NEEDBITS (e); RETURN1IFERROR; NEEDBITS (e);
d = w - t->v.n - ((unsigned) b & mask_bits[e]); d = w - t->v.n - ((unsigned) b & mask_bits[e]);
DUMPBITS (e); DUMPBITS (e);
gzio->code_state++; gzio->code_state++;
@ -832,10 +815,10 @@ init_stored_block (grub_gzio_t gzio)
DUMPBITS (k & 7); DUMPBITS (k & 7);
/* get the length and its complement */ /* get the length and its complement */
NEEDBITS (16); RETURNIFERROR; NEEDBITS (16);
gzio->block_len = ((unsigned) b & 0xffff); gzio->block_len = ((unsigned) b & 0xffff);
DUMPBITS (16); DUMPBITS (16);
NEEDBITS (16); RETURNIFERROR; NEEDBITS (16);
if (gzio->block_len != (int) ((~b) & 0xffff)) if (gzio->block_len != (int) ((~b) & 0xffff))
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
"the length of a stored block does not match"); "the length of a stored block does not match");
@ -917,13 +900,13 @@ init_dynamic_block (grub_gzio_t gzio)
k = gzio->bk; k = gzio->bk;
/* read in table lengths */ /* read in table lengths */
NEEDBITS (5); RETURNIFERROR; NEEDBITS (5);
nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */
DUMPBITS (5); DUMPBITS (5);
NEEDBITS (5); RETURNIFERROR; NEEDBITS (5);
nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */
DUMPBITS (5); DUMPBITS (5);
NEEDBITS (4); RETURNIFERROR; NEEDBITS (4);
nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */
DUMPBITS (4); DUMPBITS (4);
if (nl > 286 || nd > 30) if (nl > 286 || nd > 30)
@ -935,7 +918,7 @@ init_dynamic_block (grub_gzio_t gzio)
/* read in bit-length-code lengths */ /* read in bit-length-code lengths */
for (j = 0; j < nb; j++) for (j = 0; j < nb; j++)
{ {
NEEDBITS (3); RETURNIFERROR; NEEDBITS (3);
ll[bitorder[j]] = (unsigned) b & 7; ll[bitorder[j]] = (unsigned) b & 7;
DUMPBITS (3); DUMPBITS (3);
} }
@ -964,7 +947,7 @@ init_dynamic_block (grub_gzio_t gzio)
while ((unsigned) i < n) while ((unsigned) i < n)
{ {
NEEDBITS ((unsigned) gzio->bl); GOTOFAILIFERROR; NEEDBITS ((unsigned) gzio->bl);
j = (gzio->td = gzio->tl + ((unsigned) b & m))->b; j = (gzio->td = gzio->tl + ((unsigned) b & m))->b;
DUMPBITS (j); DUMPBITS (j);
j = gzio->td->v.n; j = gzio->td->v.n;
@ -972,7 +955,7 @@ init_dynamic_block (grub_gzio_t gzio)
ll[i++] = l = j; /* save last length in l */ ll[i++] = l = j; /* save last length in l */
else if (j == 16) /* repeat last length 3 to 6 times */ else if (j == 16) /* repeat last length 3 to 6 times */
{ {
NEEDBITS (2); GOTOFAILIFERROR; NEEDBITS (2);
j = 3 + ((unsigned) b & 3); j = 3 + ((unsigned) b & 3);
DUMPBITS (2); DUMPBITS (2);
if ((unsigned) i + j > n) if ((unsigned) i + j > n)
@ -985,7 +968,7 @@ init_dynamic_block (grub_gzio_t gzio)
} }
else if (j == 17) /* 3 to 10 zero length codes */ else if (j == 17) /* 3 to 10 zero length codes */
{ {
NEEDBITS (3); GOTOFAILIFERROR; NEEDBITS (3);
j = 3 + ((unsigned) b & 7); j = 3 + ((unsigned) b & 7);
DUMPBITS (3); DUMPBITS (3);
if ((unsigned) i + j > n) if ((unsigned) i + j > n)
@ -1000,7 +983,7 @@ init_dynamic_block (grub_gzio_t gzio)
else else
/* j == 18: 11 to 138 zero length codes */ /* j == 18: 11 to 138 zero length codes */
{ {
NEEDBITS (7); GOTOFAILIFERROR; NEEDBITS (7);
j = 11 + ((unsigned) b & 0x7f); j = 11 + ((unsigned) b & 0x7f);
DUMPBITS (7); DUMPBITS (7);
if ((unsigned) i + j > n) if ((unsigned) i + j > n)
@ -1066,12 +1049,12 @@ get_new_block (grub_gzio_t gzio)
k = gzio->bk; k = gzio->bk;
/* read in last block bit */ /* read in last block bit */
NEEDBITS (1); RETURNIFERROR; NEEDBITS (1);
gzio->last_block = (int) b & 1; gzio->last_block = (int) b & 1;
DUMPBITS (1); DUMPBITS (1);
/* read in block type */ /* read in block type */
NEEDBITS (2); RETURNIFERROR; NEEDBITS (2);
gzio->block_type = (unsigned) b & 3; gzio->block_type = (unsigned) b & 3;
DUMPBITS (2); DUMPBITS (2);

View file

@ -75,7 +75,7 @@ grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig)
return 0; return 0;
ptr = (grub_unaligned_uint64_t *) (xsdt + 1); ptr = (grub_unaligned_uint64_t *) (xsdt + 1);
s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint64_t); s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t);
for (; s; s--, ptr++) for (; s; s--, ptr++)
{ {
struct grub_acpi_table_header *tbl; struct grub_acpi_table_header *tbl;

Some files were not shown because too many files have changed in this diff Show more