Hi, if kmod has been configured with --disable-largefile on a 32 bit system, off_t will be 32 bit. In that case, the parsed sig_len can bypass a validation check (it's _unsigned_ 32 bit), allowing a an attacker to perform out of boundary access through a malicious module.
Due to the unlikeliness of people using --disable-largefile, this is
a mere validation fix. With an explicit signed 64 bit cast, there is
no binary change for 99.9% of Linux systems out there. ;)
Attached please find a proof of concept, which will most likely result in
a segmentation fault (works fine with 64 bit off_t builds):
tobias:~$ modinfo 32sig.ko
filename: /home/tobias/32sig.ko
Segmentation fault
Tobias
---
libkmod/libkmod-signature.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libkmod/libkmod-signature.c b/libkmod/libkmod-signature.c
index 5ed5973..bced8ab 100644
--- a/libkmod/libkmod-signature.c
+++ b/libkmod/libkmod-signature.c
@@ -124,7 +124,7 @@ bool kmod_module_signature_info(const struct kmod_file
*file, struct kmod_signat
modsig->id_type >= PKEY_ID_TYPE__LAST)
return false;
sig_len = be32toh(get_unaligned(&modsig->sig_len));
- if (size < (off_t)(modsig->signer_len + modsig->key_id_len + sig_len))
+ if (size < (int64_t)(modsig->signer_len + modsig->key_id_len + sig_len))
return false;
size -= modsig->key_id_len + sig_len;
--
2.3.0
32sig.ko
Description: Binary data
