On Sat, Jun 9, 2018 at 8:56 AM Alexander Kapshuk
<alexander.kaps...@gmail.com> wrote:
>
>
>
> On Sat, Jun 9, 2018, 07:34 Ian Zimmerman <i...@very.loosely.org> wrote:
>>
>> On 2018-06-08 22:38, Alexander Kapshuk wrote:
>>
>> > On Fri, Jun 8, 2018, 22:30 Ian Zimmerman <i...@very.loosely.org> wrote:
>> >
>> > > On 2018-06-08 22:00, Alexander Kapshuk wrote:
>> > >
>> > > > What's the output of:
>> > > > uname -r
>> > > > strings /path/to/your/module.ko | grep vermagic=
>> > >
>> > > Here are the results for 4.9.105 (working):
>> > >
>> > >  matica!6 ~$ uname -r
>> > > 4.9.105
>> > >  matica!7 ~$ strings
>> > >  /lib64/modules/4.9.105/kernel/drivers/video/console/fbcon.ko |
>> > >  fgrep -e 'vermagic='
>> > > vermagic=4.9.105 SMP
>> > >
>> > > Let me know if you need to see the ones for the broken kernel ...
>> > >
>> >
>> > Yes, we want to make sure the vermagic of the modules you're trying to load
>> > matches the output of uname -r of the running kernel.
>>
>> Ok, here:
>>
>> Script started on 2018-06-08 21:11:04-0700
>>  matica!501 ~# ls -l 
>> /lib64/modules/4.9.107/kernel/drivers/video/console/fbcon.ko
>> -rw-r--r-- 1 root root 54280 Jun  8 20:57 
>> /lib64/modules/4.9.107/kernel/drivers/video/console/fbcon.ko
>>  matica!502 ~# uname -r
>> 4.9.107
>>  matica!503 ~# strings 
>> /lib64/modules/4.9.107/kernel/drivers/video/console/fbcon
>> .ko | fgrep -e 'vermagic='
>> vermagic=4.9.107 SMP
>>  matica!504 ~# modprobe fbcon
>> modprobe: ERROR: could not insert 'fbcon': Exec format error
>>  matica!505 ~# exit
>>
>> Script done on 2018-06-08 21:14:46-0700
>>
>> Sorry to ruin the low-hanging hypothesis :-P
>>
>
> Did dmesg have anything useful to say other than exec format error?
> Have you tried insmod'ing the modules instead of modprobe'ing them?
>>
>>
>> --

I had a look at the source code for kmod-25. If I read it right, dmesg
should have records along the lines of:
kmod-25/libkmod/libkmod-module.c:886:           INFO(mod->ctx, "Failed
to insert module '%s': %m\n", path);

modprobe returns Exec format error.

errno -l | grep 'Exec format error'
ENOEXEC 8 Exec format error

/usr/include/asm-generic/errno-base.h:
#define   ENOEXEC          8      /* Exec format error */

Here's the execution path I've been able to follow:
insmod()->kmod_module_probe_insert_module()->kmod_module_insert_module()->init_module()->copy_module_from_user();

init_module(2):
http://man7.org/linux/man-pages/man2/init_module.2.html
ENOEXEC
              The binary image supplied in module_image is not an ELF image,
              or is an ELF image that is invalid or for a different
              architecture.

(1). kmod-25/tools/modprobe.c
ENOEXEC returned by kmod_module_probe_insert_module().
static int insmod(struct kmod_ctx *ctx, const char *alias,
const char *extra_options)
{
...
kmod_list_foreach(l, list) {
...
if (lookup_only)
printf("%s\n", kmod_module_get_name(mod));
else {
err = kmod_module_probe_insert_module(mod, flags,
extra_options, NULL, NULL, show);
}

if (err >= 0)
/* ignore flag return values such as a mod being blacklisted */
err = 0;
else {
switch (err) {
...
default:
ERR("could not insert '%s': %s\n", <- the error message reported by modprobe
kmod_module_get_name(mod),
strerror(-err));
break;
}
}

(2). kmod-25/libkmod/libkmod-module.c
KMOD_EXPORT int kmod_module_probe_insert_module(struct kmod_module *mod,
unsigned int flags, const char *extra_options,
int (*run_install)(struct kmod_module *m,
const char *cmd, void *data),
const void *data,
void (*print_action)(struct kmod_module *m,
bool install,
const char *options))
{
...
if (!(flags & KMOD_PROBE_DRY_RUN))
err = kmod_module_insert_module(m, flags,
options);
}
...
}

(3). KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
unsigned int flags,
const char *options)
{
...
size = kmod_file_get_size(mod->file); <- the size of your modules elf file
...
err = init_module(mem, size, args);
...
}

(4). [init_module syscall]
kernel/module.c
SYSCALL_DEFINE3(init_module, void __user *, umod,
                unsigned long, len, const char __user *, uargs)
{
        int err;
        struct load_info info = { };

        err = may_init_module();
        if (err)
                return err;

        pr_debug("init_module: umod=%p, len=%lu, uargs=%p\n",
               umod, len, uargs);

        err = copy_module_from_user(umod, len, &info);
        if (err)
                return err;

        return load_module(&info, uargs, 0);
}

(5). kernel/module.c
/* Sets info->hdr and info->len. */
static int copy_module_from_user(const void __user *umod, unsigned long len,
                                  struct load_info *info)
{
        int err;

        info->len = len;
        if (info->len < sizeof(*(info->hdr))) <- here, size of your
module'e elf file is being compared against the size of the ELF header
as defined for your architecture. See below.
                return -ENOEXEC;
...
}

kernel/module.c:310,313
struct load_info {
const char *name;
Elf_Ehdr *hdr; <- ELF header used in comparison above.
unsigned long len;

Elf_Ehdr is effected by CONFIG_X86_32 set in:
arch/x86/um/asm/module.h:14:#define Elf_Ehdr Elf32_Ehdr
arch/x86/um/asm/module.h:20:#define Elf_Ehdr Elf64_Ehdr

And CONFIG_64BIT defined in:
include/asm-generic/module.h:20:#define Elf_Ehdr        Elf64_Ehdr
include/asm-generic/module.h:37:#define Elf_Ehdr        Elf32_Ehdr

Example of ELF header sizes for 32/64 bit:
readelf -h ./kernel/fs/udf/udf.ko
ELF Header:
 Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
 Class:                             ELF32
...
 Machine:                           Intel 80386
...
 Size of this header:               52 (bytes)

readelf -h ./kernel/fs/udf/udf.ko
ELF Header:
 Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
 Class:                             ELF64
 ...
 Machine:                           Advanced Micro Devices X86-64
 Size of this header:               64 (bytes)

Now, if my understanding of the source code above is right, you either
have CONFIG_X86_32 set in your kernel, e.i. your Elf_Ehdr is set to
Elf32_Ehdr, or the module's header is for the architecture that is
different from what is expected by the kernel.

Reply via email to