Commit Graph
44 Commits
Author SHA1 Message Date
Peter Jones 0dcbf3652b loader/linux: Avoid overflow on initrd size calculation
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:48 +02:00
Peter Jones d2cf823d0e efi: Fix some malformed device path arithmetic errors
Several places we take the length of a device path and subtract 4 from
it, without ever checking that it's >= 4. There are also cases where
this kind of malformation will result in unpredictable iteration,
including treating the length from one dp node as the type in the next
node. These are all errors, no matter where the data comes from.

This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
the length is too small. Additionally, it makes several places in the
code check for and return errors in these cases.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:48 +02:00
Peter Jones b73cee7f1f emu: Make grub_free(NULL) safe
The grub_free() implementation in grub-core/kern/mm.c safely handles
NULL pointers, and code at many places depends on this. We don't know
that the same is true on all host OSes, so we need to handle the same
behavior in grub-emu's implementation.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:48 +02:00
Peter Jones 879c4a8342 lvm: Fix two more potential data-dependent alloc overflows
It appears to be possible to make a (possibly invalid) lvm PV with
a metadata size field that overflows our type when adding it to the
address we've allocated. Even if it doesn't, it may be possible to do so
with the math using the outcome of that as an operand. Check them both.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:48 +02:00
Peter Jones f5703eb062 hfsplus: Fix two more overflows
Both node->size and node->namelen come from the supplied filesystem,
which may be user-supplied. We can't trust them for the math unless we
know they don't overflow. Making sure they go through grub_add() or
grub_calloc() first will give us that.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:48 +02:00
Peter Jones 2a1edcf2ed iso9660: Don't leak memory on realloc() failures
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:48 +02:00
Peter Jones 3f05d693d1 malloc: Use overflow checking primitives where we do complex allocations
This attempts to fix the places where we do the following where
arithmetic_expr may include unvalidated data:

  X = grub_malloc(arithmetic_expr);

It accomplishes this by doing the arithmetic ahead of time using grub_add(),
grub_sub(), grub_mul() and testing for overflow before proceeding.

Among other issues, this fixes:
  - allocation of integer overflow in grub_video_bitmap_create()
    reported by Chris Coulson,
  - allocation of integer overflow in grub_png_decode_image_header()
    reported by Chris Coulson,
  - allocation of integer overflow in grub_squash_read_symlink()
    reported by Chris Coulson,
  - allocation of integer overflow in grub_ext2_read_symlink()
    reported by Chris Coulson,
  - allocation of integer overflow in read_section_as_string()
    reported by Chris Coulson.

Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:47 +02:00
Peter Jones f725fa7cb2 calloc: Use calloc() at most places
This modifies most of the places we do some form of:

  X = malloc(Y * Z);

to use calloc(Y, Z) instead.

Among other issues, this fixes:
  - allocation of integer overflow in grub_png_decode_image_header()
    reported by Chris Coulson,
  - allocation of integer overflow in luks_recover_key()
    reported by Chris Coulson,
  - allocation of integer overflow in grub_lvm_detect()
    reported by Chris Coulson.

Fixes: CVE-2020-14308

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:47 +02:00
Peter Jones 64e26162eb calloc: Make sure we always have an overflow-checking calloc() available
This tries to make sure that everywhere in this source tree, we always have
an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.)
available, and that they all safely check for overflow and return NULL when
it would occur.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:47 +02:00
Peter Jones 68708c4503 safemath: Add some arithmetic primitives that check for overflow
This adds a new header, include/grub/safemath.h, that includes easy to
use wrappers for __builtin_{add,sub,mul}_overflow() declared like:

  bool OP(a, b, res)

where OP is grub_add, grub_sub or grub_mul. OP() returns true in the
case where the operation would overflow and res is not modified.
Otherwise, false is returned and the operation is executed.

These arithmetic primitives require newer compiler versions. So, bump
these requirements in the INSTALL file too.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:47 +02:00
Peter Jones a4d3fbdff1 yylex: Make lexer fatal errors actually be fatal
When presented with a command that can't be tokenized to anything
smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg),
expecting that will stop further processing, as such:

  #define YY_DO_BEFORE_ACTION \
        yyg->yytext_ptr = yy_bp; \
        yyleng = (int) (yy_cp - yy_bp); \
        yyg->yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
        if ( yyleng >= YYLMAX ) \
                YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
        yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \
        yyg->yy_c_buf_p = yy_cp;

The code flex generates expects that YY_FATAL_ERROR() will either return
for it or do some form of longjmp(), or handle the error in some way at
least, and so the strncpy() call isn't in an "else" clause, and thus if
YY_FATAL_ERROR() is *not* actually fatal, it does the call with the
questionable limit, and predictable results ensue.

Unfortunately, our implementation of YY_FATAL_ERROR() is:

   #define YY_FATAL_ERROR(msg)                     \
     do {                                          \
       grub_printf (_("fatal error: %s\n"), _(msg));     \
     } while (0)

The same pattern exists in yyless(), and similar problems exist in users
of YY_INPUT(), several places in the main parsing loop,
yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack,
yy_scan_buffer(), etc.

All of these callers expect YY_FATAL_ERROR() to actually be fatal, and
the things they do if it returns after calling it are wildly unsafe.

Fixes: CVE-2020-10713

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-07-29 16:55:47 +02:00
Peter Jones 9b89b1dedb efi: Fix the type of grub_efi_status_t
Currently, in some builds with some checkers, we see:

1. grub-core/disk/efi/efidisk.c:601: error[shiftTooManyBitsSigned]: Shifting signed 64-bit value by 63 bits is undefined behaviour

This is because grub_efi_status_t is defined as grub_efi_intn_t, which is
signed, and shifting into the sign bit is not defined behavior.  UEFI fixed
this in the spec in 2.3:

2.3 | Change the defined type of EFI_STATUS from INTN to UINTN | May 7, 2009

And the current EDK2 code has:
MdePkg/Include/Base.h-//
MdePkg/Include/Base.h-// Status codes common to all execution phases
MdePkg/Include/Base.h-//
MdePkg/Include/Base.h:typedef UINTN RETURN_STATUS;
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-/**
MdePkg/Include/Base.h-  Produces a RETURN_STATUS code with the highest bit set.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  @param  StatusCode    The status code value to convert into a warning code.
MdePkg/Include/Base.h-                        StatusCode must be in the range 0x00000000..0x7FFFFFFF.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  @return The value specified by StatusCode with the highest bit set.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-**/
MdePkg/Include/Base.h-#define ENCODE_ERROR(StatusCode)     ((RETURN_STATUS)(MAX_BIT | (StatusCode)))
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-/**
MdePkg/Include/Base.h-  Produces a RETURN_STATUS code with the highest bit clear.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  @param  StatusCode    The status code value to convert into a warning code.
MdePkg/Include/Base.h-                        StatusCode must be in the range 0x00000000..0x7FFFFFFF.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  @return The value specified by StatusCode with the highest bit clear.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-**/
MdePkg/Include/Base.h-#define ENCODE_WARNING(StatusCode)   ((RETURN_STATUS)(StatusCode))
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-/**
MdePkg/Include/Base.h-  Returns TRUE if a specified RETURN_STATUS code is an error code.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  This function returns TRUE if StatusCode has the high bit set.  Otherwise, FALSE is returned.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  @param  StatusCode    The status code value to evaluate.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-  @retval TRUE          The high bit of StatusCode is set.
MdePkg/Include/Base.h-  @retval FALSE         The high bit of StatusCode is clear.
MdePkg/Include/Base.h-
MdePkg/Include/Base.h-**/
MdePkg/Include/Base.h-#define RETURN_ERROR(StatusCode)     (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
...
Uefi/UefiBaseType.h:typedef RETURN_STATUS             EFI_STATUS;

This patch makes grub's implementation match the Edk2 declaration with regards
to the signedness of the type.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:42:31 +01:00
Peter Jones 3e8c338bfa efi/gop: Add debug output on GOP probing
Add debug information to EFI GOP video driver probing function.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:42:13 +01:00
Peter Jones c73cda3495 efi/uga: Use video instead of fb as debug condition
All other video drivers use "video" as the debug condition instead of "fb"
so change this in the efi/uga driver to make it consistent with the others.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:41:38 +01:00
Peter Jones df84d6e94c efi: Print error messages to grub_efi_allocate_pages_real()
No messages were printed in this function, add some to ease debugging.

Also, the function returns a void * pointer so return NULL instead of
0 to make the code more readable.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:41:16 +01:00
Peter Jones f0f97576e0 normal/completion: Fix possible NULL pointer dereference
Coverity Scan reports that the grub_strrchr() function can return NULL if
the character is not found. Check if that's the case for dirfile pointer.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:40:23 +01:00
Peter Jones 8d88ae92b5 kern: Add grub_debug_enabled()
Add a grub_debug_enabled() helper function instead of open coding it.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:40:06 +01:00
Peter Jones 42f4054faf Makefile: Make libgrub.pp depend on config-util.h
If you build with "make -j48" a lot, sometimes you see:

gcc -E -DHAVE_CONFIG_H -I. -I..  -Wall -W -DGRUB_UTIL=1 -D_FILE_OFFSET_BITS=64 -I./include -DGRUB_FILE=\"grub_script.tab.h\" -I. -I.. -I. -I.. -I../include -I./include -I../grub-core/lib/libgcrypt-grub/src/  -I../grub-core/lib/minilzo -I../grub-core/lib/xzembed -DMINILZO_HAVE_CONFIG_H -Wall -W -DGRUB_UTIL=1 -D_FILE_OFFSET_BITS=64 -I./include -DGRUB_FILE=\"grub_script.tab.h\" -I. -I.. -I. -I.. -I../include -I./include -I../grub-core/lib/libgcrypt-grub/src/  -I./grub-core/gnulib -I../grub-core/gnulib -I/builddir/build/BUILD/grub-2.02/grub-aarch64-efi-2.02 -D_FILE_OFFSET_BITS=64 \
  -D'GRUB_MOD_INIT(x)=@MARKER@x@' grub_script.tab.h grub_script.yy.h ../grub-core/commands/blocklist.c ../grub-core/commands/macbless.c ../grub-core/commands/xnu_uuid.c ../grub-core/commands/testload.c ../grub-core/commands/ls.c ../grub-core/disk/dmraid_nvidia.c ../grub-core/disk/loopback.c ../grub-core/disk/lvm.c ../grub-core/disk/mdraid_linux.c ../grub-core/disk/mdraid_linux_be.c ../grub-core/disk/mdraid1x_linux.c ../grub-core/disk/raid5_recover.c ../grub-core/disk/raid6_recover.c ../grub-core/font/font.c ../grub-core/gfxmenu/font.c ../grub-core/normal/charset.c ../grub-core/video/fb/fbblit.c ../grub-core/video/fb/fbutil.c ../grub-core/video/fb/fbfill.c ../grub-core/video/fb/video_fb.c ../grub-core/video/video.c ../grub-core/video/capture.c ../grub-core/video/colors.c ../grub-core/unidata.c ../grub-core/io/bufio.c ../grub-core/fs/affs.c ../grub-core/fs/afs.c ../grub-core/fs/bfs.c ../grub-core/fs/btrfs.c ../grub-core/fs/cbfs.c ../grub-core/fs/cpio.c ../grub-core/fs/cpio_be.c ../grub-core/fs/odc.c ../grub-core/fs/newc.c ../grub-core/fs/ext2.c ../grub-core/fs/fat.c ../grub-core/fs/exfat.c ../grub-core/fs/fshelp.c ../grub-core/fs/hfs.c ../grub-core/fs/hfsplus.c ../grub-core/fs/hfspluscomp.c ../grub-core/fs/iso9660.c ../grub-core/fs/jfs.c ../grub-core/fs/minix.c ../grub-core/fs/minix2.c ../grub-core/fs/minix3.c ../grub-core/fs/minix_be.c ../grub-core/fs/minix2_be.c ../grub-core/fs/minix3_be.c ../grub-core/fs/nilfs2.c ../grub-core/fs/ntfs.c ../grub-core/fs/ntfscomp.c ../grub-core/fs/reiserfs.c ../grub-core/fs/romfs.c ../grub-core/fs/sfs.c ../grub-core/fs/squash4.c ../grub-core/fs/tar.c ../grub-core/fs/udf.c ../grub-core/fs/ufs2.c ../grub-core/fs/ufs.c ../grub-core/fs/ufs_be.c ../grub-core/fs/xfs.c ../grub-core/fs/zfs/zfscrypt.c ../grub-core/fs/zfs/zfs.c ../grub-core/fs/zfs/zfsinfo.c ../grub-core/fs/zfs/zfs_lzjb.c ../grub-core/fs/zfs/zfs_lz4.c ../grub-core/fs/zfs/zfs_sha256.c ../grub-core/fs/zfs/zfs_fletcher.c ../grub-core/lib/envblk.c ../grub-core/lib/hexdump.c ../grub-core/lib/LzFind.c ../grub-core/lib/LzmaEnc.c ../grub-core/lib/crc.c ../grub-core/lib/adler32.c ../grub-core/lib/crc64.c ../grub-core/normal/datetime.c ../grub-core/normal/misc.c ../grub-core/partmap/acorn.c ../grub-core/partmap/amiga.c ../grub-core/partmap/apple.c ../grub-core/partmap/sun.c ../grub-core/partmap/plan.c ../grub-core/partmap/dvh.c ../grub-core/partmap/sunpc.c ../grub-core/partmap/bsdlabel.c ../grub-core/partmap/dfly.c ../grub-core/script/function.c ../grub-core/script/lexer.c ../grub-core/script/main.c ../grub-core/script/script.c ../grub-core/script/argv.c ../grub-core/io/gzio.c ../grub-core/io/xzio.c ../grub-core/io/lzopio.c ../grub-core/kern/ia64/dl_helper.c ../grub-core/kern/arm/dl_helper.c ../grub-core/kern/arm64/dl_helper.c ../grub-core/lib/minilzo/minilzo.c ../grub-core/lib/xzembed/xz_dec_bcj.c ../grub-core/lib/xzembed/xz_dec_lzma2.c ../grub-core/lib/xzembed/xz_dec_stream.c ../util/misc.c ../grub-core/kern/command.c ../grub-core/kern/device.c ../grub-core/kern/disk.c ../grub-core/lib/disk.c ../util/getroot.c ../grub-core/osdep/unix/getroot.c ../grub-core/osdep/getroot.c ../grub-core/osdep/devmapper/getroot.c ../grub-core/osdep/relpath.c ../grub-core/kern/emu/hostdisk.c ../grub-core/osdep/devmapper/hostdisk.c ../grub-core/osdep/hostdisk.c ../grub-core/osdep/unix/hostdisk.c ../grub-core/osdep/exec.c ../grub-core/osdep/sleep.c ../grub-core/osdep/password.c ../grub-core/kern/emu/misc.c ../grub-core/kern/emu/mm.c ../grub-core/kern/env.c ../grub-core/kern/err.c ../grub-core/kern/file.c ../grub-core/kern/fs.c ../grub-core/kern/list.c ../grub-core/kern/misc.c ../grub-core/kern/partition.c ../grub-core/lib/crypto.c ../grub-core/disk/luks.c ../grub-core/disk/geli.c ../grub-core/disk/cryptodisk.c ../grub-core/disk/AFSplitter.c ../grub-core/lib/pbkdf2.c ../grub-core/commands/extcmd.c ../grub-core/lib/arg.c ../grub-core/disk/ldm.c ../grub-core/disk/diskfilter.c ../grub-core/partmap/gpt.c ../grub-core/partmap/msdos.c ../grub-core/fs/proc.c ../grub-core/fs/archelp.c > libgrub.pp || (rm -f libgrub.pp; exit 1)
rm -f stamp-h1
touch ../config-util.h.in
cd . && /bin/sh ./config.status config-util.h
config.status: creating config-util.h
In file included from ../include/grub/mm.h:25:0,
                 from ../include/grub/disk.h:29,
                 from ../include/grub/file.h:26,
                 from ../grub-core/fs/btrfs.c:21:
./config.h:38:10: fatal error: ./config-util.h: No such file or directory
 #include <config-util.h>
          ^~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:13098: libgrub.pp] Error 1

This is because libgrub.pp is built with -DGRUB_UTIL=1, which means
it'll try to include config-util.h, but a parallel make is actually
building that file.  I think.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:39:53 +01:00
Peter Jones cc93c5a849 efi: Print more debug info in our module loader
The function that searches the mods section base address does not have
any debug information. Add some debugging outputs that could be useful.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:39:44 +01:00
Peter Jones ea04f131a4 linux/getroot: Handle rssd storage device names
The Micron PCIe SSDs Linux driver (mtip32xx) exposes block devices
as /dev/rssd[a-z]+[0-9]*. Add support for these rssd device names.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-03-10 21:39:34 +01:00
Peter Jones d5a32255de misc: Make grub_strtol() "end" pointers have safer const qualifiers
Currently the string functions grub_strtol(), grub_strtoul(), and
grub_strtoull() don't declare the "end" pointer in such a way as to
require the pointer itself or the character array to be immutable to the
implementation, nor does the C standard do so in its similar functions,
though it does require us not to change any of it.

The typical declarations of these functions follow this pattern:

long
strtol(const char * restrict nptr, char ** restrict endptr, int base);

Much of the reason for this is historic, and a discussion of that
follows below, after the explanation of this change.  (GRUB currently
does not include the "restrict" qualifiers, and we name the arguments a
bit differently.)

The implementation is semantically required to treat the character array
as immutable, but such accidental modifications aren't stopped by the
compiler, and the semantics for both the callers and the implementation
of these functions are sometimes also helped by adding that requirement.

This patch changes these declarations to follow this pattern instead:

long
strtol(const char * restrict nptr,
       const char ** const restrict endptr,
       int base);

This means that if any modification to these functions accidentally
introduces either an errant modification to the underlying character
array, or an accidental assignment to endptr rather than *endptr, the
compiler should generate an error.  (The two uses of "restrict" in this
case basically mean strtol() isn't allowed to modify the character array
by going through *endptr, and endptr isn't allowed to point inside the
array.)

It also means the typical use case changes to:

  char *s = ...;
  const char *end;
  long l;

  l = strtol(s, &end, 10);

Or even:

  const char *p = str;
  while (p && *p) {
	  long l = strtol(p, &p, 10);
	  ...
  }

This fixes 26 places where we discard our attempts at treating the data
safely by doing:

  const char *p = str;
  long l;

  l = strtol(p, (char **)&ptr, 10);

It also adds 5 places where we do:

  char *p = str;
  while (p && *p) {
	  long l = strtol(p, (const char ** const)&p, 10);
	  ...
	  /* more calls that need p not to be pointer-to-const */
  }

While moderately distasteful, this is a better problem to have.

With one minor exception, I have tested that all of this compiles
without relevant warnings or errors, and that /much/ of it behaves
correctly, with gcc 9 using 'gcc -W -Wall -Wextra'.  The one exception
is the changes in grub-core/osdep/aros/hostdisk.c , which I have no idea
how to build.

Because the C standard defined type-qualifiers in a way that can be
confusing, in the past there's been a slow but fairly regular stream of
churn within our patches, which add and remove the const qualifier in many
of the users of these functions.  This change should help avoid that in
the future, and in order to help ensure this, I've added an explanation
in misc.h so that when someone does get a compiler warning about a type
error, they have the fix at hand.

The reason we don't have "const" in these calls in the standard is
purely anachronistic: C78 (de facto) did not have type qualifiers in the
syntax, and the "const" type qualifier was added for C89 (I think; it
may have been later).  strtol() appears to date from 4.3BSD in 1986,
which means it could not be added to those functions in the standard
without breaking compatibility, which is usually avoided.

The syntax chosen for type qualifiers is what has led to the churn
regarding usage of const, and is especially confusing on string
functions due to the lack of a string type.  Quoting from C99, the
syntax is:

 declarator:
  pointer[opt] direct-declarator
 direct-declarator:
  identifier
  ( declarator )
  direct-declarator [ type-qualifier-list[opt] assignment-expression[opt] ]
  ...
  direct-declarator [ type-qualifier-list[opt] * ]
  ...
 pointer:
  * type-qualifier-list[opt]
  * type-qualifier-list[opt] pointer
 type-qualifier-list:
  type-qualifier
  type-qualifier-list type-qualifier
 ...
 type-qualifier:
  const
  restrict
  volatile

So the examples go like:

const char foo;			// immutable object
const char *foo;		// mutable pointer to object
char * const foo;		// immutable pointer to mutable object
const char * const foo;		// immutable pointer to immutable object
const char const * const foo; 	// XXX extra const keyword in the middle
const char * const * const foo; // immutable pointer to immutable
				//   pointer to immutable object
const char ** const foo;	// immutable pointer to mutable pointer
				//   to immutable object

Making const left-associative for * and right-associative for everything
else may not have been the best choice ever, but here we are, and the
inevitable result is people using trying to use const (as they should!),
putting it at the wrong place, fighting with the compiler for a bit, and
then either removing it or typecasting something in a bad way.  I won't
go into describing restrict, but its syntax has exactly the same issue
as with const.

Anyway, the last example above actually represents the *behavior* that's
required of strtol()-like functions, so that's our choice for the "end"
pointer.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-02-28 12:41:29 +01:00
Peter Jones 0ad07e928a grub-editenv: Make grub-editenv chase symlinks including those across devices
The grub-editenv create command will wrongly overwrite /boot/grub2/grubenv
with a regular file if grubenv is a symbolic link. But instead, it should
create a new file in the path the symlink points to.

This lets /boot/grub2/grubenv be a symlink to /boot/efi/EFI/fedora/grubenv
even when they're different mount points, which allows grub2-editenv to be
the same across platforms (i.e. UEFI vs BIOS).

For example, in Fedora the GRUB EFI builds have prefix set to /EFI/fedora
(on the EFI System Partition), but for BIOS machine it'll be /boot/grub2
(which may or may not be its own mountpoint).

With this patch, on EFI machines we can make /boot/grub2/grubenv a symlink
to /boot/efi/EFI/fedora/grubenv, and the same copy of grub-set-default will
work on both kinds of systems.

Windows doesn't implement a readlink primitive, so the current behaviour is
maintained for this operating system.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Jonathan Lebon <jlebon@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-02-18 15:16:02 +01:00
Peter Jones 03e72830ab grub-editenv: Add grub_util_readlink()
Currently grub-editenv and related tools are not able to follow symbolic
links when finding their config file. For example the grub-editenv create
command will wrongly overwrite a symlink in /boot/grub2/grubenv with a new
regular file, instead of creating a file in the path the symlink points to.

A following patch will change that and add support in grub-editenv to
follow symbolic links when finding the grub environment variables file.

Add a grub_util_readlink() helper function that is just a wrapper around
the platform specific function to read the value of a symbolic link. This
helper function will be used by the following patch for grub-editenv.

The helper function is not added for Windows, since this operating system
doesn't have a primitive to read the contents of a symbolic link.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-02-18 15:14:13 +01:00
Peter Jones 3165efcfc2 minilzo: Update to minilzo-2.08
This patch updates the miniLZO library to a newer version, which among other
things fixes "CVE-2014-4607 - lzo: lzo1x_decompress_safe() integer overflow"
that is present in the current used in GRUB.

It also updates the "GRUB Developers Manual", to mention that the library is
used and describes the process to update it to a newer release when needed.

Resolves: http://savannah.gnu.org/bugs/?42635

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-02-11 21:30:30 +01:00
Peter Jones 598de14d93 squash4: Fix an uninitialized variable
gcc says:

grub-core/fs/squash4.c: In function ‘direct_read’:
grub-core/fs/squash4.c:868:10: error: ‘err’ may be used uninitialized in
this function [-Werror=maybe-uninitialized]
  868 |       if (err)
      |          ^
cc1: all warnings being treated as errors

This patch initializes it to GRUB_ERR_NONE.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2020-01-28 21:22:01 +01:00
Peter Jones b78d570a36 templates: Add GRUB_DISABLE_UUID
The grub-mkconfig and 10_linux scripts by default attempt to use a UUID to
set the root kernel command line parameter and the $root GRUB environment
variable.

The former can be disabled by setting the GRUB_DISABLE_LINUX_UUID variable
to "true", but there is currently no way to disable the latter.

The generated grub config uses the search command with the --fs-uuid option
to find the device that has to be set as $root, i.e:

 search --no-floppy --fs-uuid --set=root ...

This is usually more reliable but in some cases it may not be appropriate,
so this patch introduces a new GRUB_DISABLE_UUID variable that can be used
to disable searching for the $root device by filesystem UUID.

When disabled, the $root device will be set to the value specified in the
device.map as found by the grub-probe --target=compatibility_hint option.

When setting GRUB_DISABLE_UUID=true, the GRUB_DISABLE_LINUX_UUID and
GRUB_DISABLE_LINUX_PARTUUID variables will also be set to "true" unless
these have been explicitly set to "false".

That way, the GRUB_DISABLE_UUID variable can be used to force using the
device names for both GRUB and Linux.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Nicholas Vinson <nvinson234@gmail.com>
2019-10-28 15:35:40 +01:00
Peter Jones f9e28d250a gitattributes: Mark po/exclude.pot as binary so git won't try to diff nonprintables
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2019-09-23 13:17:15 +02:00
Peter Jones 8317c9eab9 grub-module-verifier: Report the filename or modname in errors
Make it so that when grub-module-verifier complains of an issue, it tells you
which module the issue was with.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-09-12 13:24:36 +02:00
Peter Jones a6c83d4a20 configure: Fix an 8 year old typo
Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-09-12 13:14:39 +02:00
Peter Jones 413f1e13e6 .mod files: Strip annobin annotations and .eh_frame, and their relocations
This way debuginfo built from the .module will still include this
information, but the final result won't have the data we don't actually
need in the modules, either on-disk, loaded at runtime, or in prebuilt
images.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 14:08:22 +01:00
Peter Jones ebc825b549 mkimage: avoid copying relocations for sections that won't be copied.
Some versions of gcc include a plugin called "annobin", and in some
build systems this is enabled by default.  This plugin creates special
ELF note sections to track which ABI-breaking features are used by a
binary, as well as a series of relocations to annotate where.

If grub is compiled with this feature, then when grub-mkimage translates
the binary to another file format which does not strongly associate
relocation data with sections (i.e. when platform is *-efi), these
relocations appear to be against the .text section rather than the
original note section.  When the binary is loaded by the PE runtime
loader, hilarity ensues.

This issue is not necessarily limited to the annobin, but could arise
any time there are relocations in sections that are not represented in
grub-mkimage's output.

This patch seeks to avoid this issue by only including relocations that
refer to sections which will be included in the final binary.

As an aside, this should also obviate the need to avoid -funwind-tables,
-fasynchronous-unwind-tables, and any sections similar to .eh_frame in
the future.  I've tested it on x86-64-efi with the following gcc command
line options (as recorded by -grecord-gcc-flags), but I still need to
test the result on some other platforms that have been problematic in
the past (especially ARM Aarch64) before I feel comfortable making
changes to the configure.ac bits:

GNU C11 7.2.1 20180116 (Red Hat 7.2.1-7) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -mno-stack-arg-probe -mcmodel=large -mno-red-zone -m64 -mtune=generic -march=x86-64 -g3 -Os -freg-struct-return -fno-stack-protector -ffreestanding -funwind-tables -fasynchronous-unwind-tables -fno-strict-aliasing -fstack-clash-protection -fno-ident -fplugin=annobin

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 14:08:09 +01:00
Peter Jones 7542af695f mkimage: refactor a bunch of section data into a struct.
This basically moves a bunch of the section information we pass around a
lot into a struct, and passes a pointer to a single one of those
instead.

This shouldn't change the binary file output or the "grub-mkimage -v"
output in any way.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 14:05:35 +01:00
Peter Jones e30de94926 mkimage: make locate_sections() set up vaddresses as well.
This puts both kinds of address initialization at the same place, and also lets
us iterate through the section list one time fewer.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 13:44:55 +01:00
Peter Jones 594ac31571 mkimage: rename a couple of things to be less confusing later.
This renames some things:

- the "strtab" and "strtab_section" in relocate_symbols are changed to "symtab"
  instead, so as to be less confusing when "strtab" is moved to a struct in a
  later patch.

- The places where we pass section_vaddresses to functions are changed to also
  be called section_vaddresses"inside those functions, so I get less confused
  when I put addresses and vaddresses in a struct in a later patch.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 13:44:55 +01:00
Peter Jones 352868d123 mkimage: make it easier to run syntax checkers on grub-mkimagexx.c
This makes it so you can treat grub-mkimagexx.c as a file you can build
directly, so syntax checkers like vim's "syntastic" plugin, which uses
"gcc -x c -fsyntax-only" to build it, will work.

One still has to do whatever setup is required to make it pick the right
include dirs, which -W options we use, etc., but this makes it so you
can do the checking on the file you're editing, rather than on a
different file.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 13:44:55 +01:00
Peter Jones e1ead149ef aout.h: Fix missing include.
grub_aout_load() has a grub_file_t parameter, and depending on what order
includes land in, it's sometimes not defined.  This patch explicitly adds
file.h to aout.h so that it will always be defined.

Signed-off-by: Peter Jones <pjones@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2018-03-05 13:44:55 +01:00
Peter Jones 9e5f70174e Use EFI_SIMPLE_TEXT_INPUT_EX to support key combinations. 2015-10-25 16:36:28 +01:00
Peter Jones 631a820038 Initialized initrd_ctx so we don't free a random pointer from the stack.
Currently, if "linux" fails, the "goto fail;" in grub_cmd_initrd sends us
into grub_initrd_close() without grub_initrd_init() being called, and thus
it never clears initrd_ctx->components.  grub_initrd_close() then frees that
address, which is stale data from the stack.  If the stack happens to have a
stale *address* there that matches a recent allocation, then you'll get a
double free later.

So initialize the memory up front.

Signed-off-by: Peter Jones <pjones@redhat.com>
2014-09-21 10:36:42 +04:00
Peter Jones a7e03923fa * grub-core/disk/efi/efidisk.c: Limit disk read or write chunk to 0x500
sectors.
	Based on patch by Peter Jones.
2013-04-15 09:12:14 +02:00
Peter Jones efe0cddae8 * grub-core/disk/efi/efidisk.c: Handle partitions on non-512B disks.
Also-By: Vladimir Serbinenko <phcoder@gmail.com>
2013-04-04 10:35:50 +02:00
Peter Jones c5052c81ab * grub-core/Makefile.core.def (efifwsetup): New module.
* grub-core/commands/efi/efifwsetup.c: New file.
	* grub-core/kern/efi/efi.c (grub_efi_set_variable): New function
	* include/grub/efi/api.h (GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI):
	New define.
	* include/grub/efi/efi.h (grub_efi_set_variable): New proto.
2012-09-08 09:40:24 +02:00
Peter Jones bcc75fb3f7 * include/grub/i386/linux.h (linux_kernel_params): Add v206.
* grub-core/loader/i386/linux.c (grub_linux_boot): Use v206.
	(grub_cmd_linux) [__x86_64__]: Validate grub_efi_system_table.
2012-05-31 13:23:30 +02:00
Peter Jones 2787ae53d6 The old code gives arguments to a printf function which can't work
correctly, and the compiler complains.

	* grub-core/tests/example_functional_test.c (example_test): Add
	missing text.
	* grub-core/tests/lib/test.c (add_failure): Rewrite.
	* include/grub/test.h (grub_test_assert_helper): New declaration.
	(grub_test_assert): Use grub_test_assert_helper.
2012-05-27 14:26:18 +02:00
Peter Jones bae7fcc1ed Fix incorrect assert failure reporting.
* grub-core/tests/example_functional_test.c (example_test): Add
	a failure comment.
	* grub-core/tests/lib/test.c (add_failure): Renamed to ...
	(failure_start): ...this. Check that malloc succeeded.
	Don't call xvasprintf. Return failure struct.
	(failure_append_vtext): New function.
	(failure_append_text): Likewise.
	(add_failure): Likewise.
	(grub_test_assert_helper): Likewise.
	* include/grub/test.h (grub_test_assert_helper): New declaration.
	(grub_test_assert): Macro rewritten.
2011-03-23 13:01:42 +01:00