aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kernel.h1
-rw-r--r--kernel/panic.c6
-rw-r--r--kernel/sysctl.c27
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
204extern void dump_stack(void); 205extern 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
152static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, 152static 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);
154static 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
156static ctl_table root_table[]; 158static ctl_table root_table[];
@@ -174,6 +176,7 @@ extern ctl_table inotify_table[];
174int sysctl_legacy_va_layout; 176int sysctl_legacy_va_layout;
175#endif 177#endif
176 178
179
177static void *get_uts(ctl_table *table, int write) 180static 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
1931static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, 1937static 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 */
1983static 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
1973struct do_proc_dointvec_minmax_conv_param { 1996struct do_proc_dointvec_minmax_conv_param {
1974 int *min; 1997 int *min;
1975 int *max; 1998 int *max;