kmod depmod ARM bug

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

 



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;

[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