Hello.
[ see bug report https://github.com/archlinuxarm/PKGBUILDs/issues/127 ]
The depmod program from kmod fails to properly compute kernel module
dependencies on ARMv5 systems:
[root@alarm ~]# modinfo bridge
filename: /lib/modules/2.6.39.4/kernel/net/bridge/bridge.ko
version: 2.3
license: GPL
srcversion: 6B583530AE2B39C7E2317BF
depends: stp,llc
vermagic: 2.6.39.4 preempt mod_unload ARMv5
[root@alarm ~]# depmod
[root@alarm ~]# cat /lib/modules/2.6.39.4/modules.dep |grep bridge
kernel/net/bridge/bridge.ko:
[root@alarm ~]#
See how modinfo properly lists the dependencies, but modules.dep which
depmod generates does not contain them. As a result, most kernel
modules fail to load because their dependencies are not loaded by
modprobe.
The cause is unaligned memory access in a hash function. Patch is
attacked, and linked to in the above link.
Best regards,
Ambroz Bizjak
diff --git a/libkmod/libkmod-hash.c b/libkmod/libkmod-hash.c
index f58e9db..97de29a 100644
--- a/libkmod/libkmod-hash.c
+++ b/libkmod/libkmod-hash.c
@@ -83,6 +83,10 @@ void hash_free(struct hash *hash)
free(hash);
}
+struct unaligned_short {
+ unsigned short v;
+} __attribute__((packed));
+
static inline unsigned int hash_superfast(const char *key, unsigned int len)
{
/* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html)
@@ -90,14 +94,14 @@ static inline unsigned int hash_superfast(const char *key, unsigned int len)
* EFL's eina and possible others.
*/
unsigned int tmp, hash = len, rem = len & 3;
- const unsigned short *itr = (const unsigned short *)key;
+ const struct unaligned_short *itr = (const struct unaligned_short *)key;
len /= 4;
/* Main loop */
for (; len > 0; len--) {
- hash += itr[0];
- tmp = (itr[1] << 11) ^ hash;
+ hash += itr[0].v;
+ tmp = (itr[1].v << 11) ^ hash;
hash = (hash << 16) ^ tmp;
itr += 2;
hash += hash >> 11;
@@ -106,14 +110,14 @@ static inline unsigned int hash_superfast(const char *key, unsigned int len)
/* Handle end cases */
switch (rem) {
case 3:
- hash += *itr;
+ hash += itr->v;
hash ^= hash << 16;
hash ^= key[2] << 18;
hash += hash >> 11;
break;
case 2:
- hash += *itr;
+ hash += itr->v;
hash ^= hash << 11;
hash += hash >> 17;
break;