| 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); |