Commit 81af8d67 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds

[PATCH] vt: rework the console spawning variables

This is such a rare path it took me a while to figure out how to test
this after soring out the locking.

This patch does several things.
- The variables used are moved into a structure and declared in vt_kern.h
- A spinlock is added so we don't have SMP races updating the values.
- Instead of raw pid_t value a struct_pid is used to guard against
  pid wrap around issues, if the daemon to spawn a new console dies.
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5feb8f5f
...@@ -108,7 +108,11 @@ const int NR_TYPES = ARRAY_SIZE(max_vals); ...@@ -108,7 +108,11 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
struct kbd_struct kbd_table[MAX_NR_CONSOLES]; struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct kbd_struct *kbd = kbd_table; static struct kbd_struct *kbd = kbd_table;
int spawnpid, spawnsig; struct vt_spawn_console vt_spawn_con = {
.lock = SPIN_LOCK_UNLOCKED,
.pid = NULL,
.sig = 0,
};
/* /*
* Variables exported for vt.c * Variables exported for vt.c
...@@ -578,9 +582,13 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs) ...@@ -578,9 +582,13 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs) static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
{ {
if (spawnpid) spin_lock(&vt_spawn_con.lock);
if (kill_proc(spawnpid, spawnsig, 1)) if (vt_spawn_con.pid)
spawnpid = 0; if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
put_pid(vt_spawn_con.pid);
vt_spawn_con.pid = NULL;
}
spin_unlock(&vt_spawn_con.lock);
} }
static void fn_SAK(struct vc_data *vc, struct pt_regs *regs) static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
......
...@@ -645,13 +645,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -645,13 +645,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/ */
case KDSIGACCEPT: case KDSIGACCEPT:
{ {
extern int spawnpid, spawnsig;
if (!perm || !capable(CAP_KILL)) if (!perm || !capable(CAP_KILL))
return -EPERM; return -EPERM;
if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
return -EINVAL; return -EINVAL;
spawnpid = current->pid;
spawnsig = arg; spin_lock_irq(&vt_spawn_con.lock);
put_pid(vt_spawn_con.pid);
vt_spawn_con.pid = get_pid(task_pid(current));
vt_spawn_con.sig = arg;
spin_unlock_irq(&vt_spawn_con.lock);
return 0; return 0;
} }
......
...@@ -84,4 +84,11 @@ void reset_vc(struct vc_data *vc); ...@@ -84,4 +84,11 @@ void reset_vc(struct vc_data *vc);
extern char con_buf[CON_BUF_SIZE]; extern char con_buf[CON_BUF_SIZE];
extern struct semaphore con_buf_sem; extern struct semaphore con_buf_sem;
struct vt_spawn_console {
spinlock_t lock;
struct pid *pid;
int sig;
};
extern struct vt_spawn_console vt_spawn_con;
#endif /* _VT_KERN_H */ #endif /* _VT_KERN_H */
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