blob: 0962fd7154d197dd920ce42eb526c6979f713aa4 [file] [log] [blame]
From 4607af3f8237114c8c679e5d976ef00fe7053123 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 25 Jan 2019 16:47:16 +0100
Subject: [PATCH 14/15] tty: n_r3964: properly reference count pids
The driver likes to look up things based on the current pid, yet the
structure is never properly reference counted when passing around the
pointer. Luckily when it is saved off it is correct, but for all other
usages, we need to handle the reference properly.
The function find_client_current() is created to handle some of the
common housekeeping when trying to lookup a structure on the current
pid.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/n_r3964.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
--- a/drivers/tty/n_r3964.c
+++ b/drivers/tty/n_r3964.c
@@ -770,6 +770,18 @@ exit:
return pClient;
}
+/* Find a client that refers to the pid of the current task */
+static struct r3964_client_info *find_client_current(struct r3964_info *info)
+{
+ struct r3964_client_info *client;
+ struct pid *pid;
+
+ pid = get_pid(task_pid(current));
+ client = findClient(info, pid);
+ put_pid(pid);
+ return client;
+}
+
static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg)
{
struct r3964_client_info *pClient;
@@ -1121,7 +1133,7 @@ static ssize_t r3964_read(struct tty_str
return -ERESTARTSYS;
}
- pClient = findClient(pInfo, task_pid(current));
+ pClient = find_client_current(pInfo);
if (pClient) {
pMsg = remove_msg(pClient);
if (pMsg == NULL) {
@@ -1208,7 +1220,7 @@ static ssize_t r3964_write(struct tty_st
pHeader->length = count;
pHeader->owner = NULL;
- pClient = findClient(pInfo, task_pid(current));
+ pClient = find_client_current(pInfo);
if (pClient) {
pHeader->owner = pClient;
}
@@ -1232,6 +1244,7 @@ static int r3964_ioctl(struct tty_struct
unsigned int cmd, unsigned long arg)
{
struct r3964_info *pInfo = tty->disc_data;
+ struct pid *pid;
unsigned long flags;
int retval = 0;
@@ -1249,7 +1262,9 @@ static int r3964_ioctl(struct tty_struct
return -ERESTARTSYS;
}
- retval = enable_signals(pInfo, task_pid(current), arg);
+ pid = get_pid(task_pid(current));
+ retval = enable_signals(pInfo, pid, arg);
+ put_pid(pid);
mutex_unlock(&pInfo->read_lock);
break;
@@ -1269,8 +1284,9 @@ static int r3964_ioctl(struct tty_struct
spin_unlock_irqrestore(&pInfo->lock, flags);
break;
case R3964_READ_TELEGRAM:
- retval = read_telegram(pInfo, task_pid(current),
- (unsigned char __user *)arg);
+ pid = get_pid(task_pid(current));
+ retval = read_telegram(pInfo, pid, (unsigned char __user *)arg);
+ put_pid(pid);
break;
default:
retval = -ENOIOCTLCMD;
@@ -1311,7 +1327,7 @@ static __poll_t r3964_poll(struct tty_st
TRACE_L("POLL");
- pClient = findClient(pInfo, task_pid(current));
+ pClient = find_client_current(pInfo);
if (pClient) {
poll_wait(file, &tty->read_wait, wait);
spin_lock_irqsave(&pClient->lock, flags);