aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r--kernel/sysctl.c27
1 files changed, 25 insertions, 2 deletions
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;