lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250219192426.164654-3-surajpatil522@gmail.com>
Date: Wed, 19 Feb 2025 19:24:26 +0000
From: Suraj Patil <surajpatil522@...il.com>
To: linux-kernel@...r.kernel.org
Cc: gregkh@...uxfoundation.org,
	jirislaby@...nel.org,
	Suraj Patil <surajpatil522@...il.com>
Subject: [PATCH] tty: ipwireless: Fix locking in ioctl and write_room functions

- Add mutex locks around tty->ipw_tty_mutex in ioctl, tiocmget, and write_room.
- Resolve FIXME comments related to locking ambiguity.

Signed-off-by: Suraj Patil <surajpatil522@...il.com>
---
 drivers/tty/ipwireless/tty.c | 178 ++++++++++++++++++++---------------
 1 file changed, 100 insertions(+), 78 deletions(-)

diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c
index b6de40815fb9..c4befc3d09f9 100644
--- a/drivers/tty/ipwireless/tty.c
+++ b/drivers/tty/ipwireless/tty.c
@@ -229,21 +229,21 @@ static ssize_t ipw_write(struct tty_struct *linux_tty, const u8 *buf,
 
 static unsigned int ipw_write_room(struct tty_struct *linux_tty)
 {
-	struct ipw_tty *tty = linux_tty->driver_data;
-	int room;
+    struct ipw_tty *tty = linux_tty->driver_data;
+    int room = 0;
 
-	/* FIXME: Exactly how is the tty object locked here .. */
-	if (!tty)
-		return 0;
+    if (!tty)
+        return 0;
 
-	if (!tty->port.count)
-		return 0;
-
-	room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
-	if (room < 0)
-		room = 0;
+    mutex_lock(&tty->ipw_tty_mutex); // Lock added
+    if (!tty->port.count) {
+        mutex_unlock(&tty->ipw_tty_mutex);
+        return 0;
+    }
 
-	return room;
+    room = IPWIRELESS_TX_QUEUE_SIZE - tty->tx_bytes_queued;
+    mutex_unlock(&tty->ipw_tty_mutex); // Unlock added
+    return room < 0 ? 0 : room;
 }
 
 static int ipwireless_get_serial_info(struct tty_struct *linux_tty,
@@ -351,85 +351,107 @@ static int set_control_lines(struct ipw_tty *tty, unsigned int set,
 
 static int ipw_tiocmget(struct tty_struct *linux_tty)
 {
-	struct ipw_tty *tty = linux_tty->driver_data;
-	/* FIXME: Exactly how is the tty object locked here .. */
+    struct ipw_tty *tty = linux_tty->driver_data;
+    int ret;
 
-	if (!tty)
-		return -ENODEV;
+    if (!tty)
+        return -ENODEV;
 
-	if (!tty->port.count)
-		return -EINVAL;
+    mutex_lock(&tty->ipw_tty_mutex); // Lock added
+    if (!tty->port.count) {
+        mutex_unlock(&tty->ipw_tty_mutex);
+        return -EINVAL;
+    }
 
-	return get_control_lines(tty);
+    ret = get_control_lines(tty);
+    mutex_unlock(&tty->ipw_tty_mutex); // Unlock added
+    return ret;
 }
 
-static int
-ipw_tiocmset(struct tty_struct *linux_tty,
-	     unsigned int set, unsigned int clear)
+static int ipw_tiocmset(struct tty_struct *linux_tty,
+             unsigned int set, unsigned int clear)
 {
-	struct ipw_tty *tty = linux_tty->driver_data;
-	/* FIXME: Exactly how is the tty object locked here .. */
+    struct ipw_tty *tty = linux_tty->driver_data;
+    int ret;
 
-	if (!tty)
-		return -ENODEV;
+    if (!tty)
+        return -ENODEV;
 
-	if (!tty->port.count)
-		return -EINVAL;
+    mutex_lock(&tty->ipw_tty_mutex); // Lock added
+    if (!tty->port.count) {
+        mutex_unlock(&tty->ipw_tty_mutex);
+        return -EINVAL;
+    }
 
-	return set_control_lines(tty, set, clear);
+    ret = set_control_lines(tty, set, clear);
+    mutex_unlock(&tty->ipw_tty_mutex); // Unlock added
+    return ret;
 }
 
 static int ipw_ioctl(struct tty_struct *linux_tty,
-		     unsigned int cmd, unsigned long arg)
+                     unsigned int cmd, unsigned long arg)
 {
-	struct ipw_tty *tty = linux_tty->driver_data;
-
-	if (!tty)
-		return -ENODEV;
-
-	if (!tty->port.count)
-		return -EINVAL;
-
-	/* FIXME: Exactly how is the tty object locked here .. */
-	if (tty->tty_type == TTYTYPE_MODEM) {
-		switch (cmd) {
-		case PPPIOCGCHAN:
-			{
-				int chan = ipwireless_ppp_channel_index(
-							tty->network);
-
-				if (chan < 0)
-					return -ENODEV;
-				if (put_user(chan, (int __user *) arg))
-					return -EFAULT;
-			}
-			return 0;
-
-		case PPPIOCGUNIT:
-			{
-				int unit = ipwireless_ppp_unit_number(
-						tty->network);
-
-				if (unit < 0)
-					return -ENODEV;
-				if (put_user(unit, (int __user *) arg))
-					return -EFAULT;
-			}
-			return 0;
-
-		case FIONREAD:
-			{
-				int val = 0;
-
-				if (put_user(val, (int __user *) arg))
-					return -EFAULT;
-			}
-			return 0;
-		case TCFLSH:
-			return tty_perform_flush(linux_tty, arg);
-		}
-	}
-	return -ENOIOCTLCMD;
+        struct ipw_tty *tty = linux_tty->driver_data;
+        int ret = -ENOIOCTLCMD; // Default return value
+
+        if (!tty)
+                return -ENODEV;
+
+        if (!tty->port.count)
+                return -EINVAL;
+
+        // Acquire the mutex to lock the tty object
+        mutex_lock(&tty->ipw_tty_mutex);
+
+        if (tty->tty_type == TTYTYPE_MODEM) {
+                switch (cmd) {
+                case PPPIOCGCHAN: {
+                        int chan = ipwireless_ppp_channel_index(tty->network);
+
+                        if (chan < 0) {
+                                ret = -ENODEV;
+                                break;
+                        }
+                        if (put_user(chan, (int __user *) arg)) {
+                                ret = -EFAULT;
+                                break;
+                        }
+                        ret = 0;
+                        break;
+                }
+                case PPPIOCGUNIT: {
+                        int unit = ipwireless_ppp_unit_number(tty->network);
+
+                        if (unit < 0) {
+                                ret = -ENODEV;
+                                break;
+                        }
+                        if (put_user(unit, (int __user *) arg)) {
+                                ret = -EFAULT;
+                                break;
+                        }
+                        ret = 0;
+                        break;
+                }
+                case FIONREAD: {
+                        int val = 0;
+
+                        if (put_user(val, (int __user *) arg)) {
+                                ret = -EFAULT;
+                                break;
+                        }
+                        ret = 0;
+                        break;
+                }
+                case TCFLSH:
+                        ret = tty_perform_flush(linux_tty, arg);
+                        break;
+                }
+        }
+
+        // Release the mutex before returning
+        mutex_unlock(&tty->ipw_tty_mutex);
+        return ret;
 }
 
 static int add_tty(int j,
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ