linux-old/kernel/module.c
<<
>>
Prefs
   1#include <linux/errno.h>
   2#include <linux/kernel.h>
   3#include <linux/mm.h>           /* defines GFP_KERNEL */
   4#include <linux/string.h>
   5#include <linux/module.h>
   6#include <linux/sched.h>
   7#include <linux/config.h>
   8#include <asm/uaccess.h>
   9#include <linux/vmalloc.h>
  10#include <linux/smp.h>
  11#include <linux/smp_lock.h>
  12#include <asm/pgtable.h>
  13
  14/*
  15 * Originally by Anonymous (as far as I know...)
  16 * Linux version by Bas Laarhoven <bas@vimec.nl>
  17 * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
  18 * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
  19 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
  20 *
  21 * This source is covered by the GNU GPL, the same as all kernel sources.
  22 */
  23
  24#ifdef CONFIG_MODULES           /* a *big* #ifdef block... */
  25
  26extern struct module_symbol __start___ksymtab[];
  27extern struct module_symbol __stop___ksymtab[];
  28
  29extern const struct exception_table_entry __start___ex_table[];
  30extern const struct exception_table_entry __stop___ex_table[];
  31
  32static struct module kernel_module =
  33{
  34        sizeof(struct module),  /* size_of_struct */
  35        NULL,                   /* next */
  36        "",                     /* name */
  37        0,                      /* size */
  38        1,                      /* usecount */
  39        MOD_RUNNING,            /* flags */
  40        0,                      /* nsyms -- to filled in in init_modules */
  41        0,                      /* ndeps */
  42        __start___ksymtab,      /* syms */
  43        NULL,                   /* deps */
  44        NULL,                   /* refs */
  45        NULL,                   /* init */
  46        NULL,                   /* cleanup */
  47        __start___ex_table,     /* ex_table_start */
  48        __stop___ex_table,      /* ex_table_end */
  49        /* Rest are NULL */
  50};
  51
  52struct module *module_list = &kernel_module;
  53
  54static long get_mod_name(const char *user_name, char **buf);
  55static void put_mod_name(char *buf);
  56static struct module *find_module(const char *name);
  57static void free_module(struct module *);
  58
  59
  60/*
  61 * Called at boot time
  62 */
  63
  64void init_modules(void)
  65{
  66        kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
  67
  68#ifdef __alpha__
  69        __asm__("stq $29,%0" : "=m"(kernel_module.gp));
  70#endif
  71}
  72
  73/*
  74 * Copy the name of a module from user space.
  75 */
  76
  77static inline long
  78get_mod_name(const char *user_name, char **buf)
  79{
  80        unsigned long page;
  81        long retval;
  82
  83        if ((unsigned long)user_name >= TASK_SIZE
  84            && get_fs () != KERNEL_DS)
  85                return -EFAULT;
  86
  87        page = __get_free_page(GFP_KERNEL);
  88        if (!page)
  89                return -ENOMEM;
  90
  91        retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
  92        if (retval > 0) {
  93                if (retval < PAGE_SIZE) {
  94                        *buf = (char *)page;
  95                        return retval;
  96                }
  97                retval = -ENAMETOOLONG;
  98        } else if (!retval)
  99                retval = -EINVAL;
 100
 101        free_page(page);
 102        return retval;
 103}
 104
 105static inline void
 106put_mod_name(char *buf)
 107{
 108        free_page((unsigned long)buf);
 109}
 110
 111/*
 112 * Allocate space for a module.
 113 */
 114
 115asmlinkage unsigned long
 116sys_create_module(const char *name_user, size_t size)
 117{
 118        char *name;
 119        long namelen, error;
 120        struct module *mod;
 121
 122        lock_kernel();
 123        if (!suser()) {
 124                error = -EPERM;
 125                goto err0;
 126        }
 127        if ((namelen = get_mod_name(name_user, &name)) < 0) {
 128                error = namelen;
 129                goto err0;
 130        }
 131        if (size < sizeof(struct module)+namelen) {
 132                error = -EINVAL;
 133                goto err1;
 134        }
 135        if (find_module(name) != NULL) {
 136                error = -EEXIST;
 137                goto err1;
 138        }
 139        if ((mod = (struct module *)module_map(size)) == NULL) {
 140                error = -ENOMEM;
 141                goto err1;
 142        }
 143
 144        memset(mod, 0, sizeof(*mod));
 145        mod->size_of_struct = sizeof(*mod);
 146        mod->next = module_list;
 147        mod->name = (char *)(mod + 1);
 148        mod->size = size;
 149        memcpy((char*)(mod+1), name, namelen+1);
 150
 151        put_mod_name(name);
 152
 153        module_list = mod;      /* link it in */
 154
 155        error = (long) mod;
 156        goto err0;
 157err1:
 158        put_mod_name(name);
 159err0:
 160        unlock_kernel();
 161        return error;
 162}
 163
 164/*
 165 * Initialize a module.
 166 */
 167
 168asmlinkage int
 169sys_init_module(const char *name_user, struct module *mod_user)
 170{
 171        struct module mod_tmp, *mod;
 172        char *name, *n_name;
 173        long namelen, n_namelen, i, error = -EPERM;
 174        unsigned long mod_user_size;
 175        struct module_ref *dep;
 176
 177        lock_kernel();
 178        if (!suser())
 179                goto err0;
 180        if ((namelen = get_mod_name(name_user, &name)) < 0) {
 181                error = namelen;
 182                goto err0;
 183        }
 184        if ((mod = find_module(name)) == NULL) {
 185                error = -ENOENT;
 186                goto err1;
 187        }
 188
 189        /* Check module header size.  We allow a bit of slop over the 
 190           size we are familiar with to cope with a version of insmod
 191           for a newer kernel.  But don't over do it. */
 192        if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
 193                goto err1;
 194        if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
 195            || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
 196                printk(KERN_ERR "init_module: Invalid module header size.\n"
 197                       KERN_ERR "A new version of the modutils is likely "
 198                                "needed.\n");
 199                error = -EINVAL;
 200                goto err1;
 201        }
 202
 203        /* Hold the current contents while we play with the user's idea
 204           of righteousness.  */
 205        mod_tmp = *mod;
 206
 207        error = copy_from_user(mod, mod_user, sizeof(struct module));
 208        if (error) {
 209                error = -EFAULT;
 210                goto err2;
 211        }
 212
 213        /* Sanity check the size of the module.  */
 214        error = -EINVAL;
 215
 216        if (mod->size > mod_tmp.size) {
 217                printk(KERN_ERR "init_module: Size of initialized module "
 218                                "exceeds size of created module.\n");
 219                goto err2;
 220        }
 221
 222        /* Make sure all interesting pointers are sane.  */
 223
 224#define bound(p, n, m)  ((unsigned long)(p) >= (unsigned long)(m+1) &&  \
 225                 (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
 226
 227        if (!bound(mod->name, namelen, mod)) {
 228                printk(KERN_ERR "init_module: mod->name out of bounds.\n");
 229                goto err2;
 230        }
 231        if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
 232                printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
 233                goto err2;
 234        }
 235        if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
 236                printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
 237                goto err2;
 238        }
 239        if (mod->init && !bound(mod->init, 0, mod)) {
 240                printk(KERN_ERR "init_module: mod->init out of bounds.\n");
 241                goto err2;
 242        }
 243        if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
 244                printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
 245                goto err2;
 246        }
 247        if (mod->ex_table_start > mod->ex_table_end
 248            || (mod->ex_table_start &&
 249                !((unsigned long)mod->ex_table_start >= (unsigned long)(mod+1)
 250                  && ((unsigned long)mod->ex_table_end
 251                      < (unsigned long)mod + mod->size)))
 252            || (((unsigned long)mod->ex_table_start
 253                 - (unsigned long)mod->ex_table_end)
 254                % sizeof(struct exception_table_entry))) {
 255                printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
 256                goto err2;
 257        }
 258        if (mod->flags & ~MOD_AUTOCLEAN) {
 259                printk(KERN_ERR "init_module: mod->flags invalid.\n");
 260                goto err2;
 261        }
 262#ifdef __alpha__
 263        if (!bound(mod->gp - 0x8000, 0, mod)) {
 264                printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
 265                goto err2;
 266        }
 267#endif
 268        if (mod_member_present(mod, can_unload)
 269            && mod->can_unload && !bound(mod->can_unload, 0, mod)) {
 270                printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
 271                goto err2;
 272        }
 273
 274#undef bound
 275
 276        /* Check that the user isn't doing something silly with the name.  */
 277
 278        if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
 279                                      + (unsigned long)mod_user,
 280                                      &n_name)) < 0) {
 281                error = n_namelen;
 282                goto err2;
 283        }
 284        if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) {
 285                printk(KERN_ERR "init_module: changed module name to "
 286                                "`%s' from `%s'\n",
 287                       n_name, mod_tmp.name);
 288                goto err3;
 289        }
 290
 291        /* Ok, that's about all the sanity we can stomach; copy the rest.  */
 292
 293        if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
 294                error = -EFAULT;
 295                goto err3;
 296        }
 297
 298        /* On some machines it is necessary to do something here
 299           to make the I and D caches consistent.  */
 300        flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
 301
 302        /* Update module references.  */
 303        mod->next = mod_tmp.next;
 304        mod->refs = NULL;
 305        for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
 306                struct module *o, *d = dep->dep;
 307
 308                /* Make sure the indicated dependancies are really modules.  */
 309                if (d == mod) {
 310                        printk(KERN_ERR "init_module: self-referential "
 311                                        "dependancy in mod->deps.\n");
 312                        goto err3;
 313                }
 314
 315                for (o = module_list; o != &kernel_module; o = o->next)
 316                        if (o == d) goto found_dep;
 317
 318                printk(KERN_ERR "init_module: found dependancy that is "
 319                                "(no longer?) a module.\n");
 320                goto err3;
 321                
 322        found_dep:
 323                dep->ref = mod;
 324                dep->next_ref = d->refs;
 325                d->refs = dep;
 326                /* Being referenced by a dependant module counts as a 
 327                   use as far as kerneld is concerned.  */
 328                d->flags |= MOD_USED_ONCE;
 329        }
 330
 331        /* Free our temporary memory.  */
 332        put_mod_name(n_name);
 333        put_mod_name(name);
 334
 335        /* Initialize the module.  */
 336        mod->usecount = 1;
 337        if (mod->init && mod->init() != 0) {
 338                mod->usecount = 0;
 339                error = -EBUSY;
 340                goto err0;
 341        }
 342        mod->usecount--;
 343
 344        /* And set it running.  */
 345        mod->flags |= MOD_RUNNING;
 346        error = 0;
 347        goto err0;
 348
 349err3:
 350        put_mod_name(n_name);
 351err2:
 352        *mod = mod_tmp;
 353err1:
 354        put_mod_name(name);
 355err0:
 356        unlock_kernel();
 357        return error;
 358}
 359
 360asmlinkage int
 361sys_delete_module(const char *name_user)
 362{
 363        struct module *mod, *next;
 364        char *name;
 365        long error = -EPERM;
 366
 367        lock_kernel();
 368        if (!suser())
 369                goto out;
 370
 371        if (name_user) {
 372                if ((error = get_mod_name(name_user, &name)) < 0)
 373                        goto out;
 374                if (error == 0) {
 375                        error = -EINVAL;
 376                        put_mod_name(name);
 377                        goto out;
 378                }
 379                error = -ENOENT;
 380                if ((mod = find_module(name)) == NULL) {
 381                        put_mod_name(name);
 382                        goto out;
 383                }
 384                put_mod_name(name);
 385                error = -EBUSY;
 386                if (mod->refs != NULL || __MOD_IN_USE(mod))
 387                        goto out;
 388
 389                free_module(mod);
 390                error = 0;
 391                goto out;
 392        }
 393
 394        /* Do automatic reaping */
 395        for (mod = module_list; mod != &kernel_module; mod = next) {
 396                next = mod->next;
 397                if (mod->refs == NULL &&
 398                    ((mod->flags
 399                      & (MOD_AUTOCLEAN|MOD_RUNNING|MOD_DELETED|MOD_USED_ONCE))
 400                     == (MOD_AUTOCLEAN|MOD_RUNNING|MOD_USED_ONCE)) &&
 401                    !__MOD_IN_USE(mod)) {
 402                        if (mod->flags & MOD_VISITED)
 403                                mod->flags &= ~MOD_VISITED;
 404                        else
 405                                free_module(mod);
 406                }
 407        }
 408        error = 0;
 409out:
 410        unlock_kernel();
 411        return error;
 412}
 413
 414/* Query various bits about modules.  */
 415
 416static int
 417qm_modules(char *buf, size_t bufsize, size_t *ret)
 418{
 419        struct module *mod;
 420        size_t nmod, space, len;
 421
 422        nmod = space = 0;
 423
 424        for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
 425                len = strlen(mod->name)+1;
 426                if (len > bufsize)
 427                        goto calc_space_needed;
 428                if (copy_to_user(buf, mod->name, len))
 429                        return -EFAULT;
 430                buf += len;
 431                bufsize -= len;
 432                space += len;
 433        }
 434
 435        if (put_user(nmod, ret))
 436                return -EFAULT;
 437        else
 438                return 0;
 439
 440calc_space_needed:
 441        space += len;
 442        while ((mod = mod->next) != &kernel_module)
 443                space += strlen(mod->name)+1;
 444
 445        if (put_user(space, ret))
 446                return -EFAULT;
 447        else
 448                return -ENOSPC;
 449}
 450
 451static int
 452qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
 453{
 454        size_t i, space, len;
 455
 456        if (mod == &kernel_module)
 457                return -EINVAL;
 458        if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
 459                if (put_user(0, ret))
 460                        return -EFAULT;
 461                else
 462                        return 0;
 463
 464        space = 0;
 465        for (i = 0; i < mod->ndeps; ++i) {
 466                const char *dep_name = mod->deps[i].dep->name;
 467
 468                len = strlen(dep_name)+1;
 469                if (len > bufsize)
 470                        goto calc_space_needed;
 471                if (copy_to_user(buf, dep_name, len))
 472                        return -EFAULT;
 473                buf += len;
 474                bufsize -= len;
 475                space += len;
 476        }
 477
 478        if (put_user(i, ret))
 479                return -EFAULT;
 480        else
 481                return 0;
 482
 483calc_space_needed:
 484        space += len;
 485        while (++i < mod->ndeps)
 486                space += strlen(mod->deps[i].dep->name)+1;
 487
 488        if (put_user(space, ret))
 489                return -EFAULT;
 490        else
 491                return -ENOSPC;
 492}
 493
 494static int
 495qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
 496{
 497        size_t nrefs, space, len;
 498        struct module_ref *ref;
 499
 500        if (mod == &kernel_module)
 501                return -EINVAL;
 502        if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
 503                if (put_user(0, ret))
 504                        return -EFAULT;
 505                else
 506                        return 0;
 507
 508        space = 0;
 509        for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
 510                const char *ref_name = ref->ref->name;
 511
 512                len = strlen(ref_name)+1;
 513                if (len > bufsize)
 514                        goto calc_space_needed;
 515                if (copy_to_user(buf, ref_name, len))
 516                        return -EFAULT;
 517                buf += len;
 518                bufsize -= len;
 519                space += len;
 520        }
 521
 522        if (put_user(nrefs, ret))
 523                return -EFAULT;
 524        else
 525                return 0;
 526
 527calc_space_needed:
 528        space += len;
 529        while ((ref = ref->next_ref) != NULL)
 530                space += strlen(ref->ref->name)+1;
 531
 532        if (put_user(space, ret))
 533                return -EFAULT;
 534        else
 535                return -ENOSPC;
 536}
 537
 538static int
 539qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
 540{
 541        size_t i, space, len;
 542        struct module_symbol *s;
 543        char *strings;
 544        unsigned long *vals;
 545
 546        if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
 547                if (put_user(0, ret))
 548                        return -EFAULT;
 549                else
 550                        return 0;
 551
 552        space = mod->nsyms * 2*sizeof(void *);
 553
 554        i = len = 0;
 555        s = mod->syms;
 556
 557        if (space > bufsize)
 558                goto calc_space_needed;
 559
 560        if (!access_ok(VERIFY_WRITE, buf, space))
 561                return -EFAULT;
 562
 563        bufsize -= space;
 564        vals = (unsigned long *)buf;
 565        strings = buf+space;
 566
 567        for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
 568                len = strlen(s->name)+1;
 569                if (len > bufsize)
 570                        goto calc_space_needed;
 571
 572                if (copy_to_user(strings, s->name, len)
 573                    || __put_user(s->value, vals+0)
 574                    || __put_user(space, vals+1))
 575                        return -EFAULT;
 576
 577                strings += len;
 578                bufsize -= len;
 579                space += len;
 580        }
 581
 582        if (put_user(i, ret))
 583                return -EFAULT;
 584        else
 585                return 0;
 586
 587calc_space_needed:
 588        for (; i < mod->nsyms; ++i, ++s)
 589                space += strlen(s->name)+1;
 590
 591        if (put_user(space, ret))
 592                return -EFAULT;
 593        else
 594                return -ENOSPC;
 595}
 596
 597static int
 598qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
 599{
 600        int error = 0;
 601
 602        if (mod == &kernel_module)
 603                return -EINVAL;
 604
 605        if (sizeof(struct module_info) <= bufsize) {
 606                struct module_info info;
 607                info.addr = (unsigned long)mod;
 608                info.size = mod->size;
 609                info.flags = mod->flags;
 610                info.usecount = (mod_member_present(mod, can_unload)
 611                                 && mod->can_unload ? -1 : mod->usecount);
 612
 613                if (copy_to_user(buf, &info, sizeof(struct module_info)))
 614                        return -EFAULT;
 615        } else
 616                error = -ENOSPC;
 617
 618        if (put_user(sizeof(struct module_info), ret))
 619                return -EFAULT;
 620
 621        return error;
 622}
 623
 624asmlinkage int
 625sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
 626                 size_t *ret)
 627{
 628        struct module *mod;
 629        int err;
 630
 631        lock_kernel();
 632        if (name_user == NULL)
 633                mod = &kernel_module;
 634        else {
 635                long namelen;
 636                char *name;
 637
 638                if ((namelen = get_mod_name(name_user, &name)) < 0) {
 639                        err = namelen;
 640                        goto out;
 641                }
 642                err = -ENOENT;
 643                if (namelen == 0)
 644                        mod = &kernel_module;
 645                else if ((mod = find_module(name)) == NULL) {
 646                        put_mod_name(name);
 647                        goto out;
 648                }
 649                put_mod_name(name);
 650        }
 651
 652        switch (which)
 653        {
 654        case 0:
 655                err = 0;
 656                break;
 657        case QM_MODULES:
 658                err = qm_modules(buf, bufsize, ret);
 659                break;
 660        case QM_DEPS:
 661                err = qm_deps(mod, buf, bufsize, ret);
 662                break;
 663        case QM_REFS:
 664                err = qm_refs(mod, buf, bufsize, ret);
 665                break;
 666        case QM_SYMBOLS:
 667                err = qm_symbols(mod, buf, bufsize, ret);
 668                break;
 669        case QM_INFO:
 670                err = qm_info(mod, buf, bufsize, ret);
 671                break;
 672        default:
 673                err = -EINVAL;
 674                break;
 675        }
 676out:
 677        unlock_kernel();
 678        return err;
 679}
 680
 681/*
 682 * Copy the kernel symbol table to user space.  If the argument is
 683 * NULL, just return the size of the table.
 684 *
 685 * This call is obsolete.  New programs should use query_module+QM_SYMBOLS
 686 * which does not arbitrarily limit the length of symbols.
 687 */
 688
 689asmlinkage int
 690sys_get_kernel_syms(struct kernel_sym *table)
 691{
 692        struct module *mod;
 693        int i;
 694        struct kernel_sym ksym;
 695
 696        lock_kernel();
 697        for (mod = module_list, i = 0; mod; mod = mod->next) {
 698                /* include the count for the module name! */
 699                i += mod->nsyms + 1;
 700        }
 701
 702        if (table == NULL)
 703                goto out;
 704
 705        /* So that we don't give the user our stack content */
 706        memset (&ksym, 0, sizeof (ksym));
 707
 708        for (mod = module_list, i = 0; mod; mod = mod->next) {
 709                struct module_symbol *msym;
 710                unsigned int j;
 711
 712                if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
 713                        continue;
 714
 715                /* magic: write module info as a pseudo symbol */
 716                ksym.value = (unsigned long)mod;
 717                ksym.name[0] = '#';
 718                strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
 719                ksym.name[sizeof(ksym.name)-1] = '\0';
 720
 721                if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
 722                        goto out;
 723                ++i, ++table;
 724
 725                if (mod->nsyms == 0)
 726                        continue;
 727
 728                for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
 729                        ksym.value = msym->value;
 730                        strncpy(ksym.name, msym->name, sizeof(ksym.name));
 731                        ksym.name[sizeof(ksym.name)-1] = '\0';
 732
 733                        if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
 734                                goto out;
 735                        ++i, ++table;
 736                }
 737        }
 738out:
 739        unlock_kernel();
 740        return i;
 741}
 742
 743/*
 744 * Look for a module by name, ignoring modules marked for deletion.
 745 */
 746
 747static struct module *
 748find_module(const char *name)
 749{
 750        struct module *mod;
 751
 752        for (mod = module_list; mod ; mod = mod->next) {
 753                if (mod->flags & MOD_DELETED)
 754                        continue;
 755                if (!strcmp(mod->name, name))
 756                        break;
 757        }
 758
 759        return mod;
 760}
 761
 762/*
 763 * Free the given module.
 764 */
 765
 766static void
 767free_module(struct module *mod)
 768{
 769        struct module_ref *dep;
 770        unsigned i;
 771
 772        /* Let the module clean up.  */
 773
 774        mod->flags |= MOD_DELETED;
 775        if (mod->flags & MOD_RUNNING) {
 776                mod->cleanup();
 777                mod->flags &= ~MOD_RUNNING;
 778        }
 779
 780        /* Remove the module from the dependancy lists.  */
 781
 782        for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
 783                struct module_ref **pp;
 784                for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
 785                        continue;
 786                *pp = dep->next_ref;
 787        }
 788
 789        /* And from the main module list.  */
 790
 791        if (mod == module_list) {
 792                module_list = mod->next;
 793        } else {
 794                struct module *p;
 795                for (p = module_list; p->next != mod; p = p->next)
 796                        continue;
 797                p->next = mod->next;
 798        }
 799
 800        /* And free the memory.  */
 801
 802        module_unmap(mod);
 803}
 804
 805/*
 806 * Called by the /proc file system to return a current list of modules.
 807 */
 808
 809int get_module_list(char *p)
 810{
 811        size_t left = PAGE_SIZE;
 812        struct module *mod;
 813        char tmpstr[64];
 814        struct module_ref *ref;
 815
 816        for (mod = module_list; mod != &kernel_module; mod = mod->next) {
 817                long len;
 818                const char *q;
 819
 820#define safe_copy_str(str, len)                                         \
 821                do {                                                    \
 822                        if (left < len)                                 \
 823                                goto fini;                              \
 824                        memcpy(p, str, len); p += len, left -= len;     \
 825                } while (0)
 826#define safe_copy_cstr(str)     safe_copy_str(str, sizeof(str)-1)
 827
 828                len = strlen(mod->name);
 829                safe_copy_str(mod->name, len);
 830
 831                if ((len = 20 - len) > 0) {
 832                        if (left < len)
 833                                goto fini;
 834                        memset(p, ' ', len);
 835                        p += len;
 836                        left -= len;
 837                }
 838
 839                len = sprintf(tmpstr, "%8lu", mod->size);
 840                safe_copy_str(tmpstr, len);
 841
 842                if (mod->flags & MOD_RUNNING) {
 843                        len = sprintf(tmpstr, "%4ld",
 844                                      (mod_member_present(mod, can_unload)
 845                                       && mod->can_unload
 846                                       ? -1 : mod->usecount));
 847                        safe_copy_str(tmpstr, len);
 848                }
 849
 850                if (mod->flags & MOD_DELETED)
 851                        safe_copy_cstr(" (deleted)");
 852                else if (mod->flags & MOD_RUNNING) {
 853                        if (mod->flags & MOD_AUTOCLEAN)
 854                                safe_copy_cstr(" (autoclean)");
 855                        if (!(mod->flags & MOD_USED_ONCE))
 856                                safe_copy_cstr(" (unused)");
 857                } else
 858                        safe_copy_cstr(" (uninitialized)");
 859
 860                if ((ref = mod->refs) != NULL) {
 861                        safe_copy_cstr(" [");
 862                        while (1) {
 863                                q = ref->ref->name;
 864                                len = strlen(q);
 865                                safe_copy_str(q, len);
 866
 867                                if ((ref = ref->next_ref) != NULL)
 868                                        safe_copy_cstr(" ");
 869                                else
 870                                        break;
 871                        }
 872                        safe_copy_cstr("]");
 873                }
 874
 875                safe_copy_cstr("\n");
 876
 877#undef safe_copy_str
 878#undef safe_copy_cstr
 879        }
 880
 881fini:
 882        return PAGE_SIZE - left;
 883}
 884
 885/*
 886 * Called by the /proc file system to return a current list of ksyms.
 887 */
 888
 889int
 890get_ksyms_list(char *buf, char **start, off_t offset, int length)
 891{
 892        struct module *mod;
 893        char *p = buf;
 894        int len     = 0;        /* code from  net/ipv4/proc.c */
 895        off_t pos   = 0;
 896        off_t begin = 0;
 897
 898        for (mod = module_list; mod; mod = mod->next) {
 899                unsigned i;
 900                struct module_symbol *sym;
 901
 902                if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
 903                        continue;
 904
 905                for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
 906                        p = buf + len;
 907                        if (*mod->name) {
 908                                len += sprintf(p, "%0*lx %s\t[%s]\n",
 909                                               (int)(2*sizeof(void*)),
 910                                               sym->value, sym->name,
 911                                               mod->name);
 912                        } else {
 913                                len += sprintf(p, "%0*lx %s\n",
 914                                               (int)(2*sizeof(void*)),
 915                                               sym->value, sym->name);
 916                        }
 917                        pos = begin + len;
 918                        if (pos < offset) {
 919                                len = 0;
 920                                begin = pos;
 921                        }
 922                        pos = begin + len;
 923                        if (pos > offset+length)
 924                                goto leave_the_loop;
 925                }
 926        }
 927leave_the_loop:
 928        *start = buf + (offset - begin);
 929        len -= (offset - begin);
 930        if (len > length)
 931                len = length;
 932        return len;
 933}
 934
 935#else           /* CONFIG_MODULES */
 936
 937/* Dummy syscalls for people who don't want modules */
 938
 939asmlinkage unsigned long
 940sys_create_module(const char *name_user, size_t size)
 941{
 942        return -ENOSYS;
 943}
 944
 945asmlinkage int
 946sys_init_module(const char *name_user, struct module *mod_user)
 947{
 948        return -ENOSYS;
 949}
 950
 951asmlinkage int
 952sys_delete_module(const char *name_user)
 953{
 954        return -ENOSYS;
 955}
 956
 957asmlinkage int
 958sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
 959                 size_t *ret)
 960{
 961        /* Let the program know about the new interface.  Not that
 962           it'll do them much good.  */
 963        if (which == 0)
 964                return 0;
 965
 966        return -ENOSYS;
 967}
 968
 969asmlinkage int
 970sys_get_kernel_syms(struct kernel_sym *table)
 971{
 972        return -ENOSYS;
 973}
 974
 975#endif  /* CONFIG_MODULES */
 976
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.