Skip to content

Commit 4a51096

Browse files
peterhurleygregkh
authored andcommitted
tty: Make tty_files_lock per-tty
Access to tty->tty_files list is always per-tty, never for all ttys simultaneously. Replace global tty_files_lock spinlock with per-tty ->files_lock. Initialize when the ->tty_files list is inited, in alloc_tty_struct(). Signed-off-by: Peter Hurley <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 527ffc1 commit 4a51096

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

drivers/tty/tty_io.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,6 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
138138
/* Mutex to protect creating and releasing a tty */
139139
DEFINE_MUTEX(tty_mutex);
140140

141-
/* Spinlock to protect the tty->tty_files list */
142-
DEFINE_SPINLOCK(tty_files_lock);
143-
144141
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
145142
static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
146143
ssize_t redirected_tty_write(struct file *, const char __user *,
@@ -202,9 +199,9 @@ void tty_add_file(struct tty_struct *tty, struct file *file)
202199
priv->tty = tty;
203200
priv->file = file;
204201

205-
spin_lock(&tty_files_lock);
202+
spin_lock(&tty->files_lock);
206203
list_add(&priv->list, &tty->tty_files);
207-
spin_unlock(&tty_files_lock);
204+
spin_unlock(&tty->files_lock);
208205
}
209206

210207
/**
@@ -225,10 +222,11 @@ void tty_free_file(struct file *file)
225222
static void tty_del_file(struct file *file)
226223
{
227224
struct tty_file_private *priv = file->private_data;
225+
struct tty_struct *tty = priv->tty;
228226

229-
spin_lock(&tty_files_lock);
227+
spin_lock(&tty->files_lock);
230228
list_del(&priv->list);
231-
spin_unlock(&tty_files_lock);
229+
spin_unlock(&tty->files_lock);
232230
tty_free_file(file);
233231
}
234232

@@ -286,11 +284,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine)
286284
struct list_head *p;
287285
int count = 0;
288286

289-
spin_lock(&tty_files_lock);
287+
spin_lock(&tty->files_lock);
290288
list_for_each(p, &tty->tty_files) {
291289
count++;
292290
}
293-
spin_unlock(&tty_files_lock);
291+
spin_unlock(&tty->files_lock);
294292
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
295293
tty->driver->subtype == PTY_TYPE_SLAVE &&
296294
tty->link && tty->link->count)
@@ -713,7 +711,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
713711
workqueue with the lock held */
714712
check_tty_count(tty, "tty_hangup");
715713

716-
spin_lock(&tty_files_lock);
714+
spin_lock(&tty->files_lock);
717715
/* This breaks for file handles being sent over AF_UNIX sockets ? */
718716
list_for_each_entry(priv, &tty->tty_files, list) {
719717
filp = priv->file;
@@ -725,7 +723,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
725723
__tty_fasync(-1, filp, 0); /* can't block */
726724
filp->f_op = &hung_up_tty_fops;
727725
}
728-
spin_unlock(&tty_files_lock);
726+
spin_unlock(&tty->files_lock);
729727

730728
refs = tty_signal_session_leader(tty, exit_session);
731729
/* Account for the p->signal references we killed */
@@ -1637,9 +1635,9 @@ static void release_one_tty(struct work_struct *work)
16371635
tty_driver_kref_put(driver);
16381636
module_put(owner);
16391637

1640-
spin_lock(&tty_files_lock);
1638+
spin_lock(&tty->files_lock);
16411639
list_del_init(&tty->tty_files);
1642-
spin_unlock(&tty_files_lock);
1640+
spin_unlock(&tty->files_lock);
16431641

16441642
put_pid(tty->pgrp);
16451643
put_pid(tty->session);
@@ -3176,6 +3174,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
31763174
mutex_init(&tty->atomic_write_lock);
31773175
spin_lock_init(&tty->ctrl_lock);
31783176
spin_lock_init(&tty->flow_lock);
3177+
spin_lock_init(&tty->files_lock);
31793178
INIT_LIST_HEAD(&tty->tty_files);
31803179
INIT_WORK(&tty->SAK_work, do_SAK_work);
31813180

include/linux/tty.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ struct tty_struct {
302302
struct work_struct hangup_work;
303303
void *disc_data;
304304
void *driver_data;
305+
spinlock_t files_lock; /* protects tty_files list */
305306
struct list_head tty_files;
306307

307308
#define N_TTY_BUF_SIZE 4096
@@ -508,7 +509,6 @@ extern int tty_standard_install(struct tty_driver *driver,
508509
struct tty_struct *tty);
509510

510511
extern struct mutex tty_mutex;
511-
extern spinlock_t tty_files_lock;
512512

513513
#define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock))
514514

security/selinux/hooks.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,7 +2415,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
24152415

24162416
tty = get_current_tty();
24172417
if (tty) {
2418-
spin_lock(&tty_files_lock);
2418+
spin_lock(&tty->files_lock);
24192419
if (!list_empty(&tty->tty_files)) {
24202420
struct tty_file_private *file_priv;
24212421

@@ -2430,7 +2430,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
24302430
if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
24312431
drop_tty = 1;
24322432
}
2433-
spin_unlock(&tty_files_lock);
2433+
spin_unlock(&tty->files_lock);
24342434
tty_kref_put(tty);
24352435
}
24362436
/* Reset controlling tty. */

0 commit comments

Comments
 (0)