aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCedric Le Goater <clg@fr.ibm.com>2006-10-02 05:19:00 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:25 -0400
commit9ec52099e4b8678a60e9f93e41ad87885d64f3e6 (patch)
treea68fe051b39f8f8e8be469cbd3c2f653b9b71a9d
parent1a657f78dcc8ea7c53eaa1f2a45ea2315738c15f (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>
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c3
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c2
-rw-r--r--arch/powerpc/platforms/iseries/mf.c2
-rw-r--r--drivers/char/nwbutton.c5
-rw-r--r--drivers/char/snsc_event.c2
-rw-r--r--drivers/parisc/power.c3
-rw-r--r--drivers/s390/s390mach.c2
-rw-r--r--include/linux/sched.h7
-rw-r--r--init/main.c2
-rw-r--r--kernel/sys.c6
-rw-r--r--kernel/sysctl.c30
11 files changed, 48 insertions, 16 deletions
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 8134220ed600..7a941ecff3bb 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -123,7 +123,8 @@ static inline void power_button(void)
123 if (machine_state & MACHINE_PANICED) 123 if (machine_state & MACHINE_PANICED)
124 return; 124 return;
125 125
126 if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { 126 if ((machine_state & MACHINE_SHUTTING_DOWN) ||
127 kill_cad_pid(SIGINT, 1)) {
127 /* No init process or button pressed twice. */ 128 /* No init process or button pressed twice. */
128 sgi_machine_power_off(); 129 sgi_machine_power_off();
129 } 130 }
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 79ddb4605659..fd0932b2d521 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -120,7 +120,7 @@ static inline void ip32_power_button(void)
120 if (has_panicked) 120 if (has_panicked)
121 return; 121 return;
122 122
123 if (shuting_down || kill_proc(1, SIGINT, 1)) { 123 if (shuting_down || kill_cad_pid(SIGINT, 1)) {
124 /* No init process or button pressed twice. */ 124 /* No init process or button pressed twice. */
125 ip32_machine_power_off(); 125 ip32_machine_power_off();
126 } 126 }
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 1a2c2a50f922..1983b640bac1 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg,
357 */ 357 */
358static int shutdown(void) 358static int shutdown(void)
359{ 359{
360 int rc = kill_proc(1, SIGINT, 1); 360 int rc = kill_cad_pid(SIGINT, 1);
361 361
362 if (rc) { 362 if (rc) {
363 printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), " 363 printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 7c57ebfa8640..ea1aa7764f8e 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -127,9 +127,8 @@ static void button_consume_callbacks (int bpcount)
127static void button_sequence_finished (unsigned long parameters) 127static void button_sequence_finished (unsigned long parameters)
128{ 128{
129#ifdef CONFIG_NWBUTTON_REBOOT /* Reboot using button is enabled */ 129#ifdef CONFIG_NWBUTTON_REBOOT /* Reboot using button is enabled */
130 if (button_press_count == reboot_count) { 130 if (button_press_count == reboot_count)
131 kill_proc (1, SIGINT, 1); /* Ask init to reboot us */ 131 kill_cad_pid(SIGINT, 1); /* Ask init to reboot us */
132 }
133#endif /* CONFIG_NWBUTTON_REBOOT */ 132#endif /* CONFIG_NWBUTTON_REBOOT */
134 button_consume_callbacks (button_press_count); 133 button_consume_callbacks (button_press_count);
135 bcount = sprintf (button_output_buffer, "%d\n", button_press_count); 134 bcount = sprintf (button_output_buffer, "%d\n", button_press_count);
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index d12d4f629cec..864854c58866 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -220,7 +220,7 @@ scdrv_dispatch_event(char *event, int len)
220 " Sending SIGPWR to init...\n"); 220 " Sending SIGPWR to init...\n");
221 221
222 /* give a SIGPWR signal to init proc */ 222 /* give a SIGPWR signal to init proc */
223 kill_proc(1, SIGPWR, 0); 223 kill_cad_pid(SIGPWR, 0);
224 } else { 224 } else {
225 /* print to system log */ 225 /* print to system log */
226 printk("%s|$(0x%x)%s\n", severity, esp_code, desc); 226 printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
diff --git a/drivers/parisc/power.c b/drivers/parisc/power.c
index fad5a33bf0fa..4a9f025a6b58 100644
--- a/drivers/parisc/power.c
+++ b/drivers/parisc/power.c
@@ -84,8 +84,7 @@
84 84
85static void deferred_poweroff(void *dummy) 85static void deferred_poweroff(void *dummy)
86{ 86{
87 extern int cad_pid; /* from kernel/sys.c */ 87 if (kill_cad_pid(SIGINT, 1)) {
88 if (kill_proc(cad_pid, SIGINT, 1)) {
89 /* just in case killing init process failed */ 88 /* just in case killing init process failed */
90 machine_power_off(); 89 machine_power_off();
91 } 90 }
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 479364d0332a..e088b5e28711 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -208,7 +208,7 @@ s390_handle_mcck(void)
208 */ 208 */
209 __ctl_clear_bit(14, 24); /* Disable WARNING MCH */ 209 __ctl_clear_bit(14, 24); /* Disable WARNING MCH */
210 if (xchg(&mchchk_wng_posted, 1) == 0) 210 if (xchg(&mchchk_wng_posted, 1) == 0)
211 kill_proc(1, SIGPWR, 1); 211 kill_cad_pid(SIGPWR, 1);
212 } 212 }
213#endif 213#endif
214 214
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9ba959e34266..38530232d92f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1065,6 +1065,8 @@ static inline int is_init(struct task_struct *tsk)
1065 return tsk->pid == 1; 1065 return tsk->pid == 1;
1066} 1066}
1067 1067
1068extern struct pid *cad_pid;
1069
1068extern void free_task(struct task_struct *tsk); 1070extern void free_task(struct task_struct *tsk);
1069#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) 1071#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
1070 1072
@@ -1292,6 +1294,11 @@ extern int send_group_sigqueue(int, struct sigqueue *, struct task_struct *);
1292extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); 1294extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
1293extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long); 1295extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
1294 1296
1297static inline int kill_cad_pid(int sig, int priv)
1298{
1299 return kill_pid(cad_pid, sig, priv);
1300}
1301
1295/* These can be the second arg to send_sig_info/send_group_sig_info. */ 1302/* These can be the second arg to send_sig_info/send_group_sig_info. */
1296#define SEND_SIG_NOINFO ((struct siginfo *) 0) 1303#define SEND_SIG_NOINFO ((struct siginfo *) 0)
1297#define SEND_SIG_PRIV ((struct siginfo *) 1) 1304#define SEND_SIG_PRIV ((struct siginfo *) 1)
diff --git a/init/main.c b/init/main.c
index a49b00235bda..ee123243fb53 100644
--- a/init/main.c
+++ b/init/main.c
@@ -721,6 +721,8 @@ static int init(void * unused)
721 */ 721 */
722 child_reaper = current; 722 child_reaper = current;
723 723
724 cad_pid = task_pid(current);
725
724 smp_prepare_cpus(max_cpus); 726 smp_prepare_cpus(max_cpus);
725 727
726 do_pre_smp_initcalls(); 728 do_pre_smp_initcalls();
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
94int C_A_D = 1; 94int C_A_D = 1;
95int cad_pid = 1; 95struct pid *cad_pid;
96EXPORT_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;
68extern int core_uses_pid; 68extern int core_uses_pid;
69extern int suid_dumpable; 69extern int suid_dumpable;
70extern char core_pattern[]; 70extern char core_pattern[];
71extern int cad_pid;
72extern int pid_max; 71extern int pid_max;
73extern int min_free_kbytes; 72extern int min_free_kbytes;
74extern int printk_ratelimit_jiffies; 73extern int printk_ratelimit_jiffies;
@@ -137,6 +136,9 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
137static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, 136static 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
139static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
140 void __user *buffer, size_t *lenp, loff_t *ppos);
141
140static ctl_table root_table[]; 142static ctl_table root_table[];
141static struct ctl_table_header root_table_header = 143static 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
2432static 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
2432int proc_dostring(ctl_table *table, int write, struct file *filp, 2456int proc_dostring(ctl_table *table, int write, struct file *filp,