mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-19 02:54:00 +08:00
[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: Eric W. Biederman <ebiederm@xmission.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
5feb8f5f84
commit
81af8d67d4
@ -108,7 +108,11 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
|
||||
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
|
||||
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
|
||||
@ -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)
|
||||
{
|
||||
if (spawnpid)
|
||||
if (kill_proc(spawnpid, spawnsig, 1))
|
||||
spawnpid = 0;
|
||||
spin_lock(&vt_spawn_con.lock);
|
||||
if (vt_spawn_con.pid)
|
||||
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)
|
||||
|
@ -645,13 +645,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
|
||||
*/
|
||||
case KDSIGACCEPT:
|
||||
{
|
||||
extern int spawnpid, spawnsig;
|
||||
if (!perm || !capable(CAP_KILL))
|
||||
return -EPERM;
|
||||
if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -84,4 +84,11 @@ void reset_vc(struct vc_data *vc);
|
||||
extern char con_buf[CON_BUF_SIZE];
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user