diff options
Diffstat (limited to 'kernel/sysctl.c')
| -rw-r--r-- | kernel/sysctl.c | 67 |
1 files changed, 28 insertions, 39 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index cfc5295f1e82..ec88fcc9a0d2 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -149,7 +149,7 @@ extern int max_lock_depth; | |||
| 149 | #ifdef CONFIG_PROC_SYSCTL | 149 | #ifdef CONFIG_PROC_SYSCTL |
| 150 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, | 150 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
| 151 | void __user *buffer, size_t *lenp, loff_t *ppos); | 151 | void __user *buffer, size_t *lenp, loff_t *ppos); |
| 152 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 152 | static int proc_taint(struct 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 | #endif | 154 | #endif |
| 155 | 155 | ||
| @@ -379,10 +379,9 @@ static struct ctl_table kern_table[] = { | |||
| 379 | #ifdef CONFIG_PROC_SYSCTL | 379 | #ifdef CONFIG_PROC_SYSCTL |
| 380 | { | 380 | { |
| 381 | .procname = "tainted", | 381 | .procname = "tainted", |
| 382 | .data = &tainted, | 382 | .maxlen = sizeof(long), |
| 383 | .maxlen = sizeof(int), | ||
| 384 | .mode = 0644, | 383 | .mode = 0644, |
| 385 | .proc_handler = &proc_dointvec_taint, | 384 | .proc_handler = &proc_taint, |
| 386 | }, | 385 | }, |
| 387 | #endif | 386 | #endif |
| 388 | #ifdef CONFIG_LATENCYTOP | 387 | #ifdef CONFIG_LATENCYTOP |
| @@ -2228,49 +2227,39 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp, | |||
| 2228 | NULL,NULL); | 2227 | NULL,NULL); |
| 2229 | } | 2228 | } |
| 2230 | 2229 | ||
| 2231 | #define OP_SET 0 | ||
| 2232 | #define OP_AND 1 | ||
| 2233 | #define OP_OR 2 | ||
| 2234 | |||
| 2235 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | ||
| 2236 | int *valp, | ||
| 2237 | int write, void *data) | ||
| 2238 | { | ||
| 2239 | int op = *(int *)data; | ||
| 2240 | if (write) { | ||
| 2241 | int val = *negp ? -*lvalp : *lvalp; | ||
| 2242 | switch(op) { | ||
| 2243 | case OP_SET: *valp = val; break; | ||
| 2244 | case OP_AND: *valp &= val; break; | ||
| 2245 | case OP_OR: *valp |= val; break; | ||
| 2246 | } | ||
| 2247 | } else { | ||
| 2248 | int val = *valp; | ||
| 2249 | if (val < 0) { | ||
| 2250 | *negp = -1; | ||
| 2251 | *lvalp = (unsigned long)-val; | ||
| 2252 | } else { | ||
| 2253 | *negp = 0; | ||
| 2254 | *lvalp = (unsigned long)val; | ||
| 2255 | } | ||
| 2256 | } | ||
| 2257 | return 0; | ||
| 2258 | } | ||
| 2259 | |||
| 2260 | /* | 2230 | /* |
| 2261 | * Taint values can only be increased | 2231 | * Taint values can only be increased |
| 2232 | * This means we can safely use a temporary. | ||
| 2262 | */ | 2233 | */ |
| 2263 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, | 2234 | static int proc_taint(struct ctl_table *table, int write, struct file *filp, |
| 2264 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2235 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 2265 | { | 2236 | { |
| 2266 | int op; | 2237 | struct ctl_table t; |
| 2238 | unsigned long tmptaint = get_taint(); | ||
| 2239 | int err; | ||
| 2267 | 2240 | ||
| 2268 | if (write && !capable(CAP_SYS_ADMIN)) | 2241 | if (write && !capable(CAP_SYS_ADMIN)) |
| 2269 | return -EPERM; | 2242 | return -EPERM; |
| 2270 | 2243 | ||
| 2271 | op = OP_OR; | 2244 | t = *table; |
| 2272 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2245 | t.data = &tmptaint; |
| 2273 | do_proc_dointvec_bset_conv,&op); | 2246 | err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos); |
| 2247 | if (err < 0) | ||
| 2248 | return err; | ||
| 2249 | |||
| 2250 | if (write) { | ||
| 2251 | /* | ||
| 2252 | * Poor man's atomic or. Not worth adding a primitive | ||
| 2253 | * to everyone's atomic.h for this | ||
| 2254 | */ | ||
| 2255 | int i; | ||
| 2256 | for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) { | ||
| 2257 | if ((tmptaint >> i) & 1) | ||
| 2258 | add_taint(i); | ||
| 2259 | } | ||
| 2260 | } | ||
| 2261 | |||
| 2262 | return err; | ||
| 2274 | } | 2263 | } |
| 2275 | 2264 | ||
| 2276 | struct do_proc_dointvec_minmax_conv_param { | 2265 | struct do_proc_dointvec_minmax_conv_param { |
