root/kernel/module.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_modules
  2. rename_module_symbol
  3. sys_create_module
  4. sys_init_module
  5. sys_delete_module
  6. sys_get_kernel_syms
  7. get_mod_name
  8. find_module
  9. drop_refs
  10. free_modules
  11. get_module_list
  12. get_ksyms_list

   1 #include <linux/errno.h>
   2 #include <linux/kernel.h>
   3 #include <asm/segment.h>
   4 #include <linux/mm.h>           /* defines GFP_KERNEL */
   5 #include <linux/string.h>
   6 #include <linux/module.h>
   7 #include <linux/sched.h>
   8 #include <linux/malloc.h>
   9 /*
  10  * Originally by Anonymous (as far as I know...)
  11  * Linux version by Bas Laarhoven <bas@vimec.nl>
  12  * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
  13  *
  14  * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
  15  * This source is covered by the GNU GPL, the same as all kernel sources.
  16  *
  17  * Features:
  18  *      - Supports stacked modules (removable only of there are no dependents).
  19  *      - Supports table of symbols defined by the modules.
  20  *      - Supports /proc/ksyms, showing value, name and owner of all
  21  *        the symbols defined by all modules (in stack order).
  22  *      - Added module dependencies information into /proc/modules
  23  *      - Supports redefines of all symbols, for streams-like behaviour.
  24  *      - Compatible with older versions of insmod.
  25  *
  26  */
  27 
  28 #ifdef DEBUG_MODULE
  29 #define PRINTK(a) printk a
  30 #else
  31 #define PRINTK(a) /* */
  32 #endif
  33 
  34 static struct module kernel_module;
  35 static struct module *module_list = &kernel_module;
  36 
  37 static int freeing_modules; /* true if some modules are marked for deletion */
  38 
  39 static struct module *find_module( const char *name);
  40 static int get_mod_name( char *user_name, char *buf);
  41 static int free_modules( void);
  42 
  43 
  44 /*
  45  * Called at boot time
  46  */
  47 void init_modules(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
  48         extern struct symbol_table symbol_table; /* in kernel/ksyms.c */
  49         struct internal_symbol *sym;
  50         int i;
  51 
  52         for (i = 0, sym = symbol_table.symbol; sym->name; ++sym, ++i)
  53                 ;
  54         symbol_table.n_symbols = i;
  55 
  56         kernel_module.symtab = &symbol_table;
  57         kernel_module.state = MOD_RUNNING; /* Hah! */
  58         kernel_module.name = "";
  59 }
  60 
  61 int
  62 rename_module_symbol(char *old_name, char *new_name)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64         struct internal_symbol *sym;
  65         int i = 0; /* keep gcc silent */
  66 
  67         if (module_list->symtab) {
  68                 sym = module_list->symtab->symbol;
  69                 for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) {
  70                         if (strcmp(sym->name, old_name) == 0) { /* found it! */
  71                                 sym->name = new_name; /* done! */
  72                                 PRINTK(("renamed %s to %s\n", old_name, new_name));
  73                                 return 1; /* it worked! */
  74                         }
  75                 }
  76         }
  77         printk("rename %s to %s failed!\n", old_name, new_name);
  78         return 0; /* not there... */
  79 
  80         /*
  81          * This one will change the name of the first matching symbol!
  82          *
  83          * With this function, you can replace the name of a symbol defined
  84          * in the current module with a new name, e.g. when you want to insert
  85          * your own function instead of a previously defined function
  86          * with the same name.
  87          *
  88          * "Normal" usage:
  89          *
  90          * bogus_function(int params)
  91          * {
  92          *      do something "smart";
  93          *      return real_function(params);
  94          * }
  95          *
  96          * ...
  97          *
  98          * init_module()
  99          * {
 100          *      if (rename_module_symbol("_bogus_function", "_real_function"))
 101          *              printk("yep!\n");
 102          *      else
 103          *              printk("no way!\n");
 104          * ...
 105          * }
 106          *
 107          * When loading this module, real_function will be resolved
 108          * to the real function address.
 109          * All later loaded modules that refer to "real_function()" will
 110          * then really call "bogus_function()" instead!!!
 111          *
 112          * This feature will give you ample opportunities to get to know
 113          * the taste of your foot when you stuff it into your mouth!!!
 114          */
 115 }
 116 
 117 /*
 118  * Allocate space for a module.
 119  */
 120 asmlinkage unsigned long
 121 sys_create_module(char *module_name, unsigned long size)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123         struct module *mp;
 124         void* addr;
 125         int error;
 126         int npages;
 127         int sspace = sizeof(struct module) + MOD_MAX_NAME;
 128         char name[MOD_MAX_NAME];
 129 
 130         if (!suser())
 131                 return -EPERM;
 132         if (module_name == NULL || size == 0)
 133                 return -EINVAL;
 134         if ((error = get_mod_name(module_name, name)) != 0)
 135                 return error;
 136         if (find_module(name) != NULL) {
 137                 return -EEXIST;
 138         }
 139 
 140         if ((mp = (struct module*) kmalloc(sspace, GFP_KERNEL)) == NULL) {
 141                 return -ENOMEM;
 142         }
 143         strcpy((char *)(mp + 1), name); /* why not? */
 144 
 145         npages = (size + sizeof (int) + 4095) / 4096;
 146         if ((addr = vmalloc(npages * 4096)) == 0) {
 147                 kfree_s(mp, sspace);
 148                 return -ENOMEM;
 149         }
 150 
 151         mp->next = module_list;
 152         mp->ref = NULL;
 153         mp->symtab = NULL;
 154         mp->name = (char *)(mp + 1);
 155         mp->size = npages;
 156         mp->addr = addr;
 157         mp->state = MOD_UNINITIALIZED;
 158         mp->cleanup = NULL;
 159 
 160         * (int *) addr = 0;     /* set use count to zero */
 161         module_list = mp;       /* link it in */
 162 
 163         PRINTK(("module `%s' (%lu pages @ 0x%08lx) created\n",
 164                 mp->name, (unsigned long) mp->size, (unsigned long) mp->addr));
 165         return (unsigned long) addr;
 166 }
 167 
 168 /*
 169  * Initialize a module.
 170  */
 171 asmlinkage int
 172 sys_init_module(char *module_name, char *code, unsigned codesize,
     /* [previous][next][first][last][top][bottom][index][help] */
 173                 struct mod_routines *routines,
 174                 struct symbol_table *symtab)
 175 {
 176         struct module *mp;
 177         struct symbol_table *newtab;
 178         char name[MOD_MAX_NAME];
 179         int error;
 180         struct mod_routines rt;
 181 
 182         if (!suser())
 183                 return -EPERM;
 184 
 185         /* A little bit of protection... we "know" where the user stack is... */
 186         if (symtab && ((unsigned long)symtab > 0xb0000000)) {
 187                 printk("warning: you are using an old insmod, no symbols will be inserted!\n");
 188                 symtab = NULL;
 189         }
 190 
 191         /*
 192          * First reclaim any memory from dead modules that where not
 193          * freed when deleted. Should I think be done by timers when
 194          * the module was deleted - Jon.
 195          */
 196         free_modules();
 197 
 198         if ((error = get_mod_name(module_name, name)) != 0)
 199                 return error;
 200         PRINTK(("initializing module `%s', %d (0x%x) bytes\n",
 201                 name, codesize, codesize));
 202         memcpy_fromfs(&rt, routines, sizeof rt);
 203         if ((mp = find_module(name)) == NULL)
 204                 return -ENOENT;
 205         if ((codesize + sizeof (int) + 4095) / 4096 > mp->size)
 206                 return -EINVAL;
 207         memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize);
 208         memset((char *)mp->addr + sizeof (int) + codesize, 0,
 209                 mp->size * 4096 - (codesize + sizeof (int)));
 210         PRINTK(( "module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
 211                 (unsigned long) rt.init, (unsigned long) rt.cleanup));
 212         mp->cleanup = rt.cleanup;
 213 
 214         /* update kernel symbol table */
 215         if (symtab) { /* symtab == NULL means no new entries to handle */
 216                 struct internal_symbol *sym;
 217                 struct module_ref *ref;
 218                 int size;
 219                 int i;
 220                 int legal_start;
 221 
 222                 if ((error = verify_area(VERIFY_READ, symtab, sizeof(int))))
 223                         return error;
 224                 memcpy_fromfs((char *)(&(size)), symtab, sizeof(int));
 225 
 226                 if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
 227                         return -ENOMEM;
 228                 }
 229 
 230                 if ((error = verify_area(VERIFY_READ, symtab, size))) {
 231                         kfree_s(newtab, size);
 232                         return error;
 233                 }
 234                 memcpy_fromfs((char *)(newtab), symtab, size);
 235 
 236                 /* sanity check */
 237                 legal_start = sizeof(struct symbol_table) +
 238                         newtab->n_symbols * sizeof(struct internal_symbol) +
 239                         newtab->n_refs * sizeof(struct module_ref);
 240 
 241                 if ((newtab->n_symbols < 0) || (newtab->n_refs < 0) ||
 242                         (legal_start > size)) {
 243                         printk("Illegal symbol table! Rejected!\n");
 244                         kfree_s(newtab, size);
 245                         return -EINVAL;
 246                 }
 247 
 248                 /* relocate name pointers, index referred from start of table */
 249                 for (sym = &(newtab->symbol[0]), i = 0;
 250                         i < newtab->n_symbols; ++sym, ++i) {
 251                         if ((unsigned long)sym->name < legal_start || size <= (unsigned long)sym->name) {
 252                                 printk("Illegal symbol table! Rejected!\n");
 253                                 kfree_s(newtab, size);
 254                                 return -EINVAL;
 255                         }
 256                         /* else */
 257                         sym->name += (long)newtab;
 258                 }
 259                 mp->symtab = newtab;
 260 
 261                 /* Update module references.
 262                  * On entry, from "insmod", ref->module points to
 263                  * the referenced module!
 264                  * Now it will point to the current module instead!
 265                  * The ref structure becomes the first link in the linked
 266                  * list of references to the referenced module.
 267                  * Also, "sym" from above, points to the first ref entry!!!
 268                  */
 269                 for (ref = (struct module_ref *)sym, i = 0;
 270                         i < newtab->n_refs; ++ref, ++i) {
 271 
 272                         /* Check for valid reference */
 273                         struct module *link = module_list;
 274                         while (link && (ref->module != link))
 275                                 link = link->next;
 276 
 277                         if (link == (struct module *)0) {
 278                                 printk("Non-module reference! Rejected!\n");
 279                                 return -EINVAL;
 280                         }
 281 
 282                         ref->next = ref->module->ref;
 283                         ref->module->ref = ref;
 284                         ref->module = mp;
 285                 }
 286         }
 287 
 288         if ((*rt.init)() != 0)
 289                 return -EBUSY;
 290         mp->state = MOD_RUNNING;
 291 
 292         return 0;
 293 }
 294 
 295 asmlinkage int
 296 sys_delete_module(char *module_name)
     /* [previous][next][first][last][top][bottom][index][help] */
 297 {
 298         struct module *mp;
 299         char name[MOD_MAX_NAME];
 300         int error;
 301 
 302         if (!suser())
 303                 return -EPERM;
 304         /* else */
 305         if (module_name != NULL) {
 306                 if ((error = get_mod_name(module_name, name)) != 0)
 307                         return error;
 308                 if ((mp = find_module(name)) == NULL)
 309                         return -ENOENT;
 310                 if ((mp->ref != NULL) || (GET_USE_COUNT(mp) != 0))
 311                         return -EBUSY;
 312                 if (mp->state == MOD_RUNNING)
 313                         (*mp->cleanup)();
 314                 mp->state = MOD_DELETED;
 315         }
 316         free_modules();
 317         return 0;
 318 }
 319 
 320 
 321 /*
 322  * Copy the kernel symbol table to user space.  If the argument is null,
 323  * just return the size of the table.
 324  *
 325  * Note that the transient module symbols are copied _first_,
 326  * in lifo order!!!
 327  *
 328  * The symbols to "insmod" are according to the "old" format: struct kernel_sym,
 329  * which is actually quite handy for this purpose.
 330  * Note that insmod inserts a struct symbol_table later on...
 331  * (as that format is quite handy for the kernel...)
 332  *
 333  * For every module, the first (pseudo)symbol copied is the module name
 334  * and the address of the module struct.
 335  * This lets "insmod" keep track of references, and build the array of
 336  * struct module_refs in the symbol table.
 337  * The format of the module name is "#module", so that "insmod" can easily
 338  * notice when a module name comes along. Also, this will make it possible
 339  * to use old versions of "insmod", albeit with reduced functionality...
 340  * The "kernel" module has an empty name.
 341  */
 342 asmlinkage int
 343 sys_get_kernel_syms(struct kernel_sym *table)
     /* [previous][next][first][last][top][bottom][index][help] */
 344 {
 345         struct internal_symbol *from;
 346         struct kernel_sym isym;
 347         struct kernel_sym *to;
 348         struct module *mp = module_list;
 349         int i;
 350         int nmodsyms = 0;
 351 
 352         for (mp = module_list; mp; mp = mp->next) {
 353                 if (mp->symtab && mp->symtab->n_symbols) {
 354                         /* include the count for the module name! */
 355                         nmodsyms += mp->symtab->n_symbols + 1;
 356                 }
 357         }
 358 
 359         if (table != NULL) {
 360                 to = table;
 361 
 362                 if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table))))
 363                         return i;
 364 
 365                 /* copy all module symbols first (always LIFO order) */
 366                 for (mp = module_list; mp; mp = mp->next) {
 367                         if ((mp->state == MOD_RUNNING) &&
 368                                 (mp->symtab != NULL) && (mp->symtab->n_symbols > 0)) {
 369                                 /* magic: write module info as a pseudo symbol */
 370                                 isym.value = (unsigned long)mp;
 371                                 sprintf(isym.name, "#%s", mp->name);
 372                                 memcpy_tofs(to, &isym, sizeof isym);
 373                                 ++to;
 374 
 375                                 for (i = mp->symtab->n_symbols,
 376                                         from = mp->symtab->symbol;
 377                                         i > 0; --i, ++from, ++to) {
 378 
 379                                         isym.value = (unsigned long)from->addr;
 380                                         strncpy(isym.name, from->name, sizeof isym.name);
 381                                         memcpy_tofs(to, &isym, sizeof isym);
 382                                 }
 383                         }
 384                 }
 385         }
 386 
 387         return nmodsyms;
 388 }
 389 
 390 
 391 /*
 392  * Copy the name of a module from user space.
 393  */
 394 int
 395 get_mod_name(char *user_name, char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 396 {
 397         int i;
 398 
 399         i = 0;
 400         for (i = 0 ; (buf[i] = get_fs_byte(user_name + i)) != '\0' ; ) {
 401                 if (++i >= MOD_MAX_NAME)
 402                         return -E2BIG;
 403         }
 404         return 0;
 405 }
 406 
 407 
 408 /*
 409  * Look for a module by name, ignoring modules marked for deletion.
 410  */
 411 struct module *
 412 find_module( const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 413 {
 414         struct module *mp;
 415 
 416         for (mp = module_list ; mp ; mp = mp->next) {
 417                 if (mp->state == MOD_DELETED)
 418                         continue;
 419                 if (!strcmp(mp->name, name))
 420                         break;
 421         }
 422         return mp;
 423 }
 424 
 425 static void
 426 drop_refs(struct module *mp)
     /* [previous][next][first][last][top][bottom][index][help] */
 427 {
 428         struct module *step;
 429         struct module_ref *prev;
 430         struct module_ref *ref;
 431 
 432         for (step = module_list; step; step = step->next) {
 433                 for (prev = ref = step->ref; ref; ref = prev->next) {
 434                         if (ref->module == mp) {
 435                                 if (ref == step->ref)
 436                                         step->ref = ref->next;
 437                                 else
 438                                         prev->next = ref->next;
 439                                 break; /* every module only references once! */
 440                         }
 441                         else
 442                                 prev = ref;
 443                 }
 444         }
 445 }
 446 
 447 /*
 448  * Try to free modules which have been marked for deletion.  Returns nonzero
 449  * if a module was actually freed.
 450  */
 451 int
 452 free_modules( void)
     /* [previous][next][first][last][top][bottom][index][help] */
 453 {
 454         struct module *mp;
 455         struct module **mpp;
 456         int did_deletion;
 457 
 458         did_deletion = 0;
 459         freeing_modules = 0;
 460         mpp = &module_list;
 461         while ((mp = *mpp) != NULL) {
 462                 if (mp->state != MOD_DELETED) {
 463                         mpp = &mp->next;
 464                 } else {
 465                         if (GET_USE_COUNT(mp) != 0) {
 466                                 freeing_modules = 1;
 467                                 mpp = &mp->next;
 468                         } else {        /* delete it */
 469                                 *mpp = mp->next;
 470                                 if (mp->symtab) {
 471                                         if (mp->symtab->n_refs)
 472                                                 drop_refs(mp);
 473                                         if (mp->symtab->size)
 474                                                 kfree_s(mp->symtab, mp->symtab->size);
 475                                 }
 476                                 vfree(mp->addr);
 477                                 kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME);
 478                                 did_deletion = 1;
 479                         }
 480                 }
 481         }
 482         return did_deletion;
 483 }
 484 
 485 
 486 /*
 487  * Called by the /proc file system to return a current list of modules.
 488  */
 489 int get_module_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 490 {
 491         char *p;
 492         char *q;
 493         int i;
 494         struct module *mp;
 495         struct module_ref *ref;
 496         char size[32];
 497 
 498         p = buf;
 499         /* Do not show the kernel pseudo module */
 500         for (mp = module_list ; mp && mp->next; mp = mp->next) {
 501                 if (p - buf > 4096 - 100)
 502                         break;                  /* avoid overflowing buffer */
 503                 q = mp->name;
 504                 i = 20;
 505                 while (*q) {
 506                         *p++ = *q++;
 507                         i--;
 508                 }
 509                 sprintf(size, "%d", mp->size);
 510                 i -= strlen(size);
 511                 if (i <= 0)
 512                         i = 1;
 513                 while (--i >= 0)
 514                         *p++ = ' ';
 515                 q = size;
 516                 while (*q)
 517                         *p++ = *q++;
 518                 if (mp->state == MOD_UNINITIALIZED)
 519                         q = "  (uninitialized)";
 520                 else if (mp->state == MOD_RUNNING)
 521                         q = "";
 522                 else if (mp->state == MOD_DELETED)
 523                         q = "  (deleted)";
 524                 else
 525                         q = "  (bad state)";
 526                 while (*q)
 527                         *p++ = *q++;
 528 
 529                 if ((ref = mp->ref) != NULL) {
 530                         *p++ = '\t';
 531                         *p++ = '[';
 532                         for (; ref; ref = ref->next) {
 533                                 q = ref->module->name;
 534                                 while (*q)
 535                                         *p++ = *q++;
 536                                 if (ref->next)
 537                                         *p++ = ' ';
 538                         }
 539                         *p++ = ']';
 540                 }
 541                 *p++ = '\n';
 542         }
 543         return p - buf;
 544 }
 545 
 546 
 547 /*
 548  * Called by the /proc file system to return a current list of ksyms.
 549  */
 550 int get_ksyms_list(char *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 551 {
 552         struct module *mp;
 553         struct internal_symbol *sym;
 554         int i;
 555         char *p = buf;
 556 
 557         for (mp = module_list; mp; mp = mp->next) {
 558                 if ((mp->state == MOD_RUNNING) &&
 559                         (mp->symtab != NULL) && (mp->symtab->n_symbols > 0)) {
 560                         for (i = mp->symtab->n_symbols,
 561                                 sym = mp->symtab->symbol;
 562                                 i > 0; --i, ++sym) {
 563 
 564                                 if (p - buf > 4096 - 100) {
 565                                         strcat(p, "...\n");
 566                                         p += strlen(p);
 567                                         return p - buf; /* avoid overflowing buffer */
 568                                 }
 569 
 570                                 if (mp->name[0]) {
 571                                         sprintf(p, "%08lx %s\t[%s]\n",
 572                                                 (long)sym->addr, sym->name, mp->name);
 573                                 }
 574                                 else {
 575                                         sprintf(p, "%08lx %s\n",
 576                                                 (long)sym->addr, sym->name);
 577                                 }
 578                                 p += strlen(p);
 579                         }
 580                 }
 581         }
 582 
 583         return p - buf;
 584 }

/* [previous][next][first][last][top][bottom][index][help] */