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>
The common datetime helper functions are currently included in the normal
module, but this makes any other module that calls these functions to have
a dependency with the normal module only for this reason.
Since the normal module does a lot of stuff, it calls functions from other
modules. But since other modules may depend on it for calling the datetime
helpers, this could lead to circular dependencies between modules.
As an example, when platform == xen the grub_get_datetime() function from
the datetime module calls to the grub_unixtime2datetime() helper function
from the normal module. Which leads to the following module dependency:
datetime -> normal
and send_dhcp_packet() from the net module calls the grub_get_datetime()
function, which leads to the following module dependency:
net -> datetime -> normal
but that means that the normal module is not allowed to depend on net or
any other module that depends on it due the transitive dependency caused
by datetime. A recent patch attempted to add support to fetch the config
file over the network, which leads to the following circular dependency:
normal -> net -> datetime -> normal
So having the datetime helpers in the normal module makes it quite fragile
and easy to add circular dependencies like these, that break the build due
the genmoddep.awk script catching the issues.
Fix this by taking the datetime helper functions out of the normal module
and instead add them to the datetime module itself. Besides fixing these
issues, it makes more sense to have these helper functions there anyways.
Reported-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
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>
While testing the 86-DOS lDebug [1] booting from GRUB2, newer versions of the
debugger would fail to load when booted using GRUB's freedos command. The
behaviour observed in a qemu i386 machine was that the ROM-BIOS's boot load
would start anew, instead of loading the selected debugger as kernel.
It came to light that there was a size limit: Kernel files that were 58880
bytes (E600h) long or shorter succeeded to boot, while files that were 64000
bytes or longer failed in the manner described.
Eventually it turned out that the relocator16 stub succeeded whenever it was
placed completely within the first 64 KiB of the Low Memory Area. The chunk
for the relocator is allocated with a minimum address of 0x8010 and a maximum
address just below 0xA0000 [2]. That means if the kernel is, for instance,
E600h bytes long, then the kernel will be allocated memory starting at 00600h
(the fixed FreeDOS kernel load address) up to E600h + 00600h = 0EC00h, which
leaves 1400h (5120) bytes for the relocator to stay in the first 64 KiB.
If the kernel is 64000 bytes (FA00h) long, then the relocator must go to
FA00h + 00600h = 10000h at least which is outside the first 64 KiB.
The problem is that the relocator16 initialises the DS register with a
"pseudo real mode" descriptor, which is defined with a segment limit of
64 KiB and a segment base of zero. After that, the relocator addressed
parts of itself (implicitly) using the DS register, with an offset from
ESI, which holds the linear address of the relocator's base [3]. With the
larger kernel files this would lead to accessing data beyond the 64 KiB
segment limit, presumably leading to a fault and perhaps a subsequent
triple-fault or such.
This patch fixes the relocator to set the segment base of the descriptors
to the base address of the relocator; then, the subsequent accesses to
the relocator's variables are done without the ESI register as an index.
This does not interfere with the relocator's or its target's normal
operation; the segment limits are still loaded with 64 KiB and all the
segment bases are subsequently reset by the relocator anyway.
Current versions of the debugger to test are uploaded to [4]. The file
ldebugnh.com (LZ4-compressed and built with -D_EXTHELP=0) at 58368 bytes
loads successfully, whereas ldebug.com at 64000 bytes fails. Loading one
of these files requires setting root to a FAT FS partition and using the
freedos command to specify the file as kernel:
set root='(hd0,msdos1)'
freedos /ldebug.com
boot
Booting the file using the multiboot command (which uses a WIP entrypoint
of the debugger) works, as it does not use GRUB's relocator16 but instead
includes a loader in the kernel itself, which drops it back to 86 Mode.
[1]: https://hg.ulukai.org/ecm/ldebug
[2]: http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/lib/i386/relocator.c?id=495781f5ed1b48bf27f16c53940d6700c181c74c#n127
[3]: http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/lib/i386/relocator16.S?id=495781f5ed1b48bf27f16c53940d6700c181c74c#n97
[4]: https://ulukai.org/ecm/lDebug-5479a7988d21-nohelp.zip
Signed-off-by: C. Masloch <pushbx@ulukai.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The upcoming support for LUKS2 disc encryption requires us to include a
parser for base64-encoded data, as it is used to represent salts and
digests. As gnulib already has code to decode such data, we can just
add it to the boostrapping configuration in order to make it available
in GRUB.
The gnulib module makes use of booleans via the <stdbool.h> header. As
GRUB does not provide any POSIX wrapper header for this, but instead
implements support for bool in <sys/types.h>, we need to patch
base64.h to not use <stdbool.h> anymore. We unfortunately cannot include
<sys/types.h> instead, as it would then use gnulib's internal header
while compiling the gnulib object but our own <sys/types.h> when
including it in a GRUB module. Because of this, the patch replaces the
include with a direct typedef.
A second fix is required to make available _GL_ATTRIBUTE_CONST, which
is provided by the configure script. As base64.h does not include
<config.h>, it is thus not available and results in a compile error.
This is fixed by adding an include of <config-util.h>.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
While the newly added jsmn library provides the parsing interface, it
does not provide any kind of interface to act on parsed tokens. Instead,
the caller is expected to handle pointer arithmetics inside of the token
array in order to extract required information. While simple, this
requires users to know some of the inner workings of the library and is
thus quite an unintuitive interface.
This commit adds a new interface on top of the jsmn parser that provides
convenience functions to retrieve values from the parsed json type, grub_json_t.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The upcoming support for LUKS2 encryption will require a JSON parser to
decode all parameters required for decryption of a drive. As there is
currently no other tool that requires JSON, and as gnulib does not
provide a parser, we need to introduce a new one into the code base. The
backend for the JSON implementation is going to be the jsmn library [1].
It has several benefits that make it a very good fit for inclusion in
GRUB:
- It is licensed under MIT.
- It is written in C89.
- It has no dependencies, not even libc.
- It is small with only about 500 lines of code.
- It doesn't do any dynamic memory allocation.
- It is testen on x86, amd64, ARM and AVR.
The library itself comes as a single header, only, that contains both
declarations and definitions. The exposed interface is kind of
simplistic, though, and does not provide any convenience features
whatsoever. Thus there will be a separate interface provided by GRUB
around this parser that is going to be implemented in the following
commit. This change only imports jsmn.h from tag v1.1.0 and adds it
unmodified to a new json module with the following command:
curl -L https://raw.githubusercontent.com/zserge/jsmn/v1.1.0/jsmn.h \
-o grub-core/lib/json/jsmn.h
Upstream jsmn commit hash: fdcef3ebf886fa210d14956d3c068a653e76a24e
Upstream jsmn commit name: Modernize (#149), 2019-04-20
[1]: https://github.com/zserge/jsmn
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
In addition to what was already there, Gnulib's <intprops.h> needs SCHAR_MIN,
SCHAR_MAX, SHRT_MIN, INT_MIN, LONG_MIN, and LONG_MAX. Fixes build on CentOS 7.
Reported-by: "Chen, Farrah" <farrah.chen@intel.com>
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
In order to maintain the coding style consistency, it was requested to
replace the methods that use "__asm__ __volatile__" with "asm volatile".
Signed-off-by: Jesús Diéguez Fernández <jesusdf@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upgrade Gnulib files to 20190105.
It's much easier to maintain GRUB's use of portability support files
from Gnulib when the process is automatic and driven by a single
configuration file, rather than by maintainers occasionally running
gnulib-tool and committing the result. Removing these
automatically-copied files from revision control also removes the
temptation to hack the output in ways that are difficult for future
maintainers to follow. Gnulib includes a "bootstrap" program which is
designed for this.
The canonical way to bootstrap GRUB from revision control is now
"./bootstrap", but "./autogen.sh" is still useful if you just want to
generate the GRUB-specific parts of the build system.
GRUB now requires Autoconf >= 2.63 and Automake >= 1.11, in line with
Gnulib.
Gnulib source code is now placed in grub-core/lib/gnulib/ (which should
not be edited directly), and GRUB's patches are in
grub-core/lib/gnulib-patches/. I've added a few notes to the developer
manual on how to maintain this.
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
syslinux_parse simplifies some filenames by removing things like ".."
segments, but the tests assumed that @abs_top_srcdir@ would be
untouched, which is not true in the case of out-of-tree builds where
@abs_top_srcdir@ may contain ".." segments.
Performing the substitution requires some awkwardness in Makefile.am due
to details of how config.status works.
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This patch adds support for RISC-V to the grub build system. With this
patch, I can successfully build grub on RISC-V as a UEFI application.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This patch adds a 32/64 capable setjmp implementation for RISC-V.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
- Import zstd-1.3.6 from upstream
- Add zstd's module.c file
- Add the zstd module to Makefile.core.def
Import zstd-1.3.6 from upstream [1]. Only the files need for decompression
are imported. I used the latest zstd release, which includes patches [2] to
build cleanly in GRUB.
I included the script used to import zstd-1.3.6 below at the bottom of the
commit message.
Upstream zstd commit hash: 4fa456d7f12f8b27bd3b2f5dfd4f46898cb31c24
Upstream zstd commit name: Merge pull request #1354 from facebook/dev
Zstd requires some posix headers, which it gets from posix_wrap.
This can be checked by inspecting the .Po files generated by automake,
which contain the header dependencies. After building run the command
`cat grub-core/lib/zstd/.deps-core/*.Po` to see the dependencies [3].
The only OS dependencies are:
- stddef.h, which is already a dependency in posix_wrap, and used for size_t
by lzo and xz.
- stdarg.h, which comes from the grub/misc.h header, and we don't use in zstd.
All the types like uint64_t are typedefed to grub_uint64_t under the hood.
The only exception is size_t, which comes from stddef.h. This is already the
case for lzo and xz. I don't think there are any cross-compilation concerns,
because cross-compilers provide their own system headers (and it would already
be broken).
[1] https://github.com/facebook/zstd/releases/tag/v1.3.6
[2] https://github.com/facebook/zstd/pull/1344
[3] https://gist.github.com/terrelln/7a16b92f5a1b3aecf980f944b4a966c4
```
curl -L -O https://github.com/facebook/zstd/releases/download/v1.3.6/zstd-1.3.6.tar.gz
curl -L -O https://github.com/facebook/zstd/releases/download/v1.3.6/zstd-1.3.6.tar.gz.sha256
sha256sum --check zstd-1.3.6.tar.gz.sha256
tar xzf zstd-1.3.6.tar.gz
SRC_LIB="zstd-1.3.6/lib"
DST_LIB="grub-core/lib/zstd"
rm -rf $DST_LIB
mkdir -p $DST_LIB
cp $SRC_LIB/zstd.h $DST_LIB/
cp $SRC_LIB/common/*.[hc] $DST_LIB/
cp $SRC_LIB/decompress/*.[hc] $DST_LIB/
rm $DST_LIB/{pool.[hc],threading.[hc]}
rm -rf zstd-1.3.6*
echo SUCCESS!
```
Signed-off-by: Nick Terrell <terrelln@fb.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
Let's provide file type info to the I/O layer. This way verifiers
framework and its users will be able to differentiate files and verify
only required ones.
This is preparatory patch.
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
Commit 0ba90a7f01 ("efi: Move grub_reboot() into kernel") broke
the build on i386-efi - genmoddep.awk bails out with message
grub_reboot in reboot is duplicated in kernel
This is because both lib/i386/reset.c and kern/efi/efi.c now provide
this function.
Rather than explicitly list each i386 platform variant in
Makefile.core.def, include the contents of lib/i386/reset.c only when
GRUB_MACHINE_EFI is not set.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
To be able to resuse the prop_entry_size macro, move it to
<grub/fdt.h> and rename it grub_fdt_prop_entry_size.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The CRC implementation imported from libgcrypt 1.5.3 is arguably
non-free, due to being encumbered by the restrictive Internet Society
licence on RFCs (see e.g. https://wiki.debian.org/NonFreeIETFDocuments).
Fortunately, libgcrypt has since replaced it with a version that is both
reportedly better-optimised and doesn't suffer from this encumbrance.
The ideal solution would be to update to a new version of libgcrypt, and
I spent some time trying to do that. However, util/import_gcry.py
requires complex modifications to cope with the new version, and I
stalled part-way through; furthermore, GRUB's libgcrypt tree already
contains some backports of upstream changes. Rather than allowing the
perfect to be the enemy of the good, I think it's best to backport this
single change to at least sort out the licensing situation. Doing so
won't make things any harder for a future wholesale upgrade.
This commit is mostly a straightforward backport of
https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff;h=06e122baa3321483a47bbf82fd2a4540becfa0c9,
but I also imported bufhelp.h from libgcrypt 1.7.0 (newer versions
required further changes elsewhere).
I've tested that "hashsum -h crc32" still produces correct output for a
variety of files on both i386-pc and x86_64-emu targets.
Signed-off-by: Colin Watson <cjwatson@ubuntu.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
The reboot function calls machine_fini() and then reboots the system.
Currently it lives in lib/ which means it gets compiled into the
reboot module which lives on the heap.
In a following patch, I want to free the heap on machine_fini()
though, so we would free the memory that the code is running in. That
obviously breaks with smarter UEFI implementations.
So this patch moves it into the core. That way we ensure that all
code running after machine_fini() in the UEFI case is running from
memory that got allocated (and gets deallocated) by the UEFI core.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
In util/getroot and efidisk slightly modify exitsing comment to mostly
retain it but still make GCC7 compliant with respect to fall through
annotation.
In grub-core/lib/xzembed/xz_dec_lzma2.c it adds same comments as
upstream.
In grub-core/tests/setjmp_tets.c declare functions as "noreturn" to
suppress GCC7 warning.
In grub-core/gnulib/regexec.c use new __attribute__, because existing
annotation is not recognized by GCC7 parser (which requires that comment
immediately precedes case statement).
Otherwise add FALLTHROUGH comment.
Closes: 50598
Unified Extensible Firmware Interface Specification, Version 2.6,
section 2.3.4, x64 Platforms, boot services, says among others:
The stack must be 16-byte aligned. So, do it. Otherwise OS may
boot only by chance as it happens right now.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Modify the page table construction to allow multiple virtual regions
to be mapped. This is done as preparation for removing the p2m list
from the initial kernel mapping in order to support huge pv domains.
This allows a cleaner approach for mapping the relocator page by
using this capability.
The interface to the assembler level of the relocator has to be changed
in order to be able to process multiple page table areas.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Add grub_relocator64_efi relocator. It will be used on EFI 64-bit platforms
when multiboot2 compatible image requests MULTIBOOT_TAG_TYPE_EFI_BS. Relocator
will set lower parts of %rax and %rbx accordingly to multiboot2 specification.
On the other hand processor mode, just before jumping into loaded image, will
be set accordingly to Unified Extensible Firmware Interface Specification,
Version 2.4 Errata B, section 2.3.4, x64 Platforms, boot services. This way
loaded image will be able to use EFI boot services without any issues.
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
-Wunreachable-code has been a no-op since GCC 4.5; GRUB hasn't been
compiled with it since 2012; and GCC 6 produces "error:
'-Wunreachable-code' is not an option that controls warnings" for these.
Fixes Debian bug #812047.
From original patch by dann frazier <dann.frazier@canonical.com>:
grub_net_fs_open() saves off a copy of the file structure it gets passed and
uses it to create a bufio structure. It then overwrites the passed in file
structure with this new bufio structure. Since file->name doesn't get set
until we return back to grub_file_open(), it means that only the bufio
structure gets a valid file->name. The "real" file's name is left
uninitialized. This leads to a crash when the progress module hook is called
on it.
grub_net_fs_open() already saved copy of file name as ->net->name, so change
progress module to use it.
Also, grub_file_open may leave file->name as NULL if grub_strdup fails. Check
for it.
Also-By: dann frazier <dann.frazier@canonical.com>
mips_attributes was introduced to work around clang problems with
-msoft-float. Those problems are now fixed and moreover .gnu_attributes
itself is unportable and creates problem with clang.
Revert "mips: Fix soft-float handling."
This partially reverts commit 6a4ecd276e.