Page MenuHomeFreeBSD

D61432.1794494821.diff
No OneTemporary

Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None

D61432.1794494821.diff

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
@@ -357,6 +357,7 @@
return (error);
}
+#ifdef COMPAT_43 /* XXX - COMPAT_FREEBSD2 */
struct module_stat_v1 {
int version; /* set to sizeof(struct module_stat) */
char name[MAXMODNAMEV1V2];
@@ -364,6 +365,18 @@
int id;
};
+static void
+module2module_stat_v1(module_t mod, struct module_stat_v1 *stat)
+{
+ stat->version = sizeof(*stat);
+ /* Not necessarily NUL-terminated */
+ strncpy(stat->name, mod->name, sizeof(stat->name));
+ stat->refs = mod->refs;
+ stat->id = mod->id;
+}
+#endif
+
+#ifdef COMPAT_FREEBSD13
struct module_stat_v2 {
int version; /* set to sizeof(struct module_stat) */
char name[MAXMODNAMEV1V2];
@@ -372,6 +385,29 @@
modspecific_t data;
};
+static void
+module2module_stat_v2(module_t mod, struct module_stat_v2 *stat)
+{
+ stat->version = sizeof(*stat);
+ /* Not necessarily NUL-terminated */
+ strncpy(stat->name, mod->name, sizeof(stat->name));
+ stat->refs = mod->refs;
+ stat->id = mod->id;
+ stat->data = mod->data;
+}
+#endif
+
+static void
+module2module_stat(module_t mod, struct module_stat *stat)
+{
+ stat->version = sizeof(*stat);
+ /* Not necessarily NUL-terminated */
+ strncpy(stat->name, mod->name, sizeof(stat->name));
+ stat->refs = mod->refs;
+ stat->id = mod->id;
+ stat->data = mod->data;
+}
+
int
sys_modstat(struct thread *td, struct modstat_args *uap)
{
@@ -382,76 +418,68 @@
kern_modstat(struct thread *td, int modid, struct module_stat *stat)
{
module_t mod;
- modspecific_t data;
int error = 0;
- int id, namelen, refs, version;
- struct module_stat_v2 *stat_v2;
- char *name, *user_namep;
- bool is_v1v2;
+ int version;
+ void *statbuf;
+ /* Look up first to preserve historic error priority */
MOD_SLOCK;
mod = module_lookupbyid(modid);
- if (mod == NULL) {
- error = ENOENT;
- goto out;
- }
- id = mod->id;
- refs = mod->refs;
- name = mod->name;
- data = mod->data;
+ MOD_SUNLOCK;
+ if (mod == NULL)
+ return (ENOENT);
/*
* Check the version of the user's structure.
*/
if ((error = copyin(&stat->version, &version, sizeof(version))) != 0)
- goto out;
- is_v1v2 = (version == sizeof(struct module_stat_v1) ||
- version == sizeof(struct module_stat_v2));
- if (!is_v1v2 && version != sizeof(struct module_stat)) {
- error = EINVAL;
- goto out;
+ return (error);
+
+ switch (version) {
+ case sizeof(struct module_stat):
+#ifdef COMPAT_FREEBSD13
+ case sizeof(struct module_stat_v2):
+#endif
+#ifdef COMPAT_43 /* XXX - COMPAT_FREEBSD2 */
+ case sizeof(struct module_stat_v1):
+#endif
+ statbuf = malloc(version, M_TEMP, M_WAITOK | M_ZERO);
+ break;
+ default:
+ return (EINVAL);
}
- if (is_v1v2)
- user_namep = ((struct module_stat_v1 *)stat)->name;
- else
- user_namep = stat->name;
- namelen = strlen(mod->name) + 1;
- if (is_v1v2 && namelen > MAXMODNAMEV1V2)
- namelen = MAXMODNAMEV1V2;
- else if (namelen > MAXMODNAMEV3)
- namelen = MAXMODNAMEV3;
- if ((error = copyout(name, user_namep, namelen)) != 0)
- goto out;
- /* 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)
- goto out;
- if ((error = copyout(&id, &stat_v2->id, sizeof(int))) != 0)
- goto out;
- } else {
- if ((error = copyout(&refs, &stat->refs, sizeof(int))) != 0)
- goto out;
- if ((error = copyout(&id, &stat->id, sizeof(int))) != 0)
- goto out;
+ MOD_SLOCK;
+ mod = module_lookupbyid(modid);
+ if (mod == NULL) {
+ MOD_SUNLOCK;
+ error = ENOENT;
+ goto out;
}
- /*
- * >v1 stat includes module data.
- */
- if (version == sizeof(struct module_stat_v2)) {
- if ((error = copyout(&data, &stat_v2->data,
- sizeof(data))) != 0)
- goto out;
- } else if (version == sizeof(struct module_stat)) {
- if ((error = copyout(&data, &stat->data,
- sizeof(data))) != 0)
- goto out;
+ switch (version) {
+ case sizeof(struct module_stat):
+ module2module_stat(mod, statbuf);
+ break;
+#ifdef COMPAT_FREEBSD13
+ case sizeof(struct module_stat_v2):
+ module2module_stat_v2(mod, statbuf);
+ break;
+#endif
+#ifdef COMPAT_43 /* XXX - COMPAT_FREEBSD2 */
+ case sizeof(struct module_stat_v1):
+ module2module_stat_v1(mod, statbuf);
+ break;
+#endif
}
+ MOD_SUNLOCK;
+
+ if ((error = copyout(statbuf, stat, version)) != 0)
+ goto out;
+
td->td_retval[0] = 0;
out:
- MOD_SUNLOCK;
+ free(statbuf, M_TEMP);
return (error);
}
@@ -497,6 +525,7 @@
uint32_t ulongval;
} modspecific32_t;
+#ifdef COMPAT_FREEBSD13
struct module_stat32_v2 {
int version;
char name[MAXMODNAMEV1V2];
@@ -505,6 +534,18 @@
modspecific32_t data;
};
+static void
+module2module_stat32_v2(module_t mod, struct module_stat32_v2 *stat)
+{
+ stat->version = sizeof(*stat);
+ /* Not necessarily NUL-terminated */
+ strncpy(stat->name, mod->name, sizeof(stat->name));
+ stat->refs = mod->refs;
+ stat->id = mod->id;
+ stat->data.uintval = mod->data.uintval;
+}
+#endif
+
struct module_stat32 {
int version;
char name[MAXMODNAME];
@@ -513,75 +554,79 @@
modspecific32_t data;
};
+static void
+module2module_stat32(module_t mod, struct module_stat32 *stat)
+{
+ stat->version = sizeof(*stat);
+ /* Not necessarily NUL-terminated */
+ strncpy(stat->name, mod->name, sizeof(stat->name));
+ stat->refs = mod->refs;
+ stat->id = mod->id;
+ stat->data.uintval = mod->data.uintval;
+}
+
int
freebsd32_modstat(struct thread *td, struct freebsd32_modstat_args *uap)
{
module_t mod;
- modspecific32_t data32;
int error = 0;
- int id, namelen, refs, version;
+ int version;
+ void *statbuf;
struct module_stat32 *stat32;
- struct module_stat32_v2 *stat32_v2;
- char *name;
- bool is_v1v2;
+ /* Look up first to preserve historic error priority */
MOD_SLOCK;
mod = module_lookupbyid(uap->modid);
- if (mod == NULL) {
- error = ENOENT;
- goto out;
- }
+ MOD_SUNLOCK;
+ if (mod == NULL)
+ return (ENOENT);
- id = mod->id;
- refs = mod->refs;
- name = mod->name;
- _Static_assert(sizeof(data32) == sizeof(data32.uintval),
- "bad modspecific32_t size");
- CP(mod->data, data32, uintval);
stat32 = uap->stat;
-
if ((error = copyin(&stat32->version, &version, sizeof(version))) != 0)
- goto out;
- is_v1v2 = (version == sizeof(struct module_stat_v1) ||
- version == sizeof(struct module_stat32_v2));
- if (!is_v1v2 && version != sizeof(struct module_stat32)) {
- error = EINVAL;
- goto out;
+ return (error);
+
+ switch (version) {
+ case sizeof(struct module_stat32):
+#ifdef COMPAT_FREEBSD13
+ case sizeof(struct module_stat32_v2):
+#endif
+#ifdef COMPAT_43 /* XXX - COMPAT_FREEBSD2 */
+ case sizeof(struct module_stat_v1):
+#endif
+ statbuf = malloc(version, M_TEMP, M_WAITOK | M_ZERO);
+ break;
+ default:
+ return (EINVAL);
}
- namelen = strlen(mod->name) + 1;
- if (is_v1v2 && namelen > MAXMODNAMEV1V2)
- namelen = MAXMODNAMEV1V2;
- else if (namelen > MAXMODNAMEV3)
- namelen = MAXMODNAMEV3;
- if ((error = copyout(name, &stat32->name[0], namelen)) != 0)
- goto out;
- /* 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)
- goto out;
- if ((error = copyout(&id, &stat32_v2->id, sizeof(int))) != 0)
- goto out;
- } else {
- if ((error = copyout(&refs, &stat32->refs, sizeof(int))) != 0)
- goto out;
- if ((error = copyout(&id, &stat32->id, sizeof(int))) != 0)
- goto out;
+ MOD_SLOCK;
+ mod = module_lookupbyid(uap->modid);
+ if (mod == NULL) {
+ MOD_SUNLOCK;
+ error = ENOENT;
+ goto out;
}
- /*
- * >v1 stat includes module data.
- */
- if (version == sizeof(struct module_stat32_v2)) {
- if ((error = copyout(&data32, &stat32_v2->data,
- sizeof(data32))) != 0)
- goto out;
- } else if (version == sizeof(struct module_stat32)) {
- if ((error = copyout(&data32, &stat32->data,
- sizeof(data32))) != 0)
- goto out;
+ switch (version) {
+ case sizeof(struct module_stat32):
+ module2module_stat32(mod, statbuf);
+ break;
+#ifdef COMPAT_FREEBSD13
+ case sizeof(struct module_stat32_v2):
+ module2module_stat32_v2(mod, statbuf);
+ break;
+#endif
+#ifdef COMPAT_43 /* XXX - COMPAT_FREEBSD2 */
+ case sizeof(struct module_stat_v1):
+ module2module_stat_v1(mod, statbuf);
+ break;
+#endif
}
+ MOD_SUNLOCK;
+
+ if ((error = copyout(statbuf, stat32, version)) != 0)
+ goto out;
+
td->td_retval[0] = 0;
out:
MOD_SUNLOCK;

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 12, 2:47 PM (6 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41676015
Default Alt Text
D61432.1794494821.diff (8 KB)

Event Timeline