diff options
Diffstat (limited to 'kernel/sysctl.c')
-rw-r--r-- | kernel/sysctl.c | 676 |
1 files changed, 144 insertions, 532 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 600b33358ded..3ca1d5ff0319 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -90,12 +90,6 @@ extern char modprobe_path[]; | |||
90 | #ifdef CONFIG_CHR_DEV_SG | 90 | #ifdef CONFIG_CHR_DEV_SG |
91 | extern int sg_big_buff; | 91 | extern int sg_big_buff; |
92 | #endif | 92 | #endif |
93 | #ifdef CONFIG_SYSVIPC | ||
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, | ||
97 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
98 | #endif | ||
99 | 93 | ||
100 | #ifdef __sparc__ | 94 | #ifdef __sparc__ |
101 | extern char reboot_command []; | 95 | extern char reboot_command []; |
@@ -135,22 +129,12 @@ static int parse_table(int __user *, int, void __user *, size_t __user *, | |||
135 | void __user *, size_t, ctl_table *); | 129 | void __user *, size_t, ctl_table *); |
136 | #endif | 130 | #endif |
137 | 131 | ||
138 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | ||
139 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
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 | 132 | ||
151 | #ifdef CONFIG_PROC_SYSCTL | 133 | #ifdef CONFIG_PROC_SYSCTL |
152 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | 134 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, |
153 | void __user *buffer, size_t *lenp, loff_t *ppos); | 135 | void __user *buffer, size_t *lenp, loff_t *ppos); |
136 | static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, | ||
137 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
154 | #endif | 138 | #endif |
155 | 139 | ||
156 | static ctl_table root_table[]; | 140 | static ctl_table root_table[]; |
@@ -174,59 +158,6 @@ extern ctl_table inotify_table[]; | |||
174 | int sysctl_legacy_va_layout; | 158 | int sysctl_legacy_va_layout; |
175 | #endif | 159 | #endif |
176 | 160 | ||
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 | |||
211 | /* /proc declarations: */ | ||
212 | |||
213 | #ifdef CONFIG_PROC_SYSCTL | ||
214 | |||
215 | static ssize_t proc_readsys(struct file *, char __user *, size_t, loff_t *); | ||
216 | static ssize_t proc_writesys(struct file *, const char __user *, size_t, loff_t *); | ||
217 | static int proc_opensys(struct inode *, struct file *); | ||
218 | |||
219 | const struct file_operations proc_sys_file_operations = { | ||
220 | .open = proc_opensys, | ||
221 | .read = proc_readsys, | ||
222 | .write = proc_writesys, | ||
223 | }; | ||
224 | |||
225 | extern struct proc_dir_entry *proc_sys_root; | ||
226 | |||
227 | static void register_proc_table(ctl_table *, struct proc_dir_entry *, void *); | ||
228 | static void unregister_proc_table(ctl_table *, struct proc_dir_entry *); | ||
229 | #endif | ||
230 | 161 | ||
231 | /* The default sysctl tables: */ | 162 | /* The default sysctl tables: */ |
232 | 163 | ||
@@ -275,51 +206,6 @@ static ctl_table root_table[] = { | |||
275 | 206 | ||
276 | static ctl_table kern_table[] = { | 207 | static ctl_table kern_table[] = { |
277 | { | 208 | { |
278 | .ctl_name = KERN_OSTYPE, | ||
279 | .procname = "ostype", | ||
280 | .data = init_uts_ns.name.sysname, | ||
281 | .maxlen = sizeof(init_uts_ns.name.sysname), | ||
282 | .mode = 0444, | ||
283 | .proc_handler = &proc_do_uts_string, | ||
284 | .strategy = &sysctl_uts_string, | ||
285 | }, | ||
286 | { | ||
287 | .ctl_name = KERN_OSRELEASE, | ||
288 | .procname = "osrelease", | ||
289 | .data = init_uts_ns.name.release, | ||
290 | .maxlen = sizeof(init_uts_ns.name.release), | ||
291 | .mode = 0444, | ||
292 | .proc_handler = &proc_do_uts_string, | ||
293 | .strategy = &sysctl_uts_string, | ||
294 | }, | ||
295 | { | ||
296 | .ctl_name = KERN_VERSION, | ||
297 | .procname = "version", | ||
298 | .data = init_uts_ns.name.version, | ||
299 | .maxlen = sizeof(init_uts_ns.name.version), | ||
300 | .mode = 0444, | ||
301 | .proc_handler = &proc_do_uts_string, | ||
302 | .strategy = &sysctl_uts_string, | ||
303 | }, | ||
304 | { | ||
305 | .ctl_name = KERN_NODENAME, | ||
306 | .procname = "hostname", | ||
307 | .data = init_uts_ns.name.nodename, | ||
308 | .maxlen = sizeof(init_uts_ns.name.nodename), | ||
309 | .mode = 0644, | ||
310 | .proc_handler = &proc_do_uts_string, | ||
311 | .strategy = &sysctl_uts_string, | ||
312 | }, | ||
313 | { | ||
314 | .ctl_name = KERN_DOMAINNAME, | ||
315 | .procname = "domainname", | ||
316 | .data = init_uts_ns.name.domainname, | ||
317 | .maxlen = sizeof(init_uts_ns.name.domainname), | ||
318 | .mode = 0644, | ||
319 | .proc_handler = &proc_do_uts_string, | ||
320 | .strategy = &sysctl_uts_string, | ||
321 | }, | ||
322 | { | ||
323 | .ctl_name = KERN_PANIC, | 209 | .ctl_name = KERN_PANIC, |
324 | .procname = "panic", | 210 | .procname = "panic", |
325 | .data = &panic_timeout, | 211 | .data = &panic_timeout, |
@@ -344,14 +230,16 @@ static ctl_table kern_table[] = { | |||
344 | .proc_handler = &proc_dostring, | 230 | .proc_handler = &proc_dostring, |
345 | .strategy = &sysctl_string, | 231 | .strategy = &sysctl_string, |
346 | }, | 232 | }, |
233 | #ifdef CONFIG_PROC_SYSCTL | ||
347 | { | 234 | { |
348 | .ctl_name = KERN_TAINTED, | 235 | .ctl_name = KERN_TAINTED, |
349 | .procname = "tainted", | 236 | .procname = "tainted", |
350 | .data = &tainted, | 237 | .data = &tainted, |
351 | .maxlen = sizeof(int), | 238 | .maxlen = sizeof(int), |
352 | .mode = 0444, | 239 | .mode = 0644, |
353 | .proc_handler = &proc_dointvec, | 240 | .proc_handler = &proc_dointvec_taint, |
354 | }, | 241 | }, |
242 | #endif | ||
355 | { | 243 | { |
356 | .ctl_name = KERN_CAP_BSET, | 244 | .ctl_name = KERN_CAP_BSET, |
357 | .procname = "cap-bound", | 245 | .procname = "cap-bound", |
@@ -473,71 +361,6 @@ static ctl_table kern_table[] = { | |||
473 | .proc_handler = &proc_dointvec, | 361 | .proc_handler = &proc_dointvec, |
474 | }, | 362 | }, |
475 | #endif | 363 | #endif |
476 | #ifdef CONFIG_SYSVIPC | ||
477 | { | ||
478 | .ctl_name = KERN_SHMMAX, | ||
479 | .procname = "shmmax", | ||
480 | .data = &init_ipc_ns.shm_ctlmax, | ||
481 | .maxlen = sizeof (init_ipc_ns.shm_ctlmax), | ||
482 | .mode = 0644, | ||
483 | .proc_handler = &proc_ipc_doulongvec_minmax, | ||
484 | .strategy = sysctl_ipc_data, | ||
485 | }, | ||
486 | { | ||
487 | .ctl_name = KERN_SHMALL, | ||
488 | .procname = "shmall", | ||
489 | .data = &init_ipc_ns.shm_ctlall, | ||
490 | .maxlen = sizeof (init_ipc_ns.shm_ctlall), | ||
491 | .mode = 0644, | ||
492 | .proc_handler = &proc_ipc_doulongvec_minmax, | ||
493 | .strategy = sysctl_ipc_data, | ||
494 | }, | ||
495 | { | ||
496 | .ctl_name = KERN_SHMMNI, | ||
497 | .procname = "shmmni", | ||
498 | .data = &init_ipc_ns.shm_ctlmni, | ||
499 | .maxlen = sizeof (init_ipc_ns.shm_ctlmni), | ||
500 | .mode = 0644, | ||
501 | .proc_handler = &proc_ipc_dointvec, | ||
502 | .strategy = sysctl_ipc_data, | ||
503 | }, | ||
504 | { | ||
505 | .ctl_name = KERN_MSGMAX, | ||
506 | .procname = "msgmax", | ||
507 | .data = &init_ipc_ns.msg_ctlmax, | ||
508 | .maxlen = sizeof (init_ipc_ns.msg_ctlmax), | ||
509 | .mode = 0644, | ||
510 | .proc_handler = &proc_ipc_dointvec, | ||
511 | .strategy = sysctl_ipc_data, | ||
512 | }, | ||
513 | { | ||
514 | .ctl_name = KERN_MSGMNI, | ||
515 | .procname = "msgmni", | ||
516 | .data = &init_ipc_ns.msg_ctlmni, | ||
517 | .maxlen = sizeof (init_ipc_ns.msg_ctlmni), | ||
518 | .mode = 0644, | ||
519 | .proc_handler = &proc_ipc_dointvec, | ||
520 | .strategy = sysctl_ipc_data, | ||
521 | }, | ||
522 | { | ||
523 | .ctl_name = KERN_MSGMNB, | ||
524 | .procname = "msgmnb", | ||
525 | .data = &init_ipc_ns.msg_ctlmnb, | ||
526 | .maxlen = sizeof (init_ipc_ns.msg_ctlmnb), | ||
527 | .mode = 0644, | ||
528 | .proc_handler = &proc_ipc_dointvec, | ||
529 | .strategy = sysctl_ipc_data, | ||
530 | }, | ||
531 | { | ||
532 | .ctl_name = KERN_SEM, | ||
533 | .procname = "sem", | ||
534 | .data = &init_ipc_ns.sem_ctls, | ||
535 | .maxlen = 4*sizeof (int), | ||
536 | .mode = 0644, | ||
537 | .proc_handler = &proc_ipc_dointvec, | ||
538 | .strategy = sysctl_ipc_data, | ||
539 | }, | ||
540 | #endif | ||
541 | #ifdef CONFIG_MAGIC_SYSRQ | 364 | #ifdef CONFIG_MAGIC_SYSRQ |
542 | { | 365 | { |
543 | .ctl_name = KERN_SYSRQ, | 366 | .ctl_name = KERN_SYSRQ, |
@@ -1038,6 +861,12 @@ static ctl_table vm_table[] = { | |||
1038 | { .ctl_name = 0 } | 861 | { .ctl_name = 0 } |
1039 | }; | 862 | }; |
1040 | 863 | ||
864 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | ||
865 | static ctl_table binfmt_misc_table[] = { | ||
866 | { .ctl_name = 0 } | ||
867 | }; | ||
868 | #endif | ||
869 | |||
1041 | static ctl_table fs_table[] = { | 870 | static ctl_table fs_table[] = { |
1042 | { | 871 | { |
1043 | .ctl_name = FS_NRINODE, | 872 | .ctl_name = FS_NRINODE, |
@@ -1161,6 +990,14 @@ static ctl_table fs_table[] = { | |||
1161 | .mode = 0644, | 990 | .mode = 0644, |
1162 | .proc_handler = &proc_dointvec, | 991 | .proc_handler = &proc_dointvec, |
1163 | }, | 992 | }, |
993 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | ||
994 | { | ||
995 | .ctl_name = CTL_UNNUMBERED, | ||
996 | .procname = "binfmt_misc", | ||
997 | .mode = 0555, | ||
998 | .child = binfmt_misc_table, | ||
999 | }, | ||
1000 | #endif | ||
1164 | { .ctl_name = 0 } | 1001 | { .ctl_name = 0 } |
1165 | }; | 1002 | }; |
1166 | 1003 | ||
@@ -1172,8 +1009,6 @@ static ctl_table dev_table[] = { | |||
1172 | { .ctl_name = 0 } | 1009 | { .ctl_name = 0 } |
1173 | }; | 1010 | }; |
1174 | 1011 | ||
1175 | extern void init_irq_proc (void); | ||
1176 | |||
1177 | static DEFINE_SPINLOCK(sysctl_lock); | 1012 | static DEFINE_SPINLOCK(sysctl_lock); |
1178 | 1013 | ||
1179 | /* called under sysctl_lock */ | 1014 | /* called under sysctl_lock */ |
@@ -1215,19 +1050,47 @@ static void start_unregistering(struct ctl_table_header *p) | |||
1215 | list_del_init(&p->ctl_entry); | 1050 | list_del_init(&p->ctl_entry); |
1216 | } | 1051 | } |
1217 | 1052 | ||
1218 | void __init sysctl_init(void) | 1053 | void sysctl_head_finish(struct ctl_table_header *head) |
1219 | { | 1054 | { |
1220 | #ifdef CONFIG_PROC_SYSCTL | 1055 | if (!head) |
1221 | register_proc_table(root_table, proc_sys_root, &root_table_header); | 1056 | return; |
1222 | init_irq_proc(); | 1057 | spin_lock(&sysctl_lock); |
1223 | #endif | 1058 | unuse_table(head); |
1059 | spin_unlock(&sysctl_lock); | ||
1060 | } | ||
1061 | |||
1062 | struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) | ||
1063 | { | ||
1064 | struct ctl_table_header *head; | ||
1065 | struct list_head *tmp; | ||
1066 | spin_lock(&sysctl_lock); | ||
1067 | if (prev) { | ||
1068 | tmp = &prev->ctl_entry; | ||
1069 | unuse_table(prev); | ||
1070 | goto next; | ||
1071 | } | ||
1072 | tmp = &root_table_header.ctl_entry; | ||
1073 | for (;;) { | ||
1074 | head = list_entry(tmp, struct ctl_table_header, ctl_entry); | ||
1075 | |||
1076 | if (!use_table(head)) | ||
1077 | goto next; | ||
1078 | spin_unlock(&sysctl_lock); | ||
1079 | return head; | ||
1080 | next: | ||
1081 | tmp = tmp->next; | ||
1082 | if (tmp == &root_table_header.ctl_entry) | ||
1083 | break; | ||
1084 | } | ||
1085 | spin_unlock(&sysctl_lock); | ||
1086 | return NULL; | ||
1224 | } | 1087 | } |
1225 | 1088 | ||
1226 | #ifdef CONFIG_SYSCTL_SYSCALL | 1089 | #ifdef CONFIG_SYSCTL_SYSCALL |
1227 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, | 1090 | int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, |
1228 | void __user *newval, size_t newlen) | 1091 | void __user *newval, size_t newlen) |
1229 | { | 1092 | { |
1230 | struct list_head *tmp; | 1093 | struct ctl_table_header *head; |
1231 | int error = -ENOTDIR; | 1094 | int error = -ENOTDIR; |
1232 | 1095 | ||
1233 | if (nlen <= 0 || nlen >= CTL_MAXNAME) | 1096 | if (nlen <= 0 || nlen >= CTL_MAXNAME) |
@@ -1237,26 +1100,16 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol | |||
1237 | if (!oldlenp || get_user(old_len, oldlenp)) | 1100 | if (!oldlenp || get_user(old_len, oldlenp)) |
1238 | return -EFAULT; | 1101 | return -EFAULT; |
1239 | } | 1102 | } |
1240 | spin_lock(&sysctl_lock); | ||
1241 | tmp = &root_table_header.ctl_entry; | ||
1242 | do { | ||
1243 | struct ctl_table_header *head = | ||
1244 | list_entry(tmp, struct ctl_table_header, ctl_entry); | ||
1245 | |||
1246 | if (!use_table(head)) | ||
1247 | continue; | ||
1248 | |||
1249 | spin_unlock(&sysctl_lock); | ||
1250 | 1103 | ||
1104 | for (head = sysctl_head_next(NULL); head; | ||
1105 | head = sysctl_head_next(head)) { | ||
1251 | error = parse_table(name, nlen, oldval, oldlenp, | 1106 | error = parse_table(name, nlen, oldval, oldlenp, |
1252 | newval, newlen, head->ctl_table); | 1107 | newval, newlen, head->ctl_table); |
1253 | 1108 | if (error != -ENOTDIR) { | |
1254 | spin_lock(&sysctl_lock); | 1109 | sysctl_head_finish(head); |
1255 | unuse_table(head); | ||
1256 | if (error != -ENOTDIR) | ||
1257 | break; | 1110 | break; |
1258 | } while ((tmp = tmp->next) != &root_table_header.ctl_entry); | 1111 | } |
1259 | spin_unlock(&sysctl_lock); | 1112 | } |
1260 | return error; | 1113 | return error; |
1261 | } | 1114 | } |
1262 | 1115 | ||
@@ -1277,7 +1130,7 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | |||
1277 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 1130 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
1278 | 1131 | ||
1279 | /* | 1132 | /* |
1280 | * ctl_perm does NOT grant the superuser all rights automatically, because | 1133 | * sysctl_perm does NOT grant the superuser all rights automatically, because |
1281 | * some sysctl variables are readonly even to root. | 1134 | * some sysctl variables are readonly even to root. |
1282 | */ | 1135 | */ |
1283 | 1136 | ||
@@ -1292,7 +1145,7 @@ static int test_perm(int mode, int op) | |||
1292 | return -EACCES; | 1145 | return -EACCES; |
1293 | } | 1146 | } |
1294 | 1147 | ||
1295 | static inline int ctl_perm(ctl_table *table, int op) | 1148 | int sysctl_perm(ctl_table *table, int op) |
1296 | { | 1149 | { |
1297 | int error; | 1150 | int error; |
1298 | error = security_sysctl(table, op); | 1151 | error = security_sysctl(table, op); |
@@ -1316,19 +1169,11 @@ repeat: | |||
1316 | for ( ; table->ctl_name || table->procname; table++) { | 1169 | for ( ; table->ctl_name || table->procname; table++) { |
1317 | if (!table->ctl_name) | 1170 | if (!table->ctl_name) |
1318 | continue; | 1171 | continue; |
1319 | if (n == table->ctl_name || table->ctl_name == CTL_ANY) { | 1172 | if (n == table->ctl_name) { |
1320 | int error; | 1173 | int error; |
1321 | if (table->child) { | 1174 | if (table->child) { |
1322 | if (ctl_perm(table, 001)) | 1175 | if (sysctl_perm(table, 001)) |
1323 | return -EPERM; | 1176 | return -EPERM; |
1324 | if (table->strategy) { | ||
1325 | error = table->strategy( | ||
1326 | table, name, nlen, | ||
1327 | oldval, oldlenp, | ||
1328 | newval, newlen); | ||
1329 | if (error) | ||
1330 | return error; | ||
1331 | } | ||
1332 | name++; | 1177 | name++; |
1333 | nlen--; | 1178 | nlen--; |
1334 | table = table->child; | 1179 | table = table->child; |
@@ -1356,7 +1201,7 @@ int do_sysctl_strategy (ctl_table *table, | |||
1356 | op |= 004; | 1201 | op |= 004; |
1357 | if (newval) | 1202 | if (newval) |
1358 | op |= 002; | 1203 | op |= 002; |
1359 | if (ctl_perm(table, op)) | 1204 | if (sysctl_perm(table, op)) |
1360 | return -EPERM; | 1205 | return -EPERM; |
1361 | 1206 | ||
1362 | if (table->strategy) { | 1207 | if (table->strategy) { |
@@ -1395,10 +1240,26 @@ int do_sysctl_strategy (ctl_table *table, | |||
1395 | } | 1240 | } |
1396 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 1241 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
1397 | 1242 | ||
1243 | static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) | ||
1244 | { | ||
1245 | for (; table->ctl_name || table->procname; table++) { | ||
1246 | table->parent = parent; | ||
1247 | if (table->child) | ||
1248 | sysctl_set_parent(table, table->child); | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | static __init int sysctl_init(void) | ||
1253 | { | ||
1254 | sysctl_set_parent(NULL, root_table); | ||
1255 | return 0; | ||
1256 | } | ||
1257 | |||
1258 | core_initcall(sysctl_init); | ||
1259 | |||
1398 | /** | 1260 | /** |
1399 | * register_sysctl_table - register a sysctl hierarchy | 1261 | * register_sysctl_table - register a sysctl hierarchy |
1400 | * @table: the top-level table structure | 1262 | * @table: the top-level table structure |
1401 | * @insert_at_head: whether the entry should be inserted in front or at the end | ||
1402 | * | 1263 | * |
1403 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table | 1264 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table |
1404 | * array. An entry with a ctl_name of 0 terminates the table. | 1265 | * array. An entry with a ctl_name of 0 terminates the table. |
@@ -1464,8 +1325,7 @@ int do_sysctl_strategy (ctl_table *table, | |||
1464 | * This routine returns %NULL on a failure to register, and a pointer | 1325 | * This routine returns %NULL on a failure to register, and a pointer |
1465 | * to the table header on success. | 1326 | * to the table header on success. |
1466 | */ | 1327 | */ |
1467 | struct ctl_table_header *register_sysctl_table(ctl_table * table, | 1328 | struct ctl_table_header *register_sysctl_table(ctl_table * table) |
1468 | int insert_at_head) | ||
1469 | { | 1329 | { |
1470 | struct ctl_table_header *tmp; | 1330 | struct ctl_table_header *tmp; |
1471 | tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); | 1331 | tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); |
@@ -1475,15 +1335,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table, | |||
1475 | INIT_LIST_HEAD(&tmp->ctl_entry); | 1335 | INIT_LIST_HEAD(&tmp->ctl_entry); |
1476 | tmp->used = 0; | 1336 | tmp->used = 0; |
1477 | tmp->unregistering = NULL; | 1337 | tmp->unregistering = NULL; |
1338 | sysctl_set_parent(NULL, table); | ||
1478 | spin_lock(&sysctl_lock); | 1339 | spin_lock(&sysctl_lock); |
1479 | if (insert_at_head) | 1340 | list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); |
1480 | list_add(&tmp->ctl_entry, &root_table_header.ctl_entry); | ||
1481 | else | ||
1482 | list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); | ||
1483 | spin_unlock(&sysctl_lock); | 1341 | spin_unlock(&sysctl_lock); |
1484 | #ifdef CONFIG_PROC_SYSCTL | ||
1485 | register_proc_table(table, proc_sys_root, tmp); | ||
1486 | #endif | ||
1487 | return tmp; | 1342 | return tmp; |
1488 | } | 1343 | } |
1489 | 1344 | ||
@@ -1499,9 +1354,6 @@ void unregister_sysctl_table(struct ctl_table_header * header) | |||
1499 | might_sleep(); | 1354 | might_sleep(); |
1500 | spin_lock(&sysctl_lock); | 1355 | spin_lock(&sysctl_lock); |
1501 | start_unregistering(header); | 1356 | start_unregistering(header); |
1502 | #ifdef CONFIG_PROC_SYSCTL | ||
1503 | unregister_proc_table(header->ctl_table, proc_sys_root); | ||
1504 | #endif | ||
1505 | spin_unlock(&sysctl_lock); | 1357 | spin_unlock(&sysctl_lock); |
1506 | kfree(header); | 1358 | kfree(header); |
1507 | } | 1359 | } |
@@ -1525,155 +1377,6 @@ void unregister_sysctl_table(struct ctl_table_header * table) | |||
1525 | 1377 | ||
1526 | #ifdef CONFIG_PROC_SYSCTL | 1378 | #ifdef CONFIG_PROC_SYSCTL |
1527 | 1379 | ||
1528 | /* Scan the sysctl entries in table and add them all into /proc */ | ||
1529 | static void register_proc_table(ctl_table * table, struct proc_dir_entry *root, void *set) | ||
1530 | { | ||
1531 | struct proc_dir_entry *de; | ||
1532 | int len; | ||
1533 | mode_t mode; | ||
1534 | |||
1535 | for (; table->ctl_name || table->procname; table++) { | ||
1536 | /* Can't do anything without a proc name. */ | ||
1537 | if (!table->procname) | ||
1538 | continue; | ||
1539 | /* Maybe we can't do anything with it... */ | ||
1540 | if (!table->proc_handler && !table->child) { | ||
1541 | printk(KERN_WARNING "SYSCTL: Can't register %s\n", | ||
1542 | table->procname); | ||
1543 | continue; | ||
1544 | } | ||
1545 | |||
1546 | len = strlen(table->procname); | ||
1547 | mode = table->mode; | ||
1548 | |||
1549 | de = NULL; | ||
1550 | if (table->proc_handler) | ||
1551 | mode |= S_IFREG; | ||
1552 | else { | ||
1553 | mode |= S_IFDIR; | ||
1554 | for (de = root->subdir; de; de = de->next) { | ||
1555 | if (proc_match(len, table->procname, de)) | ||
1556 | break; | ||
1557 | } | ||
1558 | /* If the subdir exists already, de is non-NULL */ | ||
1559 | } | ||
1560 | |||
1561 | if (!de) { | ||
1562 | de = create_proc_entry(table->procname, mode, root); | ||
1563 | if (!de) | ||
1564 | continue; | ||
1565 | de->set = set; | ||
1566 | de->data = (void *) table; | ||
1567 | if (table->proc_handler) | ||
1568 | de->proc_fops = &proc_sys_file_operations; | ||
1569 | } | ||
1570 | table->de = de; | ||
1571 | if (de->mode & S_IFDIR) | ||
1572 | register_proc_table(table->child, de, set); | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | /* | ||
1577 | * Unregister a /proc sysctl table and any subdirectories. | ||
1578 | */ | ||
1579 | static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root) | ||
1580 | { | ||
1581 | struct proc_dir_entry *de; | ||
1582 | for (; table->ctl_name || table->procname; table++) { | ||
1583 | if (!(de = table->de)) | ||
1584 | continue; | ||
1585 | if (de->mode & S_IFDIR) { | ||
1586 | if (!table->child) { | ||
1587 | printk (KERN_ALERT "Help - malformed sysctl tree on free\n"); | ||
1588 | continue; | ||
1589 | } | ||
1590 | unregister_proc_table(table->child, de); | ||
1591 | |||
1592 | /* Don't unregister directories which still have entries.. */ | ||
1593 | if (de->subdir) | ||
1594 | continue; | ||
1595 | } | ||
1596 | |||
1597 | /* | ||
1598 | * In any case, mark the entry as goner; we'll keep it | ||
1599 | * around if it's busy, but we'll know to do nothing with | ||
1600 | * its fields. We are under sysctl_lock here. | ||
1601 | */ | ||
1602 | de->data = NULL; | ||
1603 | |||
1604 | /* Don't unregister proc entries that are still being used.. */ | ||
1605 | if (atomic_read(&de->count)) | ||
1606 | continue; | ||
1607 | |||
1608 | table->de = NULL; | ||
1609 | remove_proc_entry(table->procname, root); | ||
1610 | } | ||
1611 | } | ||
1612 | |||
1613 | static ssize_t do_rw_proc(int write, struct file * file, char __user * buf, | ||
1614 | size_t count, loff_t *ppos) | ||
1615 | { | ||
1616 | int op; | ||
1617 | struct proc_dir_entry *de = PDE(file->f_path.dentry->d_inode); | ||
1618 | struct ctl_table *table; | ||
1619 | size_t res; | ||
1620 | ssize_t error = -ENOTDIR; | ||
1621 | |||
1622 | spin_lock(&sysctl_lock); | ||
1623 | if (de && de->data && use_table(de->set)) { | ||
1624 | /* | ||
1625 | * at that point we know that sysctl was not unregistered | ||
1626 | * and won't be until we finish | ||
1627 | */ | ||
1628 | spin_unlock(&sysctl_lock); | ||
1629 | table = (struct ctl_table *) de->data; | ||
1630 | if (!table || !table->proc_handler) | ||
1631 | goto out; | ||
1632 | error = -EPERM; | ||
1633 | op = (write ? 002 : 004); | ||
1634 | if (ctl_perm(table, op)) | ||
1635 | goto out; | ||
1636 | |||
1637 | /* careful: calling conventions are nasty here */ | ||
1638 | res = count; | ||
1639 | error = (*table->proc_handler)(table, write, file, | ||
1640 | buf, &res, ppos); | ||
1641 | if (!error) | ||
1642 | error = res; | ||
1643 | out: | ||
1644 | spin_lock(&sysctl_lock); | ||
1645 | unuse_table(de->set); | ||
1646 | } | ||
1647 | spin_unlock(&sysctl_lock); | ||
1648 | return error; | ||
1649 | } | ||
1650 | |||
1651 | static int proc_opensys(struct inode *inode, struct file *file) | ||
1652 | { | ||
1653 | if (file->f_mode & FMODE_WRITE) { | ||
1654 | /* | ||
1655 | * sysctl entries that are not writable, | ||
1656 | * are _NOT_ writable, capabilities or not. | ||
1657 | */ | ||
1658 | if (!(inode->i_mode & S_IWUSR)) | ||
1659 | return -EPERM; | ||
1660 | } | ||
1661 | |||
1662 | return 0; | ||
1663 | } | ||
1664 | |||
1665 | static ssize_t proc_readsys(struct file * file, char __user * buf, | ||
1666 | size_t count, loff_t *ppos) | ||
1667 | { | ||
1668 | return do_rw_proc(0, file, buf, count, ppos); | ||
1669 | } | ||
1670 | |||
1671 | static ssize_t proc_writesys(struct file * file, const char __user * buf, | ||
1672 | size_t count, loff_t *ppos) | ||
1673 | { | ||
1674 | return do_rw_proc(1, file, (char __user *) buf, count, ppos); | ||
1675 | } | ||
1676 | |||
1677 | static int _proc_do_string(void* data, int maxlen, int write, | 1380 | static int _proc_do_string(void* data, int maxlen, int write, |
1678 | struct file *filp, void __user *buffer, | 1381 | struct file *filp, void __user *buffer, |
1679 | size_t *lenp, loff_t *ppos) | 1382 | size_t *lenp, loff_t *ppos) |
@@ -1681,13 +1384,12 @@ static int _proc_do_string(void* data, int maxlen, int write, | |||
1681 | size_t len; | 1384 | size_t len; |
1682 | char __user *p; | 1385 | char __user *p; |
1683 | char c; | 1386 | char c; |
1684 | 1387 | ||
1685 | if (!data || !maxlen || !*lenp || | 1388 | if (!data || !maxlen || !*lenp) { |
1686 | (*ppos && !write)) { | ||
1687 | *lenp = 0; | 1389 | *lenp = 0; |
1688 | return 0; | 1390 | return 0; |
1689 | } | 1391 | } |
1690 | 1392 | ||
1691 | if (write) { | 1393 | if (write) { |
1692 | len = 0; | 1394 | len = 0; |
1693 | p = buffer; | 1395 | p = buffer; |
@@ -1708,6 +1410,15 @@ static int _proc_do_string(void* data, int maxlen, int write, | |||
1708 | len = strlen(data); | 1410 | len = strlen(data); |
1709 | if (len > maxlen) | 1411 | if (len > maxlen) |
1710 | len = maxlen; | 1412 | len = maxlen; |
1413 | |||
1414 | if (*ppos > len) { | ||
1415 | *lenp = 0; | ||
1416 | return 0; | ||
1417 | } | ||
1418 | |||
1419 | data += *ppos; | ||
1420 | len -= *ppos; | ||
1421 | |||
1711 | if (len > *lenp) | 1422 | if (len > *lenp) |
1712 | len = *lenp; | 1423 | len = *lenp; |
1713 | if (len) | 1424 | if (len) |
@@ -1749,21 +1460,6 @@ int proc_dostring(ctl_table *table, int write, struct file *filp, | |||
1749 | buffer, lenp, ppos); | 1460 | buffer, lenp, ppos); |
1750 | } | 1461 | } |
1751 | 1462 | ||
1752 | /* | ||
1753 | * Special case of dostring for the UTS structure. This has locks | ||
1754 | * to observe. Should this be in kernel/sys.c ???? | ||
1755 | */ | ||
1756 | |||
1757 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | ||
1758 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1759 | { | ||
1760 | int r; | ||
1761 | void *which; | ||
1762 | which = get_uts(table, write); | ||
1763 | r = _proc_do_string(which, table->maxlen,write,filp,buffer,lenp, ppos); | ||
1764 | put_uts(table, write, which); | ||
1765 | return r; | ||
1766 | } | ||
1767 | 1463 | ||
1768 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, | 1464 | static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, |
1769 | int *valp, | 1465 | int *valp, |
@@ -1927,6 +1623,7 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp, | |||
1927 | 1623 | ||
1928 | #define OP_SET 0 | 1624 | #define OP_SET 0 |
1929 | #define OP_AND 1 | 1625 | #define OP_AND 1 |
1626 | #define OP_OR 2 | ||
1930 | 1627 | ||
1931 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | 1628 | static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, |
1932 | int *valp, | 1629 | int *valp, |
@@ -1938,6 +1635,7 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | |||
1938 | switch(op) { | 1635 | switch(op) { |
1939 | case OP_SET: *valp = val; break; | 1636 | case OP_SET: *valp = val; break; |
1940 | case OP_AND: *valp &= val; break; | 1637 | case OP_AND: *valp &= val; break; |
1638 | case OP_OR: *valp |= val; break; | ||
1941 | } | 1639 | } |
1942 | } else { | 1640 | } else { |
1943 | int val = *valp; | 1641 | int val = *valp; |
@@ -1961,7 +1659,7 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, | |||
1961 | { | 1659 | { |
1962 | int op; | 1660 | int op; |
1963 | 1661 | ||
1964 | if (!capable(CAP_SYS_MODULE)) { | 1662 | if (write && !capable(CAP_SYS_MODULE)) { |
1965 | return -EPERM; | 1663 | return -EPERM; |
1966 | } | 1664 | } |
1967 | 1665 | ||
@@ -1970,6 +1668,22 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, | |||
1970 | do_proc_dointvec_bset_conv,&op); | 1668 | do_proc_dointvec_bset_conv,&op); |
1971 | } | 1669 | } |
1972 | 1670 | ||
1671 | /* | ||
1672 | * Taint values can only be increased | ||
1673 | */ | ||
1674 | static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, | ||
1675 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
1676 | { | ||
1677 | int op; | ||
1678 | |||
1679 | if (!capable(CAP_SYS_ADMIN)) | ||
1680 | return -EPERM; | ||
1681 | |||
1682 | op = OP_OR; | ||
1683 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | ||
1684 | do_proc_dointvec_bset_conv,&op); | ||
1685 | } | ||
1686 | |||
1973 | struct do_proc_dointvec_minmax_conv_param { | 1687 | struct do_proc_dointvec_minmax_conv_param { |
1974 | int *min; | 1688 | int *min; |
1975 | int *max; | 1689 | int *max; |
@@ -2331,27 +2045,6 @@ int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, | |||
2331 | do_proc_dointvec_ms_jiffies_conv, NULL); | 2045 | do_proc_dointvec_ms_jiffies_conv, NULL); |
2332 | } | 2046 | } |
2333 | 2047 | ||
2334 | #ifdef CONFIG_SYSVIPC | ||
2335 | static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, | ||
2336 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2337 | { | ||
2338 | void *which; | ||
2339 | which = get_ipc(table, write); | ||
2340 | return __do_proc_dointvec(which, table, write, filp, buffer, | ||
2341 | lenp, ppos, NULL, NULL); | ||
2342 | } | ||
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, | ||
2350 | lenp, ppos, 1l, 1l); | ||
2351 | } | ||
2352 | |||
2353 | #endif | ||
2354 | |||
2355 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | 2048 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, |
2356 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2049 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2357 | { | 2050 | { |
@@ -2382,31 +2075,6 @@ int proc_dostring(ctl_table *table, int write, struct file *filp, | |||
2382 | return -ENOSYS; | 2075 | return -ENOSYS; |
2383 | } | 2076 | } |
2384 | 2077 | ||
2385 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | ||
2386 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2387 | { | ||
2388 | return -ENOSYS; | ||
2389 | } | ||
2390 | |||
2391 | #ifdef CONFIG_SYSVIPC | ||
2392 | static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp, | ||
2393 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2394 | { | ||
2395 | return -ENOSYS; | ||
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 | } | ||
2408 | #endif | ||
2409 | |||
2410 | int proc_dointvec(ctl_table *table, int write, struct file *filp, | 2078 | int proc_dointvec(ctl_table *table, int write, struct file *filp, |
2411 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2079 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2412 | { | 2080 | { |
@@ -2553,17 +2221,23 @@ int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2553 | void __user *oldval, size_t __user *oldlenp, | 2221 | void __user *oldval, size_t __user *oldlenp, |
2554 | void __user *newval, size_t newlen) | 2222 | void __user *newval, size_t newlen) |
2555 | { | 2223 | { |
2556 | if (oldval) { | 2224 | if (oldval && oldlenp) { |
2557 | size_t olen; | 2225 | size_t olen; |
2558 | if (oldlenp) { | 2226 | |
2559 | if (get_user(olen, oldlenp)) | 2227 | if (get_user(olen, oldlenp)) |
2228 | return -EFAULT; | ||
2229 | if (olen) { | ||
2230 | int val; | ||
2231 | |||
2232 | if (olen < sizeof(int)) | ||
2233 | return -EINVAL; | ||
2234 | |||
2235 | val = *(int *)(table->data) / HZ; | ||
2236 | if (put_user(val, (int __user *)oldval)) | ||
2237 | return -EFAULT; | ||
2238 | if (put_user(sizeof(int), oldlenp)) | ||
2560 | return -EFAULT; | 2239 | return -EFAULT; |
2561 | if (olen!=sizeof(int)) | ||
2562 | return -EINVAL; | ||
2563 | } | 2240 | } |
2564 | if (put_user(*(int *)(table->data)/HZ, (int __user *)oldval) || | ||
2565 | (oldlenp && put_user(sizeof(int),oldlenp))) | ||
2566 | return -EFAULT; | ||
2567 | } | 2241 | } |
2568 | if (newval && newlen) { | 2242 | if (newval && newlen) { |
2569 | int new; | 2243 | int new; |
@@ -2581,17 +2255,23 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2581 | void __user *oldval, size_t __user *oldlenp, | 2255 | void __user *oldval, size_t __user *oldlenp, |
2582 | void __user *newval, size_t newlen) | 2256 | void __user *newval, size_t newlen) |
2583 | { | 2257 | { |
2584 | if (oldval) { | 2258 | if (oldval && oldlenp) { |
2585 | size_t olen; | 2259 | size_t olen; |
2586 | if (oldlenp) { | 2260 | |
2587 | if (get_user(olen, oldlenp)) | 2261 | if (get_user(olen, oldlenp)) |
2262 | return -EFAULT; | ||
2263 | if (olen) { | ||
2264 | int val; | ||
2265 | |||
2266 | if (olen < sizeof(int)) | ||
2267 | return -EINVAL; | ||
2268 | |||
2269 | val = jiffies_to_msecs(*(int *)(table->data)); | ||
2270 | if (put_user(val, (int __user *)oldval)) | ||
2271 | return -EFAULT; | ||
2272 | if (put_user(sizeof(int), oldlenp)) | ||
2588 | return -EFAULT; | 2273 | return -EFAULT; |
2589 | if (olen!=sizeof(int)) | ||
2590 | return -EINVAL; | ||
2591 | } | 2274 | } |
2592 | if (put_user(jiffies_to_msecs(*(int *)(table->data)), (int __user *)oldval) || | ||
2593 | (oldlenp && put_user(sizeof(int),oldlenp))) | ||
2594 | return -EFAULT; | ||
2595 | } | 2275 | } |
2596 | if (newval && newlen) { | 2276 | if (newval && newlen) { |
2597 | int new; | 2277 | int new; |
@@ -2605,62 +2285,6 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2605 | } | 2285 | } |
2606 | 2286 | ||
2607 | 2287 | ||
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 | 2288 | ||
2665 | #else /* CONFIG_SYSCTL_SYSCALL */ | 2289 | #else /* CONFIG_SYSCTL_SYSCALL */ |
2666 | 2290 | ||
@@ -2726,18 +2350,6 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2726 | return -ENOSYS; | 2350 | return -ENOSYS; |
2727 | } | 2351 | } |
2728 | 2352 | ||
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 */ | 2353 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
2742 | 2354 | ||
2743 | /* | 2355 | /* |