The patch adds data fetching from the PKCS#7 certificate using
openssl library (which is used by scripts/sign-file.c in the linux
kernel to sign modules).
In general the certificate can contain many signatures, but since
kmod (modinfo) supports only one signature at the moment, only first
one is taken.
With the current sign-file.c certificate doesn't contain signer
key's fingerprint, so "serial number" is used for the key id.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
when PKC#7 signing method is used the old structure doesn't contain
any useful data, but the data are encoded in the certificate.
The info getting/showing code is not aware of that at the moment and
since 0 is a valid constant, shows, for example, wrong "md4" for the
hash algo.
The patch splits the 2 mothods of gethering the info and reports
"unknown" for the algo.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
When building a C source file with gcc-7 -Wshift-overflow=2, this warning
springs up:
libkmod.h: warning: result of "1 << 31" requires 33 bits to
represent, but "int" only has 32 bits [-Wshift-overflow=]
Change the two _KMOD_* identifiers to fit into 32 bits.
This introduces a few missing NULL-checks in public functions, and
align their docstrings with real behavior by getting rid of copy-paste
mistakes.
Signed-off-by: Luca Bruno <luca.bruno@coreos.com>
Normally exported symbol's crc is stored as absolute (SHN_ABS)
value of special named symbol __crc_<symbol name>.
When the kernel and modules are built with the config option
CONFIG_MODULE_REL_CRCS, all the CRCs are put in a special section
and the __crc_<symbol name> symbols values are offsets in the
section. See patch description of the commit:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=56067812d5b0e737ac2063e94a50f76b810d6ca3
Add kmod support of this configuration.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
Signature was ignored from the modinfo. Implement its parsing
from the module data and add its output to the modinfo utility.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
The key output is usually short, but for signature it is more
readable to output it in several lines.
Implement line splitting. Set line limit hardcoded to 20 hex
numbers (not characters).
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
Refactor the code a bit to make it easier to extend for signature
output.
kmod_module_get_info() creats a hex string for the sig_key data
inplace. Separate it into own kmod_module_hex_to_string function
and handle the branch in the new kmod_module_info_append_hex,
keeping the same signature as the non-hex version.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
For some reason the key for sig_id was set to "signature". The
length was calculated against the proper string, as the result in
the output it was truncated to "signat".
Pass the proper key to the kmod_module_info_append() call.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
When a module is removed and re-inserted without unrefing, the
kmod_file is unconditionally re-opened. This results in a memory
and file descriptor leak.
Fix it by checking if the file is already open in
kmod_module_insert_module().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
If a module parameter on the command line contains quotes, any
spaces inside those quotes should be included as part of the
parameter.
Signed-off-by: James Minor <james.minor@ni.com>
It was failing to generate doc with recent version of gtk-doc
[kmod]$ ./bootstrap
libkmod/docs/gtk-doc.make:33: error: EXTRA_DIST must be set with '=' before using '+='
libkmod/docs/Makefile.am:29: 'libkmod/docs/gtk-doc.make' included from here
autoreconf: automake failed with exit status: 1
Just add an empty EXTRA_DIST so it works.
kmod_module_new_from_loaded() calls fgets with a 4k buffer. When a
module such as usbcore is used by too many modules, the rest of the line
is considered a beginning of another lines and we eventually get errors
like these from lsmod:
libkmod: kmod_module_get_holders: could not open '/sys/module/100,/holders': No such file or directory
together with bogus entries in the output. In kmod_module_get_size, the
problem does not affect functionality, but the line numbers in error
messages will be wrong.
Signed-off-by: Michal Marek <mmarek@suse.com>
Currently, modprobe fails with no output by default if the
search paths it tries are missing:
$ modprobe -S notakernel dm-crypt
$
$ modprobe -S notakernel lkjjweiojo
$
This is fairly cryptic and not at all obvious there is a problem
unless the error code is checked or verbose flags are used.
Update the error message to indicate a problem and print out the
directory that failed.
ENOSYS is the wrong errno to return when we don't find a module in
kmod_module_insert_module(). Why is it there in the first place? This
goes back to kmod v1 when we couldn't load modules by names, but we
should give a path instead.
708624a ("ELF: initial support for modinfo and strip of modversions and
vermagic.") changed that so we do a lazy-search by the module path in
this function. Later f304afe ("Change error message to reflect
reality") fixed the log message but the return coded remained the same.
usecase: two sd cards are being mounted in parallel at same time on
dual core. example modules which are getting loaded is nls_cp437.
While one module is being loaded , it starts creating sysfs files.
meanwhile on other core, modprobe might return saying the module
is KMOD_MODULE_BUILTIN, which might result in not mounting sd card.
Experiments done to prove the issue in kmod.
Added sleep in kernel module.c at the place of creation of sysfs files.
Then tried `modprobe nls_cp437` from two different shells.
While the first was still waiting for its completion ,
the second one returned saying the module is built-in.
[ Lucas:
The problem is that the creation of /sys/module/<name> and
/sys/module/<name>/initstate are not atomic. There's a small window in
which the directory exists but the initstate file was still not
created.
Built-in modules can be handled by searching the modules.builtin file.
We actually lose some "modules" that create entries in /sys/modules
(e.g. vt) and are not in modules.builtin file: only those that can be
compiled as module are present in this file.
We enforce mod->builtin to always be up-to-date when
kmod_module_get_initstate() is called. This way if the directory
exists but the initstate doesn't, we can be sure this is because the
module is in the "coming" state, i.e. kernel didn't create the file
yet, but since builtin modules were already handled by checking our
index the only reason for that to happen is that we hit the race
condition.
I also added some tweaks to the patch, so we don't repeat the code for builtin
lookup. ]
A segmentation fault occurs if a module has an empty key attached to
its signature. This is mostly likely due to a corrupted module.
The crash happens because kmod_module_get_info() assumes that
kmod_module_signature_info() returns a signature of at least 1 byte.
The fix is based on a patch from Tobias Stoeckmann
<tobias@stoeckmann.org>, but rather than changing kmod_module_get_info()
to fix the crash, this changes kmod_module_signature_info() to
consider the signature as invalid.
If kmod has been configured with --disable-largefile on a 32 bit
system, off_t will be 32 bit. In that case, the parsed sig_len can
bypass a validation check (it's _unsigned_ 32 bit).
Due to the unlikeliness of people using --disable-largefile, this is
a mere validation fix. With an explicit signed 64 bit cast, there is
no binary change for 99.9% of Linux systems out there. ;)
In function kmod_elf_new, the file size has to be properly validated against
section offset. Currently, the file size is considered valid based on
ELF header size + section header size * section count. That is not sufficient.
In fact, ELF specifies a section header offset, which doesn't have to be the
size of the ELF header. The supplied test cases even cover this.
The correct test is: section offset + section header size * section count
This patch also verifies that this value won't overflow. I don't know a way
to crash a tool due to this bug, because later on the offset check would
prevent out-of-bounds access. An overflow would just mean to access a wrong
part in elf->memory. Yet it's a validation error.
Please note: The file size does not have to be validated against the size
of the ELF header again, elf_identify did this already.
it is possible to overflow uint64_t by summing variables offset and
size up in elf_get_section_info. Thee values are extracted from module
file and are possibly maliciously tampered with.
If offset is in valid range and size very large, the result will
overflow and the size check passes. Later on, this will most likely
lead to a segmentation fault due to accessing uninitialized memory.
Attached please find a proof of concept module, which will trigger
a segmentation fault on modinfo. Tested on amd64:
tobias:~$ modinfo poc.ko
filename: /home/tobias/poc.ko
Segmentation fault
There are more errors of this type in the ELF handling code that will be
fixed in other patches.
Initialize variable to NULL before calling kmod_module_new_from_lookup().
libkmod/libkmod-module.c: In function 'kmod_module_new_from_lookup.part.4.constprop':
libkmod/libkmod-module.c:192:8: warning: 'depmod' may be used uninitialized in this function [-Wmaybe-uninitialized]
list = kmod_list_prepend(list, depmod);
^
libkmod/libkmod-module.c:173:23: note: 'depmod' was declared here
struct kmod_module *depmod;
It has changed in the past, and these days, anyone can get a copy of the
LGPL via the web rather than by post.
Like 657a122 (Remove FSF mailing address) in libabc by Josh Tripplet,
but let the FSF website in which the license can be found.
Just like other source files, keep the index and comments in the source
file rather than the header.
This also removes INDEX_PRIORITY_MIN that was never being used.
libkmod/libkmod-list.c:39:33: warning: unused function 'list_node_next' [-Wunused-function]
static inline struct list_node *list_node_next(const struct list_node *node)
^
libkmod/libkmod-list.c:47:33: warning: unused function 'list_node_prev' [-Wunused-function]
static inline struct list_node *list_node_prev(const struct list_node *node)
^
It doesn't really matter in the end result since the compiler won't
generate any code for it. But let's keep it clean. It wasn't needed
until now, so probably it won't be anymore.
Move underscores() to shared/. It's the same as alias_normalize(), but
it rather operates in place, with the same string being passed.
The difference now that it's in shared/ is that it's a non-logging
function.
This makes us a little bit more verbose: we don't accept partially
correct module and aliases names in kcmdline and in configuration files.
We log an error instead.
The only user outside of libkmod-util is depmod, which really only needs
to get the string for the extension of uncompressed modules. It doesn't
need to access the array itself.