diff options
-rw-r--r-- | include/linux/kernel.h | 1 | ||||
-rw-r--r-- | kernel/panic.c | 6 | ||||
-rw-r--r-- | kernel/sysctl.c | 27 |
3 files changed, 30 insertions, 4 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 63fb18dcac30..e1a429ada97f 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -200,6 +200,7 @@ extern enum system_states { | |||
200 | #define TAINT_FORCED_RMMOD (1<<3) | 200 | #define TAINT_FORCED_RMMOD (1<<3) |
201 | #define TAINT_MACHINE_CHECK (1<<4) | 201 | #define TAINT_MACHINE_CHECK (1<<4) |
202 | #define TAINT_BAD_PAGE (1<<5) | 202 | #define TAINT_BAD_PAGE (1<<5) |
203 | #define TAINT_USER (1<<6) | ||
203 | 204 | ||
204 | extern void dump_stack(void); | 205 | extern void dump_stack(void); |
205 | 206 | ||
diff --git a/kernel/panic.c b/kernel/panic.c index 525e365f7239..623d1828259a 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -150,6 +150,7 @@ EXPORT_SYMBOL(panic); | |||
150 | * 'R' - User forced a module unload. | 150 | * 'R' - User forced a module unload. |
151 | * 'M' - Machine had a machine check experience. | 151 | * 'M' - Machine had a machine check experience. |
152 | * 'B' - System has hit bad_page. | 152 | * 'B' - System has hit bad_page. |
153 | * 'U' - Userspace-defined naughtiness. | ||
153 | * | 154 | * |
154 | * The string is overwritten by the next call to print_taint(). | 155 | * The string is overwritten by the next call to print_taint(). |
155 | */ | 156 | */ |
@@ -158,13 +159,14 @@ const char *print_tainted(void) | |||
158 | { | 159 | { |
159 | static char buf[20]; | 160 | static char buf[20]; |
160 | if (tainted) { | 161 | if (tainted) { |
161 | snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c", | 162 | snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c", |
162 | tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', | 163 | tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', |
163 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', | 164 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', |
164 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', | 165 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', |
165 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', | 166 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', |
166 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', | 167 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', |
167 | tainted & TAINT_BAD_PAGE ? 'B' : ' '); | 168 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', |
169 | tainted & TAINT_USER ? 'U' : ' '); | ||
168 | } | 170 | } |
169 | else | 171 | else |
170 | snprintf(buf, sizeof(buf), "Not tainted"); | 172 | snprintf(buf, sizeof(buf), "Not tainted"); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 16ef870fa75a..7733ef58aaca 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -151,6 +151,8 @@ static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, | |||
151 | #ifdef CONFIG_PROC_SYSCTL | 151 | #ifdef CONFIG_PROC_SYSCTL |
152 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | 152 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, |
153 | void __user *buffer, size_t *lenp, loff_t *ppos); | 153 | void __user *buffer, size_t *lenp, loff_t *ppos); |
154 | static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, | ||
155 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
154 | #endif | 156 | #endif |
155 | 157 | ||
156 | static ctl_table root_table[]; | 158 | static ctl_table root_table[]; |
@@ -174,6 +176,7 @@ extern ctl_table inotify_table[]; | |||
174 | int sysctl_legacy_va_layout; | 176 | int sysctl_legacy_va_layout; |
175 | #endif | 177 | #endif |
176 | 178 | ||
179 | |||
177 | static void *get_uts(ctl_table *table, int write) | 180 | static void *get_uts(ctl_table *table, int write) |
178 | { | 181 | { |
179 | char *which = table->data; | 182 | char *which = table->data; |
@@ -344,14 +347,16 @@ static ctl_table kern_table[] = { | |||
344 | .proc_handler = &proc_dostring, | 347 | .proc_handler = &proc_dostring, |
345 | .strategy = &sysctl_string, | 348 | .strategy = &sysctl_string, |
346 | }, | 349 | }, |
350 | #ifdef CONFIG_PROC_SYSCTL | ||
347 | { | 351 | { |
348 | .ctl_name = KERN_TAINTED, | 352 | .ctl_name = KERN_TAINTED, |
349 | .procname = "tainted", | 353 | .procname = "tainted", |
350 | .data = &tainted, | 354 | .data = &tainted, |
351 | .maxlen = sizeof(int), | 355 | .maxlen = sizeof(int), |
352 | .mode = 0444, | 356 | .mode = 0644, |
353 | .proc_handler = &proc_dointvec, | 357 | .proc_handler = &proc_dointvec_taint, |
354 | }, | 358 | }, |
359 | #endif | ||
355 | { | 360 | { |
356 | .ctl_name = KERN_CAP_BSET, | 361 | .ctl_name = KERN_CAP_BSET, |
357 | .procname = "cap-bound", | 362 | .procname = "cap-bound", |
@@ -1927,6 +1932,7 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp, | |||
1927 | 1932 | ||
1928 | #define OP_SET 0 | 1933 | #define OP_SET 0 |
1929 | #define OP_AND 1 | 1934 | #define OP_AND 1 |
1935 | #define OP_OR 2 | ||
1930 | 1936 | ||
1931 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | 1937 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, |
1932 | int *valp, | 1938 | int *valp, |
@@ -1938,6 +1944,7 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | |||
1938 | switch(op) { | 1944 | switch(op) { |
1939 | case OP_SET: *valp = val; break; | 1945 | case OP_SET: *valp = val; break; |
1940 | case OP_AND: *valp &= val; break; | 1946 | case OP_AND: *valp &= val; break; |
1947 | case OP_OR: *valp |= val; break; | ||
1941 | } | 1948 | } |
1942 | } else { | 1949 | } else { |
1943 | int val = *valp; | 1950 | int val = *valp; |
@@ -1970,6 +1977,22 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, | |||
1970 | do_proc_dointvec_bset_conv,&op); | 1977 | do_proc_dointvec_bset_conv,&op); |
1971 | } | 1978 | } |
1972 | 1979 | ||
1980 | /* | ||
1981 | * Taint values can only be increased | ||
1982 | */ | ||
1983 | static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, | ||
1984 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1985 | { | ||
1986 | int op; | ||
1987 | |||
1988 | if (!capable(CAP_SYS_ADMIN)) | ||
1989 | return -EPERM; | ||
1990 | |||
1991 | op = OP_OR; | ||
1992 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | ||
1993 | do_proc_dointvec_bset_conv,&op); | ||
1994 | } | ||
1995 | |||
1973 | struct do_proc_dointvec_minmax_conv_param { | 1996 | struct do_proc_dointvec_minmax_conv_param { |
1974 | int *min; | 1997 | int *min; |
1975 | int *max; | 1998 | int *max; |