diff options
| author | Cedric Le Goater <clg@fr.ibm.com> | 2006-10-02 05:19:00 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:25 -0400 |
| commit | 9ec52099e4b8678a60e9f93e41ad87885d64f3e6 (patch) | |
| tree | a68fe051b39f8f8e8be469cbd3c2f653b9b71a9d /kernel | |
| parent | 1a657f78dcc8ea7c53eaa1f2a45ea2315738c15f (diff) | |
[PATCH] replace cad_pid by a struct pid
There are a few places in the kernel where the init task is signaled. The
ctrl+alt+del sequence is one them. It kills a task, usually init, using a
cached pid (cad_pid).
This patch replaces the pid_t by a struct pid to avoid pid wrap around
problem. The struct pid is initialized at boot time in init() and can be
modified through systctl with
/proc/sys/kernel/cad_pid
[ I haven't found any distro using it ? ]
It also introduces a small helper routine kill_cad_pid() which is used
where it seemed ok to use cad_pid instead of pid 1.
[akpm@osdl.org: cleanups, build fix]
Signed-off-by: Cedric Le Goater <clg@fr.ibm.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sys.c | 6 | ||||
| -rw-r--r-- | kernel/sysctl.c | 30 |
2 files changed, 30 insertions, 6 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 3a4776e8f16e..2314867ae34f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -92,7 +92,8 @@ EXPORT_SYMBOL(fs_overflowgid); | |||
| 92 | */ | 92 | */ |
| 93 | 93 | ||
| 94 | int C_A_D = 1; | 94 | int C_A_D = 1; |
| 95 | int cad_pid = 1; | 95 | struct pid *cad_pid; |
| 96 | EXPORT_SYMBOL(cad_pid); | ||
| 96 | 97 | ||
| 97 | /* | 98 | /* |
| 98 | * Notifier list for kernel code which wants to be called | 99 | * Notifier list for kernel code which wants to be called |
| @@ -773,10 +774,9 @@ void ctrl_alt_del(void) | |||
| 773 | if (C_A_D) | 774 | if (C_A_D) |
| 774 | schedule_work(&cad_work); | 775 | schedule_work(&cad_work); |
| 775 | else | 776 | else |
| 776 | kill_proc(cad_pid, SIGINT, 1); | 777 | kill_cad_pid(SIGINT, 1); |
| 777 | } | 778 | } |
| 778 | 779 | ||
| 779 | |||
| 780 | /* | 780 | /* |
| 781 | * Unprivileged users may change the real gid to the effective gid | 781 | * Unprivileged users may change the real gid to the effective gid |
| 782 | * or vice versa. (BSD-style) | 782 | * or vice versa. (BSD-style) |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index a79ccf9d113b..8020fb273c4f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -68,7 +68,6 @@ extern int sysrq_enabled; | |||
| 68 | extern int core_uses_pid; | 68 | extern int core_uses_pid; |
| 69 | extern int suid_dumpable; | 69 | extern int suid_dumpable; |
| 70 | extern char core_pattern[]; | 70 | extern char core_pattern[]; |
| 71 | extern int cad_pid; | ||
| 72 | extern int pid_max; | 71 | extern int pid_max; |
| 73 | extern int min_free_kbytes; | 72 | extern int min_free_kbytes; |
| 74 | extern int printk_ratelimit_jiffies; | 73 | extern int printk_ratelimit_jiffies; |
| @@ -137,6 +136,9 @@ static int parse_table(int __user *, int, void __user *, size_t __user *, | |||
| 137 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, | 136 | static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, |
| 138 | void __user *buffer, size_t *lenp, loff_t *ppos); | 137 | void __user *buffer, size_t *lenp, loff_t *ppos); |
| 139 | 138 | ||
| 139 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | ||
| 140 | void __user *buffer, size_t *lenp, loff_t *ppos); | ||
| 141 | |||
| 140 | static ctl_table root_table[]; | 142 | static ctl_table root_table[]; |
| 141 | static struct ctl_table_header root_table_header = | 143 | static struct ctl_table_header root_table_header = |
| 142 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; | 144 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; |
| @@ -543,10 +545,10 @@ static ctl_table kern_table[] = { | |||
| 543 | { | 545 | { |
| 544 | .ctl_name = KERN_CADPID, | 546 | .ctl_name = KERN_CADPID, |
| 545 | .procname = "cad_pid", | 547 | .procname = "cad_pid", |
| 546 | .data = &cad_pid, | 548 | .data = NULL, |
| 547 | .maxlen = sizeof (int), | 549 | .maxlen = sizeof (int), |
| 548 | .mode = 0600, | 550 | .mode = 0600, |
| 549 | .proc_handler = &proc_dointvec, | 551 | .proc_handler = &proc_do_cad_pid, |
| 550 | }, | 552 | }, |
| 551 | { | 553 | { |
| 552 | .ctl_name = KERN_MAX_THREADS, | 554 | .ctl_name = KERN_MAX_THREADS, |
| @@ -2427,6 +2429,28 @@ proc_minmax: | |||
| 2427 | } | 2429 | } |
| 2428 | #endif | 2430 | #endif |
| 2429 | 2431 | ||
| 2432 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | ||
| 2433 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
| 2434 | { | ||
| 2435 | struct pid *new_pid; | ||
| 2436 | pid_t tmp; | ||
| 2437 | int r; | ||
| 2438 | |||
| 2439 | tmp = pid_nr(cad_pid); | ||
| 2440 | |||
| 2441 | r = __do_proc_dointvec(&tmp, table, write, filp, buffer, | ||
| 2442 | lenp, ppos, NULL, NULL); | ||
| 2443 | if (r || !write) | ||
| 2444 | return r; | ||
| 2445 | |||
| 2446 | new_pid = find_get_pid(tmp); | ||
| 2447 | if (!new_pid) | ||
| 2448 | return -ESRCH; | ||
| 2449 | |||
| 2450 | put_pid(xchg(&cad_pid, new_pid)); | ||
| 2451 | return 0; | ||
| 2452 | } | ||
| 2453 | |||
| 2430 | #else /* CONFIG_PROC_FS */ | 2454 | #else /* CONFIG_PROC_FS */ |
| 2431 | 2455 | ||
| 2432 | int proc_dostring(ctl_table *table, int write, struct file *filp, | 2456 | int proc_dostring(ctl_table *table, int write, struct file *filp, |
