Commit 9ec52099 authored by Cedric Le Goater's avatar Cedric Le Goater Committed by Linus Torvalds

[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: default avatarCedric 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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1a657f78
...@@ -123,7 +123,8 @@ static inline void power_button(void) ...@@ -123,7 +123,8 @@ static inline void power_button(void)
if (machine_state & MACHINE_PANICED) if (machine_state & MACHINE_PANICED)
return; return;
if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { if ((machine_state & MACHINE_SHUTTING_DOWN) ||
kill_cad_pid(SIGINT, 1)) {
/* No init process or button pressed twice. */ /* No init process or button pressed twice. */
sgi_machine_power_off(); sgi_machine_power_off();
} }
......
...@@ -120,7 +120,7 @@ static inline void ip32_power_button(void) ...@@ -120,7 +120,7 @@ static inline void ip32_power_button(void)
if (has_panicked) if (has_panicked)
return; return;
if (shuting_down || kill_proc(1, SIGINT, 1)) { if (shuting_down || kill_cad_pid(SIGINT, 1)) {
/* No init process or button pressed twice. */ /* No init process or button pressed twice. */
ip32_machine_power_off(); ip32_machine_power_off();
} }
......
...@@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg, ...@@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg,
*/ */
static int shutdown(void) static int shutdown(void)
{ {
int rc = kill_proc(1, SIGINT, 1); int rc = kill_cad_pid(SIGINT, 1);
if (rc) { if (rc) {
printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), " printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), "
......
...@@ -127,9 +127,8 @@ static void button_consume_callbacks (int bpcount) ...@@ -127,9 +127,8 @@ static void button_consume_callbacks (int bpcount)
static void button_sequence_finished (unsigned long parameters) static void button_sequence_finished (unsigned long parameters)
{ {
#ifdef CONFIG_NWBUTTON_REBOOT /* Reboot using button is enabled */ #ifdef CONFIG_NWBUTTON_REBOOT /* Reboot using button is enabled */
if (button_press_count == reboot_count) { if (button_press_count == reboot_count)
kill_proc (1, SIGINT, 1); /* Ask init to reboot us */ kill_cad_pid(SIGINT, 1); /* Ask init to reboot us */
}
#endif /* CONFIG_NWBUTTON_REBOOT */ #endif /* CONFIG_NWBUTTON_REBOOT */
button_consume_callbacks (button_press_count); button_consume_callbacks (button_press_count);
bcount = sprintf (button_output_buffer, "%d\n", button_press_count); bcount = sprintf (button_output_buffer, "%d\n", button_press_count);
......
...@@ -220,7 +220,7 @@ scdrv_dispatch_event(char *event, int len) ...@@ -220,7 +220,7 @@ scdrv_dispatch_event(char *event, int len)
" Sending SIGPWR to init...\n"); " Sending SIGPWR to init...\n");
/* give a SIGPWR signal to init proc */ /* give a SIGPWR signal to init proc */
kill_proc(1, SIGPWR, 0); kill_cad_pid(SIGPWR, 0);
} else { } else {
/* print to system log */ /* print to system log */
printk("%s|$(0x%x)%s\n", severity, esp_code, desc); printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
......
...@@ -84,8 +84,7 @@ ...@@ -84,8 +84,7 @@
static void deferred_poweroff(void *dummy) static void deferred_poweroff(void *dummy)
{ {
extern int cad_pid; /* from kernel/sys.c */ if (kill_cad_pid(SIGINT, 1)) {
if (kill_proc(cad_pid, SIGINT, 1)) {
/* just in case killing init process failed */ /* just in case killing init process failed */
machine_power_off(); machine_power_off();
} }
......
...@@ -208,7 +208,7 @@ s390_handle_mcck(void) ...@@ -208,7 +208,7 @@ s390_handle_mcck(void)
*/ */
__ctl_clear_bit(14, 24); /* Disable WARNING MCH */ __ctl_clear_bit(14, 24); /* Disable WARNING MCH */
if (xchg(&mchchk_wng_posted, 1) == 0) if (xchg(&mchchk_wng_posted, 1) == 0)
kill_proc(1, SIGPWR, 1); kill_cad_pid(SIGPWR, 1);
} }
#endif #endif
......
...@@ -1065,6 +1065,8 @@ static inline int is_init(struct task_struct *tsk) ...@@ -1065,6 +1065,8 @@ static inline int is_init(struct task_struct *tsk)
return tsk->pid == 1; return tsk->pid == 1;
} }
extern struct pid *cad_pid;
extern void free_task(struct task_struct *tsk); extern void free_task(struct task_struct *tsk);
#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
...@@ -1292,6 +1294,11 @@ extern int send_group_sigqueue(int, struct sigqueue *, struct task_struct *); ...@@ -1292,6 +1294,11 @@ extern int send_group_sigqueue(int, struct sigqueue *, struct task_struct *);
extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long); extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
static inline int kill_cad_pid(int sig, int priv)
{
return kill_pid(cad_pid, sig, priv);
}
/* These can be the second arg to send_sig_info/send_group_sig_info. */ /* These can be the second arg to send_sig_info/send_group_sig_info. */
#define SEND_SIG_NOINFO ((struct siginfo *) 0) #define SEND_SIG_NOINFO ((struct siginfo *) 0)
#define SEND_SIG_PRIV ((struct siginfo *) 1) #define SEND_SIG_PRIV ((struct siginfo *) 1)
......
...@@ -721,6 +721,8 @@ static int init(void * unused) ...@@ -721,6 +721,8 @@ static int init(void * unused)
*/ */
child_reaper = current; child_reaper = current;
cad_pid = task_pid(current);
smp_prepare_cpus(max_cpus); smp_prepare_cpus(max_cpus);
do_pre_smp_initcalls(); do_pre_smp_initcalls();
......
...@@ -92,7 +92,8 @@ EXPORT_SYMBOL(fs_overflowgid); ...@@ -92,7 +92,8 @@ EXPORT_SYMBOL(fs_overflowgid);
*/ */
int C_A_D = 1; int C_A_D = 1;
int cad_pid = 1; struct pid *cad_pid;
EXPORT_SYMBOL(cad_pid);
/* /*
* Notifier list for kernel code which wants to be called * Notifier list for kernel code which wants to be called
...@@ -773,10 +774,9 @@ void ctrl_alt_del(void) ...@@ -773,10 +774,9 @@ void ctrl_alt_del(void)
if (C_A_D) if (C_A_D)
schedule_work(&cad_work); schedule_work(&cad_work);
else else
kill_proc(cad_pid, SIGINT, 1); kill_cad_pid(SIGINT, 1);
} }
/* /*
* Unprivileged users may change the real gid to the effective gid * Unprivileged users may change the real gid to the effective gid
* or vice versa. (BSD-style) * or vice versa. (BSD-style)
......
...@@ -68,7 +68,6 @@ extern int sysrq_enabled; ...@@ -68,7 +68,6 @@ extern int sysrq_enabled;
extern int core_uses_pid; extern int core_uses_pid;
extern int suid_dumpable; extern int suid_dumpable;
extern char core_pattern[]; extern char core_pattern[];
extern int cad_pid;
extern int pid_max; extern int pid_max;
extern int min_free_kbytes; extern int min_free_kbytes;
extern int printk_ratelimit_jiffies; extern int printk_ratelimit_jiffies;
...@@ -137,6 +136,9 @@ static int parse_table(int __user *, int, void __user *, size_t __user *, ...@@ -137,6 +136,9 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos); void __user *buffer, size_t *lenp, loff_t *ppos);
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
static ctl_table root_table[]; static ctl_table root_table[];
static struct ctl_table_header root_table_header = static struct ctl_table_header root_table_header =
{ root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
...@@ -543,10 +545,10 @@ static ctl_table kern_table[] = { ...@@ -543,10 +545,10 @@ static ctl_table kern_table[] = {
{ {
.ctl_name = KERN_CADPID, .ctl_name = KERN_CADPID,
.procname = "cad_pid", .procname = "cad_pid",
.data = &cad_pid, .data = NULL,
.maxlen = sizeof (int), .maxlen = sizeof (int),
.mode = 0600, .mode = 0600,
.proc_handler = &proc_dointvec, .proc_handler = &proc_do_cad_pid,
}, },
{ {
.ctl_name = KERN_MAX_THREADS, .ctl_name = KERN_MAX_THREADS,
...@@ -2427,6 +2429,28 @@ static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp, ...@@ -2427,6 +2429,28 @@ static int proc_do_ipc_string(ctl_table *table, int write, struct file *filp,
} }
#endif #endif
static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
struct pid *new_pid;
pid_t tmp;
int r;
tmp = pid_nr(cad_pid);
r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
lenp, ppos, NULL, NULL);
if (r || !write)
return r;
new_pid = find_get_pid(tmp);
if (!new_pid)
return -ESRCH;
put_pid(xchg(&cad_pid, new_pid));
return 0;
}
#else /* CONFIG_PROC_FS */ #else /* CONFIG_PROC_FS */
int proc_dostring(ctl_table *table, int write, struct file *filp, int proc_dostring(ctl_table *table, int write, struct file *filp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment