Re: Assertion fails in init_module.c on 32bits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 20 Jun 2012 16:00:40 -0300
Lucas De Marchi <lucas.demarchi@xxxxxxxxxxxxxx> wrote:

> Hi Robert,
> 
> On Wed, Jun 20, 2012 at 9:47 AM, Robert Milasan <rmilasan@xxxxxxx>
> wrote:
> > On Wed, 20 Jun 2012 09:15:33 -0300
> > Lucas De Marchi <lucas.demarchi@xxxxxxxxxxxxxx> wrote:
> >
> >> On Wed, Jun 20, 2012 at 8:56 AM, Robert Milasan <rmilasan@xxxxxxx>
> >> wrote:
> >> > On Wed, 20 Jun 2012 08:34:59 -0300
> >> > Lucas De Marchi <lucas.demarchi@xxxxxxxxxxxxxx> wrote:
> >> >
> >> >> Hi Robert,
> >> >>
> >> >> please CC linux-modules@xxxxxxxxxxxxxxx so others can benefit
> >> >> from the responses. I'm doing so now.
> >> >>
> >> >> On Wed, Jun 20, 2012 at 8:21 AM, Robert Milasan
> >> >> <rmilasan@xxxxxxx> wrote:
> >> >> > Hello, I'm trying now to build kmod 9 on 64 and 32 bits
> >> >> > opensuse. On 64bits everything is fine, but on 32bits it fails
> >> >> > in init_modules.c: 150:assert(mkdir_p(buf, 0755) >= 0);
> >> >> >
> >> >> > If I drop assert, all works. Do you have an idea why it fails?
> >> >>
> >> >> Does "make check" work for you after removing this assert? Some
> >> >> of the tests that rely on being able to create dirs on
> >> >> testsuite's rootfs should fail if you didn't create the dirs.
> >> >>
> >> >> On your 32 bits machine, is your testsuite/rootfs dir (or any of
> >> >> the dirs below)  read-only?
> >> >>
> >> >> Lucas De Marchi
> >> >
> >> > If I drop assert(mkdir_p...) then all works. rootfs and the below
> >> > dirs all have the rights "0755" so all good, but this issue
> >> > doesn't happen on 64bits which is a bit strange for me. Maybe
> >> > there is something wrong in mkdir.c -> mkdir_p function.
> >>
> >> Maybe... gotta check this on a 32 bits machine.
> >>
> >> >
> >> > Anyway I've asked around and some people said that using assert
> >> > on "mkdir_p" is kind of a bad idea, but I'm not a developer so I
> >> > wouldn't know.
> >>
> >> Yeah, except that this code path runs only on *testsuite*, i.e.
> >>  it's part of the tests we make to check it's right, but it's not
> >> part of libkmod, modprobe or depmod, etc that runs on production.
> >>
> >> I put the assert because there are tests that depend on being able
> >> to create dirs: among others, the "install command loop" test. If
> >> dir is not created, it will fail nonetheless, but instead of
> >> saying it's because of a failed dir creation it will create a fork
> >> bomb (yeah, it's a loop of fork + exec). I preferred failing the
> >> test earlier than having to killall modprobe later or wait for
> >> kernel's oom killer.
> >>
> >>
> >> Lucas De Marchi
> >
> > OK, now I know why it fails errno -17 which means the dir already
> > exists.
> >
> > test-init: testsuite/init_module.c:155: create_sysfs_files:
> > Assertion `err >= 0' failed. err: -17
> >
> > This is a small patch for that:
> 
> Thanks for this.
> 
> 
> The bug is a bit deeper: neither on mkdir_p or the filesystem
> permissions.  The testsuite includes a 64 bits module that we need to
> fake its insertion (both in 64 and 32 bits machine) - and that means
> picking the module name at the correct memory offset. This is why it
> fails only for 32 bits machine - it was using the "32-bits offset" to
> parse a module for 64 bits and the end result was:  modname = "".
> 
> The patch below (the same as attached) fixed the issue for me on 32
> bits. Let me know if it works for you
> 
> Lucas De Marchi
> 
> ----------8<-----------
> diff --git a/testsuite/init_module.c b/testsuite/init_module.c
> index 814998a..8089636 100644
> --- a/testsuite/init_module.c
> +++ b/testsuite/init_module.c
> @@ -16,6 +16,7 @@
>   */
> 
>  #include <assert.h>
> +#include <elf.h>
>  #include <errno.h>
>  #include <dirent.h>
>  #include <fcntl.h>
> @@ -206,6 +207,12 @@ static inline bool module_is_inkernel(const char
> *modname) return ret;
>  }
> 
> +static uint8_t elf_identify(void *mem)
> +{
> +	uint8_t *p = mem;
> +	return p[EI_CLASS];
> +}
> +
>  TS_EXPORT long init_module(void *mem, unsigned long len, const char
> *args);
> 
>  /*
> @@ -225,6 +232,8 @@ long init_module(void *mem, unsigned long len,
> const char *args)
>  	const void *buf;
>  	uint64_t bufsize;
>  	int err;
> +	uint8_t class;
> +	off_t offset;
> 
>  	init_retcodes();
> 
> @@ -236,14 +245,18 @@ long init_module(void *mem, unsigned long len,
> const char *args)
>  								&bufsize);
>  	kmod_elf_unref(elf);
> 
> -	/*
> -	 * We couldn't find the module's name inside the ELF file.
> Just exit
> -	 * as if it was successful
> -	 */
> +	/* We couldn't parse the ELF file. Just exit as if it was
> successful */ if (err < 0)
>  		return 0;
> 
> -	modname = (char *)buf + offsetof(struct module, name);
> +	/* We need to open both 32 and 64 bits module - hack! */
> +	class = elf_identify(mem);
> +	if (class == ELFCLASS64)
> +		offset = MODULE_NAME_OFFSET_64;
> +	else
> +		offset = MODULE_NAME_OFFSET_32;
> +
> +	modname = (char *)buf + offset;
>  	mod = find_module(modules, modname);
>  	if (mod != NULL) {
>  		errno = mod->errcode;
> diff --git a/testsuite/stripped-module.h b/testsuite/stripped-module.h
> index 9f97dae..19862f3 100644
> --- a/testsuite/stripped-module.h
> +++ b/testsuite/stripped-module.h
> @@ -13,6 +13,7 @@ struct list_head {
>  };
> 
>  #define MODULE_NAME_LEN (64 - sizeof(unsigned long))
> +
>  struct module
>  {
>  	enum module_state state;
> @@ -24,4 +25,8 @@ struct module
>  	char name[MODULE_NAME_LEN];
>  };
> 
> +/*                                padding */
> +#define MODULE_NAME_OFFSET_64 4 + 4           + 2 * 8
> +#define MODULE_NAME_OFFSET_32 4 + 2 * 4
> +
>  #endif

Thank you, this worked, at least it builds :)

-- 
Robert Milasan
L3 Support Engineer
SUSE
rmilasan@xxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux