lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 25 Apr 2018 22:37:44 -0400
From:   "Theodore Y. Ts'o" <tytso@....edu>
To:     James Blanford <jhblanford@...il.com>
Cc:     linux-ext4@...r.kernel.org
Subject: Re: Boot fail - Cannot load crc32c driver

On Wed, Apr 25, 2018 at 10:59:58AM -0600, James Blanford wrote:
> 
> I noticed the 4.14.36 patch includes a new ext4 requirement that the
> crc32c driver be initialized. My system loads and uses the crc32c_intel
> driver, but apparently that's not good enough. The system won't boot
> without crc32c_generic, but it can't load it, because the fs it
> resides on has not been mounted.
> 
> No big deal, so I explicitly include crc32c_generic in the initrd. It
> boots, but I find that once booted the system doesn't seem to need
> crc32c_generic for subsequent mounts.
> 
> Can this change be modified to allow any of the three crc32c drivers?

So what happens is if crc32c isn't built into the kernel, the kernel
will request the module "crypto-crc32c".  (Look for the call to
request_module in crypto/api.c.)

The module name "crypto-crc32c" is an alias to crc32c_generic and
crc32c_intel.  You can see this via:

% git grep MODULE_ALIAS_CRYPTO | grep \"crc32c\"
arch/arm/crypto/crc32-ce-glue.c:MODULE_ALIAS_CRYPTO("crc32c");
arch/powerpc/crypto/crc32c-vpmsum_glue.c:MODULE_ALIAS_CRYPTO("crc32c");
arch/s390/crypto/crc32-vx.c:MODULE_ALIAS_CRYPTO("crc32c");
arch/sparc/crypto/crc32c_glue.c:MODULE_ALIAS_CRYPTO("crc32c");
arch/x86/crypto/crc32c-intel_glue.c:MODULE_ALIAS_CRYPTO("crc32c");  <-------
crypto/crc32c_generic.c:MODULE_ALIAS_CRYPTO("crc32c");  <----------

You can also see this by running "modinfo crypto-crc32c":

# modinfo crypto-crc32c
filename:       /lib/modules/4.15.0-0.bpo.2-cloud-amd64/kernel/arch/x86/crypto/crc32c-intel.ko
alias:          crypto-crc32c-intel
alias:          crc32c-intel
alias:          crypto-crc32c
alias:          crc32c
license:        GPL
description:    CRC32c (Castagnoli) optimization using Intel Hardware.
author:         Austin Zhang <austin.zhang@...el.com>, Kent Liu <kent.liu@...el.com>
alias:          cpu:type:x86,ven*fam*mod*:feature:*0094*
depends:        
retpoline:      Y
intree:         Y
name:           crc32c_intel
vermagic:       4.15.0-0.bpo.2-cloud-amd64 SMP mod_unload modversions 
filename:       /lib/modules/4.15.0-0.bpo.2-cloud-amd64/kernel/crypto/crc32c_generic.ko
alias:          crypto-crc32c-generic
alias:          crc32c-generic
alias:          crypto-crc32c
alias:          crc32c
license:        GPL
description:    CRC32c (Castagnoli) calculations wrapper for lib/crc32c
author:         Clay Haapala <chaapala@...co.com>
depends:        
retpoline:      Y
intree:         Y
name:           crc32c_generic
vermagic:       4.15.0-0.bpo.2-cloud-amd64 SMP mod_unload modversions 

So it is already the case any of the crc32c modules will work.  The
problem is which one(s) are included in the initial ramdisk, and which
one modprobe tries to use.

It looks like the problem is that if you only have a partial set of
modules in the initramfs, it's important that the initial ramdisk
tools needs to run depmod -a on the initramfs modules directory so
that modules.dep.bin file only has modules that are actually in the
initramfs.  Otherwise modprobe will try to find one of the modules
which is aliased to crypto-crc32c (I think it's unspecified which one,
or it's the last one).

root@...so-ssd:/home/tytso# mv /lib/modules/4.15.0-0.bpo.2-cloud-amd64/kernel/crypto/crc32c_generic.ko /lib/modules/4.15.0-0.bpo.2-cloud-amd64/kernel/crypto/crc32c_generic.ko.off
root@...so-ssd:/home/tytso# modprobe crypto-crc32c
modprobe: ERROR: could not insert 'crc32c_generic': Unknown symbol in module, or unknown parameter (see dmesg)
root@...so-ssd:/home/tytso# depmod -a
root@...so-ssd:/home/tytso# modprobe crypto-crc32c
root@...so-ssd:/home/tytso# lsmod | grep crc32c
crc32c_intel           24576  3

By the way, there seems to be a very long history of there being
problems with crc32c modules and aliasing.  I found a Debian bug going
back to 2011, which was helpful in my understanding how it was
supposed to work.

	https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=608538

I think the right solution is probably just to build (all) of the
crc32c modules into the kernel.  It's actually kind of silly to build
libcrc32c as a module.  The size of crc32c_generic and crc32c_intel
are well less than 16k:

   text	   data	    bss	    dec	    hex	filename
   7672	   1328	      0	   9000	   2328	/lib/modules/4.15.0-0.bpo.2-cloud-amd64/kernel/arch/x86/crypto/crc32c-intel.ko
   1197	   1328	      0	   2525	    9dd	/lib/modules/4.15.0-0.bpo.2-cloud-amd64/kernel/crypto/crc32c_generic.ko

The reason why that's important is that a loaded module always uses
16k, and by using lots of modules is less efficient, since each module
require burning an extra TLB cache entry when you call into it.  And
given that so many things uses crc32c, you might as well just always
build into the kernel, instead of building everything as a separate
module.

Cheers,

						- Ted

Powered by blists - more mailing lists