aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modutils/insmod.c116
-rw-r--r--modutils/lsmod.c34
2 files changed, 146 insertions, 4 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 856c12a63..b246d90af 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -71,6 +71,7 @@
71#include <assert.h> 71#include <assert.h>
72#include <string.h> 72#include <string.h>
73#include <getopt.h> 73#include <getopt.h>
74#include <fcntl.h>
74#include <sys/utsname.h> 75#include <sys/utsname.h>
75#include "busybox.h" 76#include "busybox.h"
76 77
@@ -233,7 +234,7 @@
233#ifndef MODUTILS_MODULE_H 234#ifndef MODUTILS_MODULE_H
234static const int MODUTILS_MODULE_H = 1; 235static const int MODUTILS_MODULE_H = 1;
235 236
236#ident "$Id: insmod.c,v 1.89 2002/07/21 17:33:26 sandman Exp $" 237#ident "$Id: insmod.c,v 1.90 2002/09/16 05:30:24 andersen Exp $"
237 238
238/* This file contains the structures used by the 2.0 and 2.1 kernels. 239/* This file contains the structures used by the 2.0 and 2.1 kernels.
239 We do not use the kernel headers directly because we do not wish 240 We do not use the kernel headers directly because we do not wish
@@ -454,7 +455,7 @@ int delete_module(const char *);
454#ifndef MODUTILS_OBJ_H 455#ifndef MODUTILS_OBJ_H
455static const int MODUTILS_OBJ_H = 1; 456static const int MODUTILS_OBJ_H = 1;
456 457
457#ident "$Id: insmod.c,v 1.89 2002/07/21 17:33:26 sandman Exp $" 458#ident "$Id: insmod.c,v 1.90 2002/09/16 05:30:24 andersen Exp $"
458 459
459/* The relocatable object is manipulated using elfin types. */ 460/* The relocatable object is manipulated using elfin types. */
460 461
@@ -3421,7 +3422,117 @@ static void hide_special_symbols(struct obj_file *f)
3421 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info)); 3422 ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info));
3422} 3423}
3423 3424
3425static int obj_gpl_license(struct obj_file *f, const char **license)
3426{
3427 struct obj_section *sec;
3428 /* This list must match *exactly* the list of allowable licenses in
3429 * linux/include/linux/module.h. Checking for leading "GPL" will not
3430 * work, somebody will use "GPL sucks, this is proprietary".
3431 */
3432 static const char *gpl_licenses[] = {
3433 "GPL",
3434 "GPL v2",
3435 "GPL and additional rights",
3436 "Dual BSD/GPL",
3437 "Dual MPL/GPL",
3438 };
3439
3440 if ((sec = obj_find_section(f, ".modinfo"))) {
3441 const char *value, *ptr, *endptr;
3442 ptr = sec->contents;
3443 endptr = ptr + sec->header.sh_size;
3444 while (ptr < endptr) {
3445 if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) {
3446 int i;
3447 if (license)
3448 *license = value+1;
3449 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {
3450 if (strcmp(value+1, gpl_licenses[i]) == 0)
3451 return(0);
3452 }
3453 return(2);
3454 }
3455 if (strchr(ptr, '\0'))
3456 ptr = strchr(ptr, '\0') + 1;
3457 else
3458 ptr = endptr;
3459 }
3460 }
3461 return(1);
3462}
3463
3464#define TAINT_FILENAME "/proc/sys/kernel/tainted"
3465#define TAINT_PROPRIETORY_MODULE (1<<0)
3466#define TAINT_FORCED_MODULE (1<<1)
3467#define TAINT_UNSAFE_SMP (1<<2)
3468#define TAINT_URL "http://www.tux.org/lkml/#export-tainted"
3469
3470static void set_tainted(struct obj_file *f, int fd, char *m_name,
3471 int kernel_has_tainted, int taint, const char *text1, const char *text2)
3472{
3473 char buf[80];
3474 int oldval;
3475 static int first = 1;
3476 if (fd < 0 && !kernel_has_tainted)
3477 return; /* New modutils on old kernel */
3478 printf("Warning: loading %s will taint the kernel: %s%s\n",
3479 m_name, text1, text2);
3480 if (first) {
3481 printf(" See %s for information about tainted modules\n", TAINT_URL);
3482 first = 0;
3483 }
3484 if (fd >= 0) {
3485 read(fd, buf, sizeof(buf)-1);
3486 buf[sizeof(buf)-1] = '\0';
3487 oldval = strtoul(buf, NULL, 10);
3488 sprintf(buf, "%d\n", oldval | taint);
3489 write(fd, buf, strlen(buf));
3490 }
3491}
3492
3493/* Check if loading this module will taint the kernel. */
3494static void check_tainted_module(struct obj_file *f, char *m_name)
3495{
3496 static const char tainted_file[] = TAINT_FILENAME;
3497 int fd, kernel_has_tainted;
3498 const char *ptr;
3499
3500 kernel_has_tainted = 1;
3501 if ((fd = open(tainted_file, O_RDWR)) < 0) {
3502 if (errno == ENOENT)
3503 kernel_has_tainted = 0;
3504 else if (errno == EACCES)
3505 kernel_has_tainted = 1;
3506 else {
3507 perror(tainted_file);
3508 kernel_has_tainted = 0;
3509 }
3510 }
3424 3511
3512 switch (obj_gpl_license(f, &ptr)) {
3513 case 0:
3514 break;
3515 case 1:
3516 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", "");
3517 break;
3518 case 2:
3519 /* The module has a non-GPL license so we pretend that the
3520 * kernel always has a taint flag to get a warning even on
3521 * kernels without the proc flag.
3522 */
3523 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr);
3524 break;
3525 default:
3526 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", "");
3527 break;
3528 }
3529
3530 if (flag_force_load)
3531 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", "");
3532
3533 if (fd >= 0)
3534 close(fd);
3535}
3425 3536
3426extern int insmod_main( int argc, char **argv) 3537extern int insmod_main( int argc, char **argv)
3427{ 3538{
@@ -3657,6 +3768,7 @@ extern int insmod_main( int argc, char **argv)
3657 goto out; 3768 goto out;
3658 } 3769 }
3659 obj_allocate_commons(f); 3770 obj_allocate_commons(f);
3771 check_tainted_module(f, m_name);
3660 3772
3661 /* done with the module name, on to the optional var=value arguments */ 3773 /* done with the module name, on to the optional var=value arguments */
3662 ++optind; 3774 ++optind;
diff --git a/modutils/lsmod.c b/modutils/lsmod.c
index 5cb585bab..3618ebe0b 100644
--- a/modutils/lsmod.c
+++ b/modutils/lsmod.c
@@ -41,6 +41,32 @@
41 41
42 42
43 43
44#define TAINT_FILENAME "/proc/sys/kernel/tainted"
45#define TAINT_PROPRIETORY_MODULE (1<<0)
46#define TAINT_FORCED_MODULE (1<<1)
47#define TAINT_UNSAFE_SMP (1<<2)
48
49void check_tainted(void)
50{
51 int tainted;
52 FILE *f;
53
54 tainted = 0;
55 if ((f = fopen(TAINT_FILENAME, "r"))) {
56 fscanf(f, "%d", &tainted);
57 fclose(f);
58 }
59 if (f && tainted) {
60 printf(" Tainted: %c%c%c",
61 tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G',
62 tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
63 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ');
64 }
65 else {
66 printf(" Not tainted");
67 }
68}
69
44#ifdef CONFIG_FEATURE_QUERY_MODULE_INTERFACE 70#ifdef CONFIG_FEATURE_QUERY_MODULE_INTERFACE
45 71
46struct module_info 72struct module_info
@@ -99,7 +125,10 @@ extern int lsmod_main(int argc, char **argv)
99 } 125 }
100 126
101 deps = xmalloc(depsize = 256); 127 deps = xmalloc(depsize = 256);
102 printf("Module Size Used by\n"); 128 printf("Module Size Used by");
129 check_tainted();
130 printf("\n");
131
103 for (i = 0, mn = module_names; i < nmod; mn += strlen(mn) + 1, i++) { 132 for (i = 0, mn = module_names; i < nmod; mn += strlen(mn) + 1, i++) {
104 if (query_module(mn, QM_INFO, &info, sizeof(info), &count)) { 133 if (query_module(mn, QM_INFO, &info, sizeof(info), &count)) {
105 if (errno == ENOENT) { 134 if (errno == ENOENT) {
@@ -149,7 +178,8 @@ extern int lsmod_main(int argc, char **argv)
149 int fd, i; 178 int fd, i;
150 char line[128]; 179 char line[128];
151 180
152 puts("Module Size Used by"); 181 printf("Module Size Used by");
182 check_tainted();
153 fflush(stdout); 183 fflush(stdout);
154 184
155 if ((fd = open("/proc/modules", O_RDONLY)) >= 0 ) { 185 if ((fd = open("/proc/modules", O_RDONLY)) >= 0 ) {