patch-2.1.11 linux/kernel/module.c
Next file: linux/kernel/panic.c
Previous file: linux/kernel/itimer.c
Back to the patch index
Back to the overall index
- Lines: 151
- Date:
Sat Nov 16 13:11:18 1996
- Orig file:
v2.1.10/linux/kernel/module.c
- Orig date:
Sun Nov 10 20:12:19 1996
diff -u --recursive --new-file v2.1.10/linux/kernel/module.c linux/kernel/module.c
@@ -54,7 +54,6 @@
static int freeing_modules; /* true if some modules are marked for deletion */
static struct module *find_module( const char *name);
-static int get_mod_name( char *user_name, char *buf);
static int free_modules( void);
extern struct symbol_table symbol_table; /* in kernel/ksyms.c */
@@ -75,6 +74,21 @@
kernel_module.name = "";
}
+
+/*
+ * Copy the name of a module from user space.
+ */
+inline int
+get_mod_name(char *user_name, char *buf)
+{
+ /* Should return -EBIG instead of -EFAULT when the name
+ is too long, but that we couldn't detect real faults then.
+ Maybe strncpy_from_user() should return -EBIG, when
+ the source string is too long. */
+ return strncpy_from_user(buf, user_name, MOD_MAX_NAME);
+}
+
+
/*
* Allocate space for a module.
*/
@@ -128,6 +142,7 @@
return (unsigned long) addr;
}
+
/*
* Initialize a module.
*/
@@ -157,7 +172,8 @@
return error;
pr_debug("initializing module `%s', %d (0x%x) bytes\n",
name, codesize, codesize);
- copy_from_user(&rt, routines, sizeof rt);
+ if (copy_from_user(&rt, routines, sizeof rt))
+ return -EFAULT;
if ((mp = find_module(name)) == NULL)
return -ENOENT;
if (codesize & MOD_AUTOCLEAN) {
@@ -170,7 +186,8 @@
}
if ((codesize + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE > mp->size)
return -EINVAL;
- copy_from_user((char *)mp->addr + sizeof (long), code, codesize);
+ if (copy_from_user((char *)mp->addr + sizeof (long), code, codesize))
+ return -EFAULT;
memset((char *)mp->addr + sizeof (long) + codesize, 0,
mp->size * PAGE_SIZE - (codesize + sizeof (long)));
pr_debug("module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
@@ -190,19 +207,17 @@
int i;
int legal_start;
- if ((error = verify_area(VERIFY_READ, &symtab->size, sizeof(symtab->size))))
- return error;
- get_user(size, &symtab->size);
-
+ error = get_user(size, &symtab->size);
+ if (error)
+ return error;
if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
return -ENOMEM;
}
- if ((error = verify_area(VERIFY_READ, symtab, size))) {
- kfree_s(newtab, size);
- return error;
+ if (copy_from_user((char *)(newtab), symtab, size)) {
+ kfree_s(newtab, size);
+ return -EFAULT;
}
- copy_from_user((char *)(newtab), symtab, size);
/* sanity check */
legal_start = sizeof(struct symbol_table) +
@@ -344,6 +359,7 @@
struct module *mp = module_list;
int i;
int nmodsyms = 0;
+ int err;
for (mp = module_list; mp; mp = mp->next) {
if (mp->symtab && mp->symtab->n_symbols) {
@@ -358,16 +374,15 @@
if (table != NULL) {
to = table;
- if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table))))
- return i;
-
/* copy all module symbols first (always LIFO order) */
for (mp = module_list; mp; mp = mp->next) {
if (mp->state == MOD_RUNNING) {
/* magic: write module info as a pseudo symbol */
isym.value = (unsigned long)mp;
sprintf(isym.name, "#%s", mp->name);
- copy_to_user(to, &isym, sizeof isym);
+ err = copy_to_user(to, &isym, sizeof isym);
+ if (err)
+ return -EFAULT;
++to;
if (mp->symtab != NULL) {
@@ -377,7 +392,9 @@
isym.value = (unsigned long)from->addr;
strncpy(isym.name, from->name, sizeof isym.name);
- copy_to_user(to, &isym, sizeof isym);
+ err = copy_to_user(to, &isym, sizeof isym);
+ if (err)
+ return -EFAULT;
}
}
}
@@ -386,27 +403,6 @@
return nmodsyms;
}
-
-
-/*
- * Copy the name of a module from user space.
- */
-int
-get_mod_name(char *user_name, char *buf)
-{
- int i;
-
- i = 0;
- for (;;) {
- get_user(buf[i], user_name + i);
- if (buf[i] == '\0')
- break;
- if (++i >= MOD_MAX_NAME)
- return -E2BIG;
- }
- return 0;
-}
-
/*
* Look for a module by name, ignoring modules marked for deletion.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov