Skip to content

Commit 6a1c068

Browse files
peterhurleygregkh
authored andcommitted
tty: Convert termios_mutex to termios_rwsem
termios is commonly accessed unsafely (especially by N_TTY) because the existing mutex forces exclusive access. Convert existing usage. Signed-off-by: Peter Hurley <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a2f73be commit 6a1c068

File tree

8 files changed

+70
-69
lines changed

8 files changed

+70
-69
lines changed

drivers/net/irda/irtty-sir.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed)
123123

124124
tty = priv->tty;
125125

126-
mutex_lock(&tty->termios_mutex);
126+
down_write(&tty->termios_rwsem);
127127
old_termios = tty->termios;
128128
cflag = tty->termios.c_cflag;
129129
tty_encode_baud_rate(tty, speed, speed);
130130
if (tty->ops->set_termios)
131131
tty->ops->set_termios(tty, &old_termios);
132132
priv->io.speed = speed;
133-
mutex_unlock(&tty->termios_mutex);
133+
up_write(&tty->termios_rwsem);
134134

135135
return 0;
136136
}
@@ -280,7 +280,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
280280
struct ktermios old_termios;
281281
int cflag;
282282

283-
mutex_lock(&tty->termios_mutex);
283+
down_write(&tty->termios_rwsem);
284284
old_termios = tty->termios;
285285
cflag = tty->termios.c_cflag;
286286

@@ -292,7 +292,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
292292
tty->termios.c_cflag = cflag;
293293
if (tty->ops->set_termios)
294294
tty->ops->set_termios(tty, &old_termios);
295-
mutex_unlock(&tty->termios_mutex);
295+
up_write(&tty->termios_rwsem);
296296
}
297297

298298
/*****************************************************************/

drivers/tty/n_tty.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1539,7 +1539,7 @@ int is_ignored(int sig)
15391539
* guaranteed that this function will not be re-entered or in progress
15401540
* when the ldisc is closed.
15411541
*
1542-
* Locking: Caller holds tty->termios_mutex
1542+
* Locking: Caller holds tty->termios_rwsem
15431543
*/
15441544

15451545
static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)

drivers/tty/pty.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ static int pty_resize(struct tty_struct *tty, struct winsize *ws)
287287
struct tty_struct *pty = tty->link;
288288

289289
/* For a PTY we need to lock the tty side */
290-
mutex_lock(&tty->termios_mutex);
290+
down_write(&tty->termios_rwsem);
291291
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
292292
goto done;
293293

@@ -314,7 +314,7 @@ static int pty_resize(struct tty_struct *tty, struct winsize *ws)
314314
tty->winsize = *ws;
315315
pty->winsize = *ws; /* Never used so will go away soon */
316316
done:
317-
mutex_unlock(&tty->termios_mutex);
317+
up_write(&tty->termios_rwsem);
318318
return 0;
319319
}
320320

drivers/tty/tty_io.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ static int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
604604
* redirect lock for undoing redirection
605605
* file list lock for manipulating list of ttys
606606
* tty_ldiscs_lock from called functions
607-
* termios_mutex resetting termios data
607+
* termios_rwsem resetting termios data
608608
* tasklist_lock to walk task list for hangup event
609609
* ->siglock to protect ->signal/->sighand
610610
*/
@@ -2230,17 +2230,17 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
22302230
*
22312231
* Copies the kernel idea of the window size into the user buffer.
22322232
*
2233-
* Locking: tty->termios_mutex is taken to ensure the winsize data
2233+
* Locking: tty->termios_rwsem is taken to ensure the winsize data
22342234
* is consistent.
22352235
*/
22362236

22372237
static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
22382238
{
22392239
int err;
22402240

2241-
mutex_lock(&tty->termios_mutex);
2241+
down_read(&tty->termios_rwsem);
22422242
err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
2243-
mutex_unlock(&tty->termios_mutex);
2243+
up_read(&tty->termios_rwsem);
22442244

22452245
return err ? -EFAULT: 0;
22462246
}
@@ -2261,7 +2261,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
22612261
unsigned long flags;
22622262

22632263
/* Lock the tty */
2264-
mutex_lock(&tty->termios_mutex);
2264+
down_write(&tty->termios_rwsem);
22652265
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
22662266
goto done;
22672267
/* Get the PID values and reference them so we can
@@ -2276,7 +2276,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
22762276

22772277
tty->winsize = *ws;
22782278
done:
2279-
mutex_unlock(&tty->termios_mutex);
2279+
up_write(&tty->termios_rwsem);
22802280
return 0;
22812281
}
22822282
EXPORT_SYMBOL(tty_do_resize);
@@ -3015,7 +3015,7 @@ void initialize_tty_struct(struct tty_struct *tty,
30153015
tty->session = NULL;
30163016
tty->pgrp = NULL;
30173017
mutex_init(&tty->legacy_mutex);
3018-
mutex_init(&tty->termios_mutex);
3018+
init_rwsem(&tty->termios_rwsem);
30193019
init_ldsem(&tty->ldisc_sem);
30203020
init_waitqueue_head(&tty->write_wait);
30213021
init_waitqueue_head(&tty->read_wait);

0 commit comments

Comments
 (0)