blob: 9842a56d052f1eaaf51edcd39ff1dbee71035f92 [file] [log] [blame]
From 7105eeab4aa73032fe40f5e72f51601da0cd7c4f Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: Fri, 25 Jan 2019 16:35:57 +0100
Subject: [PATCH 13/15] tty: n_r3964: properly protect sig_flags of client
structure
This cleans up the remaining users of the sig_flags field in the client
structure to allways access it under the client structure's lock.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/n_r3964.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
--- a/drivers/tty/n_r3964.c
+++ b/drivers/tty/n_r3964.c
@@ -193,7 +193,6 @@ static void transmit_block(struct r3964_
static void receive_char(struct r3964_info *pInfo, const unsigned char c);
static void receive_error(struct r3964_info *pInfo, const char flag);
static void on_timeout(struct timer_list *t);
-static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg);
static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
int error_code, struct rx_block_header *pBlock);
static struct r3964_message *remove_msg(struct r3964_client_info *client);
@@ -548,7 +547,14 @@ static void on_receive_block(struct r396
/* notify attached client processes: */
spin_lock_irqsave(&pInfo->lock, flags);
list_for_each_entry(pClient, &pInfo->clients, node) {
- if (pClient->sig_flags & R3964_SIG_DATA) {
+ unsigned long client_flags;
+ unsigned int sig_flags;
+
+ spin_lock_irqsave(&pClient->lock, client_flags);
+ sig_flags = pClient->sig_flags;
+ spin_unlock_irqrestore(&pClient->lock, client_flags);
+
+ if (sig_flags & R3964_SIG_DATA) {
add_msg(pClient, R3964_MSG_DATA, length, R3964_OK,
pBlock);
}
@@ -799,8 +805,12 @@ static int enable_signals(struct r3964_i
} else {
pClient = findClient(pInfo, pid);
if (pClient) {
+ unsigned long client_flags;
+
/* update signal options */
+ spin_lock_irqsave(&pClient->lock, client_flags);
pClient->sig_flags = arg;
+ spin_unlock_irqrestore(&pClient->lock, client_flags);
} else {
/* add client to client list */
pClient = kmalloc(sizeof(struct r3964_client_info),
@@ -915,6 +925,7 @@ static void add_msg(struct r3964_client_
{
struct r3964_message *pMsg;
unsigned long flags;
+ unsigned int sig_flags;
spin_lock_irqsave(&pClient->lock, flags);
@@ -935,12 +946,13 @@ static void add_msg(struct r3964_client_
TRACE_PE("add_msg - queue OVERFLOW-msg");
}
}
+
+ sig_flags = pClient->sig_flags;
spin_unlock_irqrestore(&pClient->lock, flags);
/* Send SIGIO signal to client process: */
- if (pClient->sig_flags & R3964_USE_SIGIO) {
+ if (sig_flags & R3964_USE_SIGIO)
kill_pid(pClient->pid, SIGIO, 1);
- }
}
static struct r3964_message *remove_msg(struct r3964_client_info *client)