From 74712770546bf340a05465b7c9df2920c307fe8c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 13 Feb 2008 21:34:06 +0000 Subject: [PATCH] Add an automatic kernel module version dependency to prevent loading modules using invalid ABI versions (e.g. a 7.x module with an 8.x kernel) for a given kernel: - Add a 'kernel' module version whose value is __FreeBSD_version. - Add a version dependency on 'kernel' in every module that has an acceptable version range of __FreeBSD_version up to the end of the branch __FreeBSD_version is part of. E.g. a module compiled on 701000 would work on kernels with versions between 701000 and 799999 inclusive. Discussed on: arch@ MFC after: 1 week --- sys/kern/kern_module.c | 2 ++ sys/sys/module.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index 9a1f159e3060..72a6991dd20d 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -414,6 +414,8 @@ modfind(struct thread *td, struct modfind_args *uap) return (error); } +MODULE_VERSION(kernel, __FreeBSD_version); + #ifdef COMPAT_IA32 #include #include diff --git a/sys/sys/module.h b/sys/sys/module.h index b621ba3d12e6..bcffb452905b 100644 --- a/sys/sys/module.h +++ b/sys/sys/module.h @@ -114,7 +114,20 @@ struct mod_metadata { MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND, \ &_##module##_depend_on_##mdepend, #mdepend) +/* + * Every kernel has a 'kernel' module with the version set to + * __FreeBSD_version. We embed a MODULE_DEPEND() inside every module + * that depends on the 'kernel' module. It uses the current value of + * __FreeBSD_version as the minimum and preferred versions. For the + * maximum version it rounds the version up to the end of its branch + * (i.e. M99999 for M.x). This allows a module built on M.x to work + * on M.y systems where y >= x, but fail on M.z systems where z < x. + */ +#define MODULE_KERNEL_MAXVER (roundup(__FreeBSD_version, 100000) - 1) + #define DECLARE_MODULE(name, data, sub, order) \ + MODULE_DEPEND(name, kernel, __FreeBSD_version, \ + __FreeBSD_version, MODULE_KERNEL_MAXVER); \ MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name); \ SYSINIT(name##module, sub, order, module_register_init, &data) \ struct __hack