diff --git a/sys/compat/linuxkpi/common/include/linux/module.h b/sys/compat/linuxkpi/common/include/linux/module.h --- a/sys/compat/linuxkpi/common/include/linux/module.h +++ b/sys/compat/linuxkpi/common/include/linux/module.h @@ -33,6 +33,7 @@ #include #include +#include #include #include diff --git a/sys/contrib/rdma/krping/krping_dev.c b/sys/contrib/rdma/krping/krping_dev.c --- a/sys/contrib/rdma/krping/krping_dev.c +++ b/sys/contrib/rdma/krping/krping_dev.c @@ -14,10 +14,10 @@ __FBSDID("$FreeBSD$"); #include +#include /* defines used in kernel.h and module.h */ #include #include /* uprintf */ #include -#include /* defines used in kernel.h */ #include /* types used in module initialization */ #include /* cdevsw struct */ #include /* uio struct */ diff --git a/sys/dev/videomode/videomode.c b/sys/dev/videomode/videomode.c --- a/sys/dev/videomode/videomode.c +++ b/sys/dev/videomode/videomode.c @@ -11,6 +11,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c --- a/sys/fs/fuse/fuse_device.c +++ b/sys/fs/fuse/fuse_device.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include diff --git a/sys/fs/fuse/fuse_io.c b/sys/fs/fuse/fuse_io.c --- a/sys/fs/fuse/fuse_io.c +++ b/sys/fs/fuse/fuse_io.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include diff --git a/sys/fs/fuse/fuse_main.c b/sys/fs/fuse/fuse_main.c --- a/sys/fs/fuse/fuse_main.c +++ b/sys/fs/fuse/fuse_main.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -361,11 +361,19 @@ struct module_stat_v1 { int version; /* set to sizeof(struct module_stat) */ - char name[MAXMODNAME]; + char name[MAXMODNAMEV1V2]; int refs; int id; }; +struct module_stat_v2 { + int version; /* set to sizeof(struct module_stat) */ + char name[MAXMODNAMEV1V2]; + int refs; + int id; + modspecific_t data; +}; + int sys_modstat(struct thread *td, struct modstat_args *uap) { @@ -374,7 +382,9 @@ int error = 0; int id, namelen, refs, version; struct module_stat *stat; + struct module_stat_v2 *stat_v2; char *name; + bool is_v1v2; MOD_SLOCK; mod = module_lookupbyid(uap->modid); @@ -394,27 +404,44 @@ */ if ((error = copyin(&stat->version, &version, sizeof(version))) != 0) return (error); - if (version != sizeof(struct module_stat_v1) - && version != sizeof(struct module_stat)) + is_v1v2 = (version == sizeof(struct module_stat_v1) || + version == sizeof(struct module_stat_v2)); + if (!is_v1v2 && version != sizeof(struct module_stat)) return (EINVAL); namelen = strlen(mod->name) + 1; - if (namelen > MAXMODNAME) - namelen = MAXMODNAME; + if (is_v1v2 && namelen > MAXMODNAMEV1V2) + namelen = MAXMODNAMEV1V2; + else if (namelen > MAXMODNAMEV3) + namelen = MAXMODNAMEV3; if ((error = copyout(name, &stat->name[0], namelen)) != 0) return (error); - if ((error = copyout(&refs, &stat->refs, sizeof(int))) != 0) - return (error); - if ((error = copyout(&id, &stat->id, sizeof(int))) != 0) - return (error); + /* Extending MAXMODNAME gives an offset change for v3. */ + if (is_v1v2) { + stat_v2 = (struct module_stat_v2 *)stat; + if ((error = copyout(&refs, &stat_v2->refs, sizeof(int))) != 0) + return (error); + if ((error = copyout(&id, &stat_v2->id, sizeof(int))) != 0) + return (error); + } else { + if ((error = copyout(&refs, &stat->refs, sizeof(int))) != 0) + return (error); + if ((error = copyout(&id, &stat->id, sizeof(int))) != 0) + return (error); + } /* * >v1 stat includes module data. */ - if (version == sizeof(struct module_stat)) + if (version == sizeof(struct module_stat_v2)) { + if ((error = copyout(&data, &stat_v2->data, + sizeof(data))) != 0) + return (error); + } else if (version == sizeof(struct module_stat)) { if ((error = copyout(&data, &stat->data, sizeof(data))) != 0) return (error); + } td->td_retval[0] = 0; return (error); } @@ -423,7 +450,7 @@ sys_modfind(struct thread *td, struct modfind_args *uap) { int error = 0; - char name[MAXMODNAME]; + char name[MAXMODNAMEV3]; module_t mod; if ((error = copyinstr(uap->name, name, sizeof name, 0)) != 0) @@ -455,6 +482,14 @@ uint32_t ulongval; } modspecific32_t; +struct module_stat32_v2 { + int version; + char name[MAXMODNAMEV1V2]; + int refs; + int id; + modspecific32_t data; +}; + struct module_stat32 { int version; char name[MAXMODNAME]; @@ -471,7 +506,9 @@ int error = 0; int id, namelen, refs, version; struct module_stat32 *stat32; + struct module_stat32_v2 *stat32_v2; char *name; + bool is_v1v2; MOD_SLOCK; mod = module_lookupbyid(uap->modid); @@ -492,27 +529,44 @@ if ((error = copyin(&stat32->version, &version, sizeof(version))) != 0) return (error); - if (version != sizeof(struct module_stat_v1) - && version != sizeof(struct module_stat32)) + is_v1v2 = (version == sizeof(struct module_stat_v1) || + version == sizeof(struct module_stat32_v2)); + if (!is_v1v2 && version != sizeof(struct module_stat32)) return (EINVAL); namelen = strlen(mod->name) + 1; - if (namelen > MAXMODNAME) - namelen = MAXMODNAME; + if (is_v1v2 && namelen > MAXMODNAMEV1V2) + namelen = MAXMODNAMEV1V2; + else if (namelen > MAXMODNAMEV3) + namelen = MAXMODNAMEV3; if ((error = copyout(name, &stat32->name[0], namelen)) != 0) return (error); - if ((error = copyout(&refs, &stat32->refs, sizeof(int))) != 0) - return (error); - if ((error = copyout(&id, &stat32->id, sizeof(int))) != 0) - return (error); + /* Extending MAXMODNAME gives an offset change for v3. */ + if (is_v1v2) { + stat32_v2 = (struct module_stat32_v2 *)stat32; + if ((error = copyout(&refs, &stat32_v2->refs, sizeof(int))) != 0) + return (error); + if ((error = copyout(&id, &stat32_v2->id, sizeof(int))) != 0) + return (error); + } else { + if ((error = copyout(&refs, &stat32->refs, sizeof(int))) != 0) + return (error); + if ((error = copyout(&id, &stat32->id, sizeof(int))) != 0) + return (error); + } /* * >v1 stat includes module data. */ - if (version == sizeof(struct module_stat32)) + if (version == sizeof(struct module_stat32_v2)) { + if ((error = copyout(&data32, &stat32_v2->data, + sizeof(data32))) != 0) + return (error); + } else if (version == sizeof(struct module_stat32)) { if ((error = copyout(&data32, &stat32->data, sizeof(data32))) != 0) return (error); + } td->td_retval[0] = 0; return (error); } diff --git a/sys/sys/module.h b/sys/sys/module.h --- a/sys/sys/module.h +++ b/sys/sys/module.h @@ -253,7 +253,9 @@ #endif #endif /* _KERNEL */ -#define MAXMODNAME 32 +#define MAXMODNAMEV1V2 32 +#define MAXMODNAMEV3 MAXPATHLEN +#define MAXMODNAME MAXMODNAMEV3 struct module_stat { int version; /* set to sizeof(struct module_stat) */ diff --git a/sys/x86/cpufreq/hwpstate_intel.c b/sys/x86/cpufreq/hwpstate_intel.c --- a/sys/x86/cpufreq/hwpstate_intel.c +++ b/sys/x86/cpufreq/hwpstate_intel.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include