summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@google.com>2020-12-11 15:09:14 +0100
committerGreg Kroah-Hartman <gregkh@google.com>2020-12-11 15:09:14 +0100
commit7bc2af6ac8a8b78895d78207aab9560564e56058 (patch)
treecd5872affccfd91f5cfa1ba7861cd8f672835074 /drivers/tty
parent4cb652f2d058eacdfb720e53de0dceaf19ae4587 (diff)
parentf299fb634f3b99d7462b2321c3ccf6773812a44e (diff)
Merge 4.4.248 into android-4.4-p
Changes in 4.4.248 net/af_iucv: set correct sk_protocol for child sockets rose: Fix Null pointer dereference in rose_send_frame() usbnet: ipheth: fix connectivity with iOS 14 bonding: wait for sysfs kobject destruction before freeing struct slave netfilter: bridge: reset skb->pkt_type after NF_INET_POST_ROUTING traversal net/x25: prevent a couple of overflows cxgb3: fix error return code in t3_sge_alloc_qset() net: pasemi: fix error return code in pasemi_mac_open() dt-bindings: net: correct interrupt flags in examples Input: xpad - support Ardwiino Controllers Input: i8042 - add ByteSpeed touchpad to noloop table powerpc: Stop exporting __clear_user which is now inlined. btrfs: sysfs: init devices outside of the chunk_mutex vlan: consolidate VLAN parsing code and limit max parsing depth usb: gadget: f_fs: Use local copy of descriptors for userspace copy USB: serial: kl5kusb105: fix memleak on open USB: serial: ch341: add new Product ID for CH341A USB: serial: ch341: sort device-id entries USB: serial: option: add Fibocom NL668 variants USB: serial: option: add support for Thales Cinterion EXS82 tty: Fix ->pgrp locking in tiocspgrp() ALSA: hda/realtek - Add new codec supported for ALC897 ALSA: hda/generic: Add option to enforce preferred_dacs pairs tty: Fix ->session locking cifs: fix potential use-after-free in cifs_echo_request() i2c: imx: Fix reset of I2SR_IAL flag i2c: imx: Check for I2SR_IAL after every byte arm64: assembler: make adr_l work in modules under KASLR iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs spi: Introduce device-managed SPI controller allocation spi: bcm2835: Fix use-after-free on unbind spi: bcm2835: Release the DMA channel if probe fails after dma_init tracing: Fix userstacktrace option for instances btrfs: cleanup cow block on error mm/userfaultfd: do not access vma->vm_mm after calling handle_userfault() gfs2: check for empty rgrp tree in gfs2_ri_update Input: i8042 - fix error return code in i8042_setup_aux() x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes Linux 4.4.248 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ibe14a8d4e51b79235bf3afec20d773a593625c53
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/tty_io.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index b7effcfee91d..dff507cd0250 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -537,8 +537,8 @@ static void __proc_set_tty(struct tty_struct *tty)
put_pid(tty->session);
put_pid(tty->pgrp);
tty->pgrp = get_pid(task_pgrp(current));
- spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty->session = get_pid(task_session(current));
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (current->signal->tty) {
tty_debug(tty, "current tty %s not NULL!!\n",
current->signal->tty->name);
@@ -929,21 +929,24 @@ void disassociate_ctty(int on_exit)
spin_lock_irq(&current->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
-
tty = tty_kref_get(current->signal->tty);
+ spin_unlock_irq(&current->sighand->siglock);
+
if (tty) {
unsigned long flags;
+
+ tty_lock(tty);
spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ tty_unlock(tty);
tty_kref_put(tty);
} else
tty_debug_hangup(tty, "no current tty\n");
- spin_unlock_irq(&current->sighand->siglock);
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));
@@ -2601,14 +2604,19 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
return -ENOTTY;
if (retval)
return retval;
- if (!current->signal->tty ||
- (current->signal->tty != real_tty) ||
- (real_tty->session != task_session(current)))
- return -ENOTTY;
+
if (get_user(pgrp_nr, p))
return -EFAULT;
if (pgrp_nr < 0)
return -EINVAL;
+
+ spin_lock_irq(&real_tty->ctrl_lock);
+ if (!current->signal->tty ||
+ (current->signal->tty != real_tty) ||
+ (real_tty->session != task_session(current))) {
+ retval = -ENOTTY;
+ goto out_unlock_ctrl;
+ }
rcu_read_lock();
pgrp = find_vpid(pgrp_nr);
retval = -ESRCH;
@@ -2618,12 +2626,12 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
- spin_lock_irq(&tty->ctrl_lock);
put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
- spin_unlock_irq(&tty->ctrl_lock);
out_unlock:
rcu_read_unlock();
+out_unlock_ctrl:
+ spin_unlock_irq(&real_tty->ctrl_lock);
return retval;
}
@@ -2635,21 +2643,31 @@ out_unlock:
*
* Obtain the session id of the tty. If there is no session
* return an error.
- *
- * Locking: none. Reference to current->signal->tty is safe.
*/
static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ unsigned long flags;
+ pid_t sid;
+
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
+
+ spin_lock_irqsave(&real_tty->ctrl_lock, flags);
if (!real_tty->session)
- return -ENOTTY;
- return put_user(pid_vnr(real_tty->session), p);
+ goto err;
+ sid = pid_vnr(real_tty->session);
+ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
+
+ return put_user(sid, p);
+
+err:
+ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
+ return -ENOTTY;
}
/**
@@ -3061,10 +3079,14 @@ void __do_SAK(struct tty_struct *tty)
struct task_struct *g, *p;
struct pid *session;
int i;
+ unsigned long flags;
if (!tty)
return;
- session = tty->session;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ session = get_pid(tty->session);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty_ldisc_flush(tty);
@@ -3100,6 +3122,7 @@ void __do_SAK(struct tty_struct *tty)
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
+ put_pid(session);
#endif
}