diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 390 |
1 files changed, 195 insertions, 195 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 8e9f00fd6d18..600b33358ded 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -65,7 +65,6 @@ extern int sysctl_overcommit_memory; | |||
65 | extern int sysctl_overcommit_ratio; | 65 | extern int sysctl_overcommit_ratio; |
66 | extern int sysctl_panic_on_oom; | 66 | extern int sysctl_panic_on_oom; |
67 | extern int max_threads; | 67 | extern int max_threads; |
68 | extern int sysrq_enabled; | ||
69 | extern int core_uses_pid; | 68 | extern int core_uses_pid; |
70 | extern int suid_dumpable; | 69 | extern int suid_dumpable; |
71 | extern char core_pattern[]; | 70 | extern char core_pattern[]; |
@@ -92,7 +91,9 @@ extern char modprobe_path[]; | |||
92 | extern int sg_big_buff; | 91 | extern int sg_big_buff; |
93 | #endif | 92 | #endif |
94 | #ifdef CONFIG_SYSVIPC | 93 | #ifdef CONFIG_SYSVIPC |
95 | static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp, | 94 | static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, |
95 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
96 | static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, | ||
96 | void __user *buffer, size_t *lenp, loff_t *ppos); | 97 | void __user *buffer, size_t *lenp, loff_t *ppos); |
97 | #endif | 98 | #endif |
98 | 99 | ||
@@ -131,12 +132,22 @@ extern int max_lock_depth; | |||
131 | 132 | ||
132 | #ifdef CONFIG_SYSCTL_SYSCALL | 133 | #ifdef CONFIG_SYSCTL_SYSCALL |
133 | static int parse_table(int __user *, int, void __user *, size_t __user *, | 134 | static int parse_table(int __user *, int, void __user *, size_t __user *, |
134 | void __user *, size_t, ctl_table *, void **); | 135 | void __user *, size_t, ctl_table *); |
135 | #endif | 136 | #endif |
136 | 137 | ||
137 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | 138 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, |
138 | void __user *buffer, size_t *lenp, loff_t *ppos); | 139 | void __user *buffer, size_t *lenp, loff_t *ppos); |
139 | 140 | ||
141 | static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, | ||
142 | void __user *oldval, size_t __user *oldlenp, | ||
143 | void __user *newval, size_t newlen); | ||
144 | |||
145 | #ifdef CONFIG_SYSVIPC | ||
146 | static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, | ||
147 | void __user *oldval, size_t __user *oldlenp, | ||
148 | void __user *newval, size_t newlen); | ||
149 | #endif | ||
150 | |||
140 | #ifdef CONFIG_PROC_SYSCTL | 151 | #ifdef CONFIG_PROC_SYSCTL |
141 | 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, |
142 | void __user *buffer, size_t *lenp, loff_t *ppos); | 153 | void __user *buffer, size_t *lenp, loff_t *ppos); |
@@ -163,6 +174,40 @@ extern ctl_table inotify_table[]; | |||
163 | int sysctl_legacy_va_layout; | 174 | int sysctl_legacy_va_layout; |
164 | #endif | 175 | #endif |
165 | 176 | ||
177 | static void *get_uts(ctl_table *table, int write) | ||
178 | { | ||
179 | char *which = table->data; | ||
180 | #ifdef CONFIG_UTS_NS | ||
181 | struct uts_namespace *uts_ns = current->nsproxy->uts_ns; | ||
182 | which = (which - (char *)&init_uts_ns) + (char *)uts_ns; | ||
183 | #endif | ||
184 | if (!write) | ||
185 | down_read(&uts_sem); | ||
186 | else | ||
187 | down_write(&uts_sem); | ||
188 | return which; | ||
189 | } | ||
190 | |||
191 | static void put_uts(ctl_table *table, int write, void *which) | ||
192 | { | ||
193 | if (!write) | ||
194 | up_read(&uts_sem); | ||
195 | else | ||
196 | up_write(&uts_sem); | ||
197 | } | ||
198 | |||
199 | #ifdef CONFIG_SYSVIPC | ||
200 | static void *get_ipc(ctl_table *table, int write) | ||
201 | { | ||
202 | char *which = table->data; | ||
203 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; | ||
204 | which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns; | ||
205 | return which; | ||
206 | } | ||
207 | #else | ||
208 | #define get_ipc(T,W) ((T)->data) | ||
209 | #endif | ||
210 | |||
166 | /* /proc declarations: */ | 211 | /* /proc declarations: */ |
167 | 212 | ||
168 | #ifdef CONFIG_PROC_SYSCTL | 213 | #ifdef CONFIG_PROC_SYSCTL |
@@ -229,7 +274,6 @@ static ctl_table root_table[] = { | |||
229 | }; | 274 | }; |
230 | 275 | ||
231 | static ctl_table kern_table[] = { | 276 | static ctl_table kern_table[] = { |
232 | #ifndef CONFIG_UTS_NS | ||
233 | { | 277 | { |
234 | .ctl_name = KERN_OSTYPE, | 278 | .ctl_name = KERN_OSTYPE, |
235 | .procname = "ostype", | 279 | .procname = "ostype", |
@@ -237,7 +281,7 @@ static ctl_table kern_table[] = { | |||
237 | .maxlen = sizeof(init_uts_ns.name.sysname), | 281 | .maxlen = sizeof(init_uts_ns.name.sysname), |
238 | .mode = 0444, | 282 | .mode = 0444, |
239 | .proc_handler = &proc_do_uts_string, | 283 | .proc_handler = &proc_do_uts_string, |
240 | .strategy = &sysctl_string, | 284 | .strategy = &sysctl_uts_string, |
241 | }, | 285 | }, |
242 | { | 286 | { |
243 | .ctl_name = KERN_OSRELEASE, | 287 | .ctl_name = KERN_OSRELEASE, |
@@ -246,7 +290,7 @@ static ctl_table kern_table[] = { | |||
246 | .maxlen = sizeof(init_uts_ns.name.release), | 290 | .maxlen = sizeof(init_uts_ns.name.release), |
247 | .mode = 0444, | 291 | .mode = 0444, |
248 | .proc_handler = &proc_do_uts_string, | 292 | .proc_handler = &proc_do_uts_string, |
249 | .strategy = &sysctl_string, | 293 | .strategy = &sysctl_uts_string, |
250 | }, | 294 | }, |
251 | { | 295 | { |
252 | .ctl_name = KERN_VERSION, | 296 | .ctl_name = KERN_VERSION, |
@@ -255,7 +299,7 @@ static ctl_table kern_table[] = { | |||
255 | .maxlen = sizeof(init_uts_ns.name.version), | 299 | .maxlen = sizeof(init_uts_ns.name.version), |
256 | .mode = 0444, | 300 | .mode = 0444, |
257 | .proc_handler = &proc_do_uts_string, | 301 | .proc_handler = &proc_do_uts_string, |
258 | .strategy = &sysctl_string, | 302 | .strategy = &sysctl_uts_string, |
259 | }, | 303 | }, |
260 | { | 304 | { |
261 | .ctl_name = KERN_NODENAME, | 305 | .ctl_name = KERN_NODENAME, |
@@ -264,7 +308,7 @@ static ctl_table kern_table[] = { | |||
264 | .maxlen = sizeof(init_uts_ns.name.nodename), | 308 | .maxlen = sizeof(init_uts_ns.name.nodename), |
265 | .mode = 0644, | 309 | .mode = 0644, |
266 | .proc_handler = &proc_do_uts_string, | 310 | .proc_handler = &proc_do_uts_string, |
267 | .strategy = &sysctl_string, | 311 | .strategy = &sysctl_uts_string, |
268 | }, | 312 | }, |
269 | { | 313 | { |
270 | .ctl_name = KERN_DOMAINNAME, | 314 | .ctl_name = KERN_DOMAINNAME, |
@@ -273,56 +317,8 @@ static ctl_table kern_table[] = { | |||
273 | .maxlen = sizeof(init_uts_ns.name.domainname), | 317 | .maxlen = sizeof(init_uts_ns.name.domainname), |
274 | .mode = 0644, | 318 | .mode = 0644, |
275 | .proc_handler = &proc_do_uts_string, | 319 | .proc_handler = &proc_do_uts_string, |
276 | .strategy = &sysctl_string, | 320 | .strategy = &sysctl_uts_string, |
277 | }, | ||
278 | #else /* !CONFIG_UTS_NS */ | ||
279 | { | ||
280 | .ctl_name = KERN_OSTYPE, | ||
281 | .procname = "ostype", | ||
282 | .data = NULL, | ||
283 | /* could maybe use __NEW_UTS_LEN here? */ | ||
284 | .maxlen = FIELD_SIZEOF(struct new_utsname, sysname), | ||
285 | .mode = 0444, | ||
286 | .proc_handler = &proc_do_uts_string, | ||
287 | .strategy = &sysctl_string, | ||
288 | }, | ||
289 | { | ||
290 | .ctl_name = KERN_OSRELEASE, | ||
291 | .procname = "osrelease", | ||
292 | .data = NULL, | ||
293 | .maxlen = FIELD_SIZEOF(struct new_utsname, release), | ||
294 | .mode = 0444, | ||
295 | .proc_handler = &proc_do_uts_string, | ||
296 | .strategy = &sysctl_string, | ||
297 | }, | ||
298 | { | ||
299 | .ctl_name = KERN_VERSION, | ||
300 | .procname = "version", | ||
301 | .data = NULL, | ||
302 | .maxlen = FIELD_SIZEOF(struct new_utsname, version), | ||
303 | .mode = 0444, | ||
304 | .proc_handler = &proc_do_uts_string, | ||
305 | .strategy = &sysctl_string, | ||
306 | }, | ||
307 | { | ||
308 | .ctl_name = KERN_NODENAME, | ||
309 | .procname = "hostname", | ||
310 | .data = NULL, | ||
311 | .maxlen = FIELD_SIZEOF(struct new_utsname, nodename), | ||
312 | .mode = 0644, | ||
313 | .proc_handler = &proc_do_uts_string, | ||
314 | .strategy = &sysctl_string, | ||
315 | }, | ||
316 | { | ||
317 | .ctl_name = KERN_DOMAINNAME, | ||
318 | .procname = "domainname", | ||
319 | .data = NULL, | ||
320 | .maxlen = FIELD_SIZEOF(struct new_utsname, domainname), | ||
321 | .mode = 0644, | ||
322 | .proc_handler = &proc_do_uts_string, | ||
323 | .strategy = &sysctl_string, | ||
324 | }, | 321 | }, |
325 | #endif /* !CONFIG_UTS_NS */ | ||
326 | { | 322 | { |
327 | .ctl_name = KERN_PANIC, | 323 | .ctl_name = KERN_PANIC, |
328 | .procname = "panic", | 324 | .procname = "panic", |
@@ -481,65 +477,72 @@ static ctl_table kern_table[] = { | |||
481 | { | 477 | { |
482 | .ctl_name = KERN_SHMMAX, | 478 | .ctl_name = KERN_SHMMAX, |
483 | .procname = "shmmax", | 479 | .procname = "shmmax", |
484 | .data = NULL, | 480 | .data = &init_ipc_ns.shm_ctlmax, |
485 | .maxlen = sizeof (size_t), | 481 | .maxlen = sizeof (init_ipc_ns.shm_ctlmax), |
486 | .mode = 0644, | 482 | .mode = 0644, |
487 | .proc_handler = &proc_do_ipc_string, | 483 | .proc_handler = &proc_ipc_doulongvec_minmax, |
484 | .strategy = sysctl_ipc_data, | ||
488 | }, | 485 | }, |
489 | { | 486 | { |
490 | .ctl_name = KERN_SHMALL, | 487 | .ctl_name = KERN_SHMALL, |
491 | .procname = "shmall", | 488 | .procname = "shmall", |
492 | .data = NULL, | 489 | .data = &init_ipc_ns.shm_ctlall, |
493 | .maxlen = sizeof (size_t), | 490 | .maxlen = sizeof (init_ipc_ns.shm_ctlall), |
494 | .mode = 0644, | 491 | .mode = 0644, |
495 | .proc_handler = &proc_do_ipc_string, | 492 | .proc_handler = &proc_ipc_doulongvec_minmax, |
493 | .strategy = sysctl_ipc_data, | ||
496 | }, | 494 | }, |
497 | { | 495 | { |
498 | .ctl_name = KERN_SHMMNI, | 496 | .ctl_name = KERN_SHMMNI, |
499 | .procname = "shmmni", | 497 | .procname = "shmmni", |
500 | .data = NULL, | 498 | .data = &init_ipc_ns.shm_ctlmni, |
501 | .maxlen = sizeof (int), | 499 | .maxlen = sizeof (init_ipc_ns.shm_ctlmni), |
502 | .mode = 0644, | 500 | .mode = 0644, |
503 | .proc_handler = &proc_do_ipc_string, | 501 | .proc_handler = &proc_ipc_dointvec, |
502 | .strategy = sysctl_ipc_data, | ||
504 | }, | 503 | }, |
505 | { | 504 | { |
506 | .ctl_name = KERN_MSGMAX, | 505 | .ctl_name = KERN_MSGMAX, |
507 | .procname = "msgmax", | 506 | .procname = "msgmax", |
508 | .data = NULL, | 507 | .data = &init_ipc_ns.msg_ctlmax, |
509 | .maxlen = sizeof (int), | 508 | .maxlen = sizeof (init_ipc_ns.msg_ctlmax), |
510 | .mode = 0644, | 509 | .mode = 0644, |
511 | .proc_handler = &proc_do_ipc_string, | 510 | .proc_handler = &proc_ipc_dointvec, |
511 | .strategy = sysctl_ipc_data, | ||
512 | }, | 512 | }, |
513 | { | 513 | { |
514 | .ctl_name = KERN_MSGMNI, | 514 | .ctl_name = KERN_MSGMNI, |
515 | .procname = "msgmni", | 515 | .procname = "msgmni", |
516 | .data = NULL, | 516 | .data = &init_ipc_ns.msg_ctlmni, |
517 | .maxlen = sizeof (int), | 517 | .maxlen = sizeof (init_ipc_ns.msg_ctlmni), |
518 | .mode = 0644, | 518 | .mode = 0644, |
519 | .proc_handler = &proc_do_ipc_string, | 519 | .proc_handler = &proc_ipc_dointvec, |
520 | .strategy = sysctl_ipc_data, | ||
520 | }, | 521 | }, |
521 | { | 522 | { |
522 | .ctl_name = KERN_MSGMNB, | 523 | .ctl_name = KERN_MSGMNB, |
523 | .procname = "msgmnb", | 524 | .procname = "msgmnb", |
524 | .data = NULL, | 525 | .data = &init_ipc_ns.msg_ctlmnb, |
525 | .maxlen = sizeof (int), | 526 | .maxlen = sizeof (init_ipc_ns.msg_ctlmnb), |
526 | .mode = 0644, | 527 | .mode = 0644, |
527 | .proc_handler = &proc_do_ipc_string, | 528 | .proc_handler = &proc_ipc_dointvec, |
529 | .strategy = sysctl_ipc_data, | ||
528 | }, | 530 | }, |
529 | { | 531 | { |
530 | .ctl_name = KERN_SEM, | 532 | .ctl_name = KERN_SEM, |
531 | .procname = "sem", | 533 | .procname = "sem", |
532 | .data = NULL, | 534 | .data = &init_ipc_ns.sem_ctls, |
533 | .maxlen = 4*sizeof (int), | 535 | .maxlen = 4*sizeof (int), |
534 | .mode = 0644, | 536 | .mode = 0644, |
535 | .proc_handler = &proc_do_ipc_string, | 537 | .proc_handler = &proc_ipc_dointvec, |
538 | .strategy = sysctl_ipc_data, | ||
536 | }, | 539 | }, |
537 | #endif | 540 | #endif |
538 | #ifdef CONFIG_MAGIC_SYSRQ | 541 | #ifdef CONFIG_MAGIC_SYSRQ |
539 | { | 542 | { |
540 | .ctl_name = KERN_SYSRQ, | 543 | .ctl_name = KERN_SYSRQ, |
541 | .procname = "sysrq", | 544 | .procname = "sysrq", |
542 | .data = &sysrq_enabled, | 545 | .data = &__sysrq_enabled, |
543 | .maxlen = sizeof (int), | 546 | .maxlen = sizeof (int), |
544 | .mode = 0644, | 547 | .mode = 0644, |
545 | .proc_handler = &proc_dointvec, | 548 | .proc_handler = &proc_dointvec, |
@@ -1239,7 +1242,6 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol | |||
1239 | do { | 1242 | do { |
1240 | struct ctl_table_header *head = | 1243 | struct ctl_table_header *head = |
1241 | list_entry(tmp, struct ctl_table_header, ctl_entry); | 1244 | list_entry(tmp, struct ctl_table_header, ctl_entry); |
1242 | void *context = NULL; | ||
1243 | 1245 | ||
1244 | if (!use_table(head)) | 1246 | if (!use_table(head)) |
1245 | continue; | 1247 | continue; |
@@ -1247,9 +1249,7 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol | |||
1247 | spin_unlock(&sysctl_lock); | 1249 | spin_unlock(&sysctl_lock); |
1248 | 1250 | ||
1249 | error = parse_table(name, nlen, oldval, oldlenp, | 1251 | error = parse_table(name, nlen, oldval, oldlenp, |
1250 | newval, newlen, head->ctl_table, | 1252 | newval, newlen, head->ctl_table); |
1251 | &context); | ||
1252 | kfree(context); | ||
1253 | 1253 | ||
1254 | spin_lock(&sysctl_lock); | 1254 | spin_lock(&sysctl_lock); |
1255 | unuse_table(head); | 1255 | unuse_table(head); |
@@ -1305,7 +1305,7 @@ static inline int ctl_perm(ctl_table *table, int op) | |||
1305 | static int parse_table(int __user *name, int nlen, | 1305 | static int parse_table(int __user *name, int nlen, |
1306 | void __user *oldval, size_t __user *oldlenp, | 1306 | void __user *oldval, size_t __user *oldlenp, |
1307 | void __user *newval, size_t newlen, | 1307 | void __user *newval, size_t newlen, |
1308 | ctl_table *table, void **context) | 1308 | ctl_table *table) |
1309 | { | 1309 | { |
1310 | int n; | 1310 | int n; |
1311 | repeat: | 1311 | repeat: |
@@ -1325,7 +1325,7 @@ repeat: | |||
1325 | error = table->strategy( | 1325 | error = table->strategy( |
1326 | table, name, nlen, | 1326 | table, name, nlen, |
1327 | oldval, oldlenp, | 1327 | oldval, oldlenp, |
1328 | newval, newlen, context); | 1328 | newval, newlen); |
1329 | if (error) | 1329 | if (error) |
1330 | return error; | 1330 | return error; |
1331 | } | 1331 | } |
@@ -1336,7 +1336,7 @@ repeat: | |||
1336 | } | 1336 | } |
1337 | error = do_sysctl_strategy(table, name, nlen, | 1337 | error = do_sysctl_strategy(table, name, nlen, |
1338 | oldval, oldlenp, | 1338 | oldval, oldlenp, |
1339 | newval, newlen, context); | 1339 | newval, newlen); |
1340 | return error; | 1340 | return error; |
1341 | } | 1341 | } |
1342 | } | 1342 | } |
@@ -1347,7 +1347,7 @@ repeat: | |||
1347 | int do_sysctl_strategy (ctl_table *table, | 1347 | int do_sysctl_strategy (ctl_table *table, |
1348 | int __user *name, int nlen, | 1348 | int __user *name, int nlen, |
1349 | void __user *oldval, size_t __user *oldlenp, | 1349 | void __user *oldval, size_t __user *oldlenp, |
1350 | void __user *newval, size_t newlen, void **context) | 1350 | void __user *newval, size_t newlen) |
1351 | { | 1351 | { |
1352 | int op = 0, rc; | 1352 | int op = 0, rc; |
1353 | size_t len; | 1353 | size_t len; |
@@ -1361,7 +1361,7 @@ int do_sysctl_strategy (ctl_table *table, | |||
1361 | 1361 | ||
1362 | if (table->strategy) { | 1362 | if (table->strategy) { |
1363 | rc = table->strategy(table, name, nlen, oldval, oldlenp, | 1363 | rc = table->strategy(table, name, nlen, oldval, oldlenp, |
1364 | newval, newlen, context); | 1364 | newval, newlen); |
1365 | if (rc < 0) | 1365 | if (rc < 0) |
1366 | return rc; | 1366 | return rc; |
1367 | if (rc > 0) | 1367 | if (rc > 0) |
@@ -1614,7 +1614,7 @@ static ssize_t do_rw_proc(int write, struct file * file, char __user * buf, | |||
1614 | size_t count, loff_t *ppos) | 1614 | size_t count, loff_t *ppos) |
1615 | { | 1615 | { |
1616 | int op; | 1616 | int op; |
1617 | struct proc_dir_entry *de = PDE(file->f_dentry->d_inode); | 1617 | struct proc_dir_entry *de = PDE(file->f_path.dentry->d_inode); |
1618 | struct ctl_table *table; | 1618 | struct ctl_table *table; |
1619 | size_t res; | 1619 | size_t res; |
1620 | ssize_t error = -ENOTDIR; | 1620 | ssize_t error = -ENOTDIR; |
@@ -1753,66 +1753,17 @@ int proc_dostring(ctl_table *table, int write, struct file *filp, | |||
1753 | * Special case of dostring for the UTS structure. This has locks | 1753 | * Special case of dostring for the UTS structure. This has locks |
1754 | * to observe. Should this be in kernel/sys.c ???? | 1754 | * to observe. Should this be in kernel/sys.c ???? |
1755 | */ | 1755 | */ |
1756 | |||
1757 | #ifndef CONFIG_UTS_NS | ||
1758 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | ||
1759 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1760 | { | ||
1761 | int r; | ||
1762 | 1756 | ||
1763 | if (!write) { | ||
1764 | down_read(&uts_sem); | ||
1765 | r=proc_dostring(table,0,filp,buffer,lenp, ppos); | ||
1766 | up_read(&uts_sem); | ||
1767 | } else { | ||
1768 | down_write(&uts_sem); | ||
1769 | r=proc_dostring(table,1,filp,buffer,lenp, ppos); | ||
1770 | up_write(&uts_sem); | ||
1771 | } | ||
1772 | return r; | ||
1773 | } | ||
1774 | #else /* !CONFIG_UTS_NS */ | ||
1775 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | 1757 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, |
1776 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1758 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1777 | { | 1759 | { |
1778 | int r; | 1760 | int r; |
1779 | struct uts_namespace* uts_ns = current->nsproxy->uts_ns; | 1761 | void *which; |
1780 | char* which; | 1762 | which = get_uts(table, write); |
1781 | 1763 | r = _proc_do_string(which, table->maxlen,write,filp,buffer,lenp, ppos); | |
1782 | switch (table->ctl_name) { | 1764 | put_uts(table, write, which); |
1783 | case KERN_OSTYPE: | ||
1784 | which = uts_ns->name.sysname; | ||
1785 | break; | ||
1786 | case KERN_NODENAME: | ||
1787 | which = uts_ns->name.nodename; | ||
1788 | break; | ||
1789 | case KERN_OSRELEASE: | ||
1790 | which = uts_ns->name.release; | ||
1791 | break; | ||
1792 | case KERN_VERSION: | ||
1793 | which = uts_ns->name.version; | ||
1794 | break; | ||
1795 | case KERN_DOMAINNAME: | ||
1796 | which = uts_ns->name.domainname; | ||
1797 | break; | ||
1798 | default: | ||
1799 | r = -EINVAL; | ||
1800 | goto out; | ||
1801 | } | ||
1802 | |||
1803 | if (!write) { | ||
1804 | down_read(&uts_sem); | ||
1805 | r=_proc_do_string(which,table->maxlen,0,filp,buffer,lenp, ppos); | ||
1806 | up_read(&uts_sem); | ||
1807 | } else { | ||
1808 | down_write(&uts_sem); | ||
1809 | r=_proc_do_string(which,table->maxlen,1,filp,buffer,lenp, ppos); | ||
1810 | up_write(&uts_sem); | ||
1811 | } | ||
1812 | out: | ||
1813 | return r; | 1765 | return r; |
1814 | } | 1766 | } |
1815 | #endif /* !CONFIG_UTS_NS */ | ||
1816 | 1767 | ||
1817 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, | 1768 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, |
1818 | int *valp, | 1769 | int *valp, |
@@ -1976,9 +1927,6 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp, | |||
1976 | 1927 | ||
1977 | #define OP_SET 0 | 1928 | #define OP_SET 0 |
1978 | #define OP_AND 1 | 1929 | #define OP_AND 1 |
1979 | #define OP_OR 2 | ||
1980 | #define OP_MAX 3 | ||
1981 | #define OP_MIN 4 | ||
1982 | 1930 | ||
1983 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | 1931 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, |
1984 | int *valp, | 1932 | int *valp, |
@@ -1990,13 +1938,6 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | |||
1990 | switch(op) { | 1938 | switch(op) { |
1991 | case OP_SET: *valp = val; break; | 1939 | case OP_SET: *valp = val; break; |
1992 | case OP_AND: *valp &= val; break; | 1940 | case OP_AND: *valp &= val; break; |
1993 | case OP_OR: *valp |= val; break; | ||
1994 | case OP_MAX: if(*valp < val) | ||
1995 | *valp = val; | ||
1996 | break; | ||
1997 | case OP_MIN: if(*valp > val) | ||
1998 | *valp = val; | ||
1999 | break; | ||
2000 | } | 1941 | } |
2001 | } else { | 1942 | } else { |
2002 | int val = *valp; | 1943 | int val = *valp; |
@@ -2391,46 +2332,24 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, | |||
2391 | } | 2332 | } |
2392 | 2333 | ||
2393 | #ifdef CONFIG_SYSVIPC | 2334 | #ifdef CONFIG_SYSVIPC |
2394 | static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp, | 2335 | static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, |
2395 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2336 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2396 | { | 2337 | { |
2397 | void *data; | 2338 | void *which; |
2398 | struct ipc_namespace *ns; | 2339 | which = get_ipc(table, write); |
2399 | 2340 | return __do_proc_dointvec(which, table, write, filp, buffer, | |
2400 | ns = current->nsproxy->ipc_ns; | ||
2401 | |||
2402 | switch (table->ctl_name) { | ||
2403 | case KERN_SHMMAX: | ||
2404 | data = &ns->shm_ctlmax; | ||
2405 | goto proc_minmax; | ||
2406 | case KERN_SHMALL: | ||
2407 | data = &ns->shm_ctlall; | ||
2408 | goto proc_minmax; | ||
2409 | case KERN_SHMMNI: | ||
2410 | data = &ns->shm_ctlmni; | ||
2411 | break; | ||
2412 | case KERN_MSGMAX: | ||
2413 | data = &ns->msg_ctlmax; | ||
2414 | break; | ||
2415 | case KERN_MSGMNI: | ||
2416 | data = &ns->msg_ctlmni; | ||
2417 | break; | ||
2418 | case KERN_MSGMNB: | ||
2419 | data = &ns->msg_ctlmnb; | ||
2420 | break; | ||
2421 | case KERN_SEM: | ||
2422 | data = &ns->sem_ctls; | ||
2423 | break; | ||
2424 | default: | ||
2425 | return -EINVAL; | ||
2426 | } | ||
2427 | |||
2428 | return __do_proc_dointvec(data, table, write, filp, buffer, | ||
2429 | lenp, ppos, NULL, NULL); | 2341 | lenp, ppos, NULL, NULL); |
2430 | proc_minmax: | 2342 | } |
2431 | return __do_proc_doulongvec_minmax(data, table, write, filp, buffer, | 2343 | |
2344 | static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, | ||
2345 | struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2346 | { | ||
2347 | void *which; | ||
2348 | which = get_ipc(table, write); | ||
2349 | return __do_proc_doulongvec_minmax(which, table, write, filp, buffer, | ||
2432 | lenp, ppos, 1l, 1l); | 2350 | lenp, ppos, 1l, 1l); |
2433 | } | 2351 | } |
2352 | |||
2434 | #endif | 2353 | #endif |
2435 | 2354 | ||
2436 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | 2355 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, |
@@ -2475,6 +2394,17 @@ static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp, | |||
2475 | { | 2394 | { |
2476 | return -ENOSYS; | 2395 | return -ENOSYS; |
2477 | } | 2396 | } |
2397 | static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, | ||
2398 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2399 | { | ||
2400 | return -ENOSYS; | ||
2401 | } | ||
2402 | static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, | ||
2403 | struct file *filp, void __user *buffer, | ||
2404 | size_t *lenp, loff_t *ppos) | ||
2405 | { | ||
2406 | return -ENOSYS; | ||
2407 | } | ||
2478 | #endif | 2408 | #endif |
2479 | 2409 | ||
2480 | int proc_dointvec(ctl_table *table, int write, struct file *filp, | 2410 | int proc_dointvec(ctl_table *table, int write, struct file *filp, |
@@ -2539,7 +2469,7 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, | |||
2539 | /* The generic string strategy routine: */ | 2469 | /* The generic string strategy routine: */ |
2540 | int sysctl_string(ctl_table *table, int __user *name, int nlen, | 2470 | int sysctl_string(ctl_table *table, int __user *name, int nlen, |
2541 | void __user *oldval, size_t __user *oldlenp, | 2471 | void __user *oldval, size_t __user *oldlenp, |
2542 | void __user *newval, size_t newlen, void **context) | 2472 | void __user *newval, size_t newlen) |
2543 | { | 2473 | { |
2544 | if (!table->data || !table->maxlen) | 2474 | if (!table->data || !table->maxlen) |
2545 | return -ENOTDIR; | 2475 | return -ENOTDIR; |
@@ -2585,7 +2515,7 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen, | |||
2585 | */ | 2515 | */ |
2586 | int sysctl_intvec(ctl_table *table, int __user *name, int nlen, | 2516 | int sysctl_intvec(ctl_table *table, int __user *name, int nlen, |
2587 | void __user *oldval, size_t __user *oldlenp, | 2517 | void __user *oldval, size_t __user *oldlenp, |
2588 | void __user *newval, size_t newlen, void **context) | 2518 | void __user *newval, size_t newlen) |
2589 | { | 2519 | { |
2590 | 2520 | ||
2591 | if (newval && newlen) { | 2521 | if (newval && newlen) { |
@@ -2621,7 +2551,7 @@ int sysctl_intvec(ctl_table *table, int __user *name, int nlen, | |||
2621 | /* Strategy function to convert jiffies to seconds */ | 2551 | /* Strategy function to convert jiffies to seconds */ |
2622 | int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | 2552 | int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, |
2623 | void __user *oldval, size_t __user *oldlenp, | 2553 | void __user *oldval, size_t __user *oldlenp, |
2624 | void __user *newval, size_t newlen, void **context) | 2554 | void __user *newval, size_t newlen) |
2625 | { | 2555 | { |
2626 | if (oldval) { | 2556 | if (oldval) { |
2627 | size_t olen; | 2557 | size_t olen; |
@@ -2649,7 +2579,7 @@ int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2649 | /* Strategy function to convert jiffies to seconds */ | 2579 | /* Strategy function to convert jiffies to seconds */ |
2650 | int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | 2580 | int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, |
2651 | void __user *oldval, size_t __user *oldlenp, | 2581 | void __user *oldval, size_t __user *oldlenp, |
2652 | void __user *newval, size_t newlen, void **context) | 2582 | void __user *newval, size_t newlen) |
2653 | { | 2583 | { |
2654 | if (oldval) { | 2584 | if (oldval) { |
2655 | size_t olen; | 2585 | size_t olen; |
@@ -2674,6 +2604,64 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2674 | return 1; | 2604 | return 1; |
2675 | } | 2605 | } |
2676 | 2606 | ||
2607 | |||
2608 | /* The generic string strategy routine: */ | ||
2609 | static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, | ||
2610 | void __user *oldval, size_t __user *oldlenp, | ||
2611 | void __user *newval, size_t newlen) | ||
2612 | { | ||
2613 | struct ctl_table uts_table; | ||
2614 | int r, write; | ||
2615 | write = newval && newlen; | ||
2616 | memcpy(&uts_table, table, sizeof(uts_table)); | ||
2617 | uts_table.data = get_uts(table, write); | ||
2618 | r = sysctl_string(&uts_table, name, nlen, | ||
2619 | oldval, oldlenp, newval, newlen); | ||
2620 | put_uts(table, write, uts_table.data); | ||
2621 | return r; | ||
2622 | } | ||
2623 | |||
2624 | #ifdef CONFIG_SYSVIPC | ||
2625 | /* The generic sysctl ipc data routine. */ | ||
2626 | static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, | ||
2627 | void __user *oldval, size_t __user *oldlenp, | ||
2628 | void __user *newval, size_t newlen) | ||
2629 | { | ||
2630 | size_t len; | ||
2631 | void *data; | ||
2632 | |||
2633 | /* Get out of I don't have a variable */ | ||
2634 | if (!table->data || !table->maxlen) | ||
2635 | return -ENOTDIR; | ||
2636 | |||
2637 | data = get_ipc(table, 1); | ||
2638 | if (!data) | ||
2639 | return -ENOTDIR; | ||
2640 | |||
2641 | if (oldval && oldlenp) { | ||
2642 | if (get_user(len, oldlenp)) | ||
2643 | return -EFAULT; | ||
2644 | if (len) { | ||
2645 | if (len > table->maxlen) | ||
2646 | len = table->maxlen; | ||
2647 | if (copy_to_user(oldval, data, len)) | ||
2648 | return -EFAULT; | ||
2649 | if (put_user(len, oldlenp)) | ||
2650 | return -EFAULT; | ||
2651 | } | ||
2652 | } | ||
2653 | |||
2654 | if (newval && newlen) { | ||
2655 | if (newlen > table->maxlen) | ||
2656 | newlen = table->maxlen; | ||
2657 | |||
2658 | if (copy_from_user(data, newval, newlen)) | ||
2659 | return -EFAULT; | ||
2660 | } | ||
2661 | return 1; | ||
2662 | } | ||
2663 | #endif | ||
2664 | |||
2677 | #else /* CONFIG_SYSCTL_SYSCALL */ | 2665 | #else /* CONFIG_SYSCTL_SYSCALL */ |
2678 | 2666 | ||
2679 | 2667 | ||
@@ -2712,32 +2700,44 @@ out: | |||
2712 | 2700 | ||
2713 | int sysctl_string(ctl_table *table, int __user *name, int nlen, | 2701 | int sysctl_string(ctl_table *table, int __user *name, int nlen, |
2714 | void __user *oldval, size_t __user *oldlenp, | 2702 | void __user *oldval, size_t __user *oldlenp, |
2715 | void __user *newval, size_t newlen, void **context) | 2703 | void __user *newval, size_t newlen) |
2716 | { | 2704 | { |
2717 | return -ENOSYS; | 2705 | return -ENOSYS; |
2718 | } | 2706 | } |
2719 | 2707 | ||
2720 | int sysctl_intvec(ctl_table *table, int __user *name, int nlen, | 2708 | int sysctl_intvec(ctl_table *table, int __user *name, int nlen, |
2721 | void __user *oldval, size_t __user *oldlenp, | 2709 | void __user *oldval, size_t __user *oldlenp, |
2722 | void __user *newval, size_t newlen, void **context) | 2710 | void __user *newval, size_t newlen) |
2723 | { | 2711 | { |
2724 | return -ENOSYS; | 2712 | return -ENOSYS; |
2725 | } | 2713 | } |
2726 | 2714 | ||
2727 | int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | 2715 | int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, |
2728 | void __user *oldval, size_t __user *oldlenp, | 2716 | void __user *oldval, size_t __user *oldlenp, |
2729 | void __user *newval, size_t newlen, void **context) | 2717 | void __user *newval, size_t newlen) |
2730 | { | 2718 | { |
2731 | return -ENOSYS; | 2719 | return -ENOSYS; |
2732 | } | 2720 | } |
2733 | 2721 | ||
2734 | int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | 2722 | int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, |
2735 | void __user *oldval, size_t __user *oldlenp, | 2723 | void __user *oldval, size_t __user *oldlenp, |
2736 | void __user *newval, size_t newlen, void **context) | 2724 | void __user *newval, size_t newlen) |
2737 | { | 2725 | { |
2738 | return -ENOSYS; | 2726 | return -ENOSYS; |
2739 | } | 2727 | } |
2740 | 2728 | ||
2729 | static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, | ||
2730 | void __user *oldval, size_t __user *oldlenp, | ||
2731 | void __user *newval, size_t newlen) | ||
2732 | { | ||
2733 | return -ENOSYS; | ||
2734 | } | ||
2735 | static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen, | ||
2736 | void __user *oldval, size_t __user *oldlenp, | ||
2737 | void __user *newval, size_t newlen) | ||
2738 | { | ||
2739 | return -ENOSYS; | ||
2740 | } | ||
2741 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 2741 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
2742 | 2742 | ||
2743 | /* | 2743 | /* |