View | Details | Raw Unified | Return to bug 65372
Collapse All | Expand All

(-)linux-2.6.5.old/drivers/char/tty_io.c (-24 / +34 lines)
Lines 122-127 Link Here
122
LIST_HEAD(tty_drivers);			/* linked list of tty drivers */
122
LIST_HEAD(tty_drivers);			/* linked list of tty drivers */
123
struct tty_ldisc ldiscs[NR_LDISCS];	/* line disc dispatch table	*/
123
struct tty_ldisc ldiscs[NR_LDISCS];	/* line disc dispatch table	*/
124
124
125
/* Semaphore to protect creating and releasing a tty */
126
DECLARE_MUTEX(tty_sem);
127
125
#ifdef CONFIG_UNIX98_PTYS
128
#ifdef CONFIG_UNIX98_PTYS
126
extern struct tty_driver *ptm_driver;	/* Unix98 pty masters; for /dev/ptmx */
129
extern struct tty_driver *ptm_driver;	/* Unix98 pty masters; for /dev/ptmx */
127
extern int pty_limit;		/* Config limit on Unix98 ptys */
130
extern int pty_limit;		/* Config limit on Unix98 ptys */
Lines 567-575 Link Here
567
570
568
	lock_kernel();
571
	lock_kernel();
569
572
573
	down(&tty_sem);
570
	tty = current->signal->tty;
574
	tty = current->signal->tty;
571
	if (tty) {
575
	if (tty) {
572
		tty_pgrp = tty->pgrp;
576
		tty_pgrp = tty->pgrp;
577
		up(&tty_sem);
573
		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
578
		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
574
			tty_vhangup(tty);
579
			tty_vhangup(tty);
575
	} else {
580
	} else {
Lines 577-582 Link Here
577
			kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
582
			kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
578
			kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
583
			kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
579
		}
584
		}
585
		up(&tty_sem);
580
		unlock_kernel();	
586
		unlock_kernel();	
581
		return;
587
		return;
582
	}
588
	}
Lines 586-599 Link Here
586
			kill_pg(tty_pgrp, SIGCONT, on_exit);
592
			kill_pg(tty_pgrp, SIGCONT, on_exit);
587
	}
593
	}
588
594
595
	/* Must lock changes to tty_old_pgrp */
596
	down(&tty_sem);
589
	current->signal->tty_old_pgrp = 0;
597
	current->signal->tty_old_pgrp = 0;
590
	tty->session = 0;
598
	tty->session = 0;
591
	tty->pgrp = -1;
599
	tty->pgrp = -1;
592
600
601
	/* Now clear signal->tty under the lock */
593
	read_lock(&tasklist_lock);
602
	read_lock(&tasklist_lock);
594
	for_each_task_pid(current->signal->session, PIDTYPE_SID, p, l, pid)
603
	for_each_task_pid(current->signal->session, PIDTYPE_SID, p, l, pid)
595
		p->signal->tty = NULL;
604
		p->signal->tty = NULL;
596
	read_unlock(&tasklist_lock);
605
	read_unlock(&tasklist_lock);
606
	up(&tty_sem);
597
	unlock_kernel();
607
	unlock_kernel();
598
}
608
}
599
609
Lines 758-776 Link Here
758
	return tty_write(file, buf, count, ppos);
768
	return tty_write(file, buf, count, ppos);
759
}
769
}
760
770
761
/* Semaphore to protect creating and releasing a tty */
762
static DECLARE_MUTEX(tty_sem);
763
764
static void down_tty_sem(int index)
765
{
766
	down(&tty_sem);
767
}
768
769
static void up_tty_sem(int index)
770
{
771
	up(&tty_sem);
772
}
773
774
static void release_mem(struct tty_struct *tty, int idx);
771
static void release_mem(struct tty_struct *tty, int idx);
775
772
776
static char ptychar[] = "pqrstuvwxyzabcde";
773
static char ptychar[] = "pqrstuvwxyzabcde";
Lines 803-814 Link Here
803
	struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
800
	struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
804
	int retval=0;
801
	int retval=0;
805
802
806
	/* 
807
	 * Check whether we need to acquire the tty semaphore to avoid
808
	 * race conditions.  For now, play it safe.
809
	 */
810
	down_tty_sem(idx);
811
812
	/* check whether we're reopening an existing tty */
803
	/* check whether we're reopening an existing tty */
813
	if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
804
	if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
814
		tty = devpts_get_tty(idx);
805
		tty = devpts_get_tty(idx);
Lines 989-997 Link Here
989
success:
980
success:
990
	*ret_tty = tty;
981
	*ret_tty = tty;
991
	
982
	
992
	/* All paths come through here to release the semaphore */
993
end_init:
983
end_init:
994
	up_tty_sem(idx);
995
	return retval;
984
	return retval;
996
985
997
	/* Release locally allocated memory ... nothing placed in slots */
986
	/* Release locally allocated memory ... nothing placed in slots */
Lines 1184-1192 Link Here
1184
	 * each iteration we avoid any problems.
1173
	 * each iteration we avoid any problems.
1185
	 */
1174
	 */
1186
	while (1) {
1175
	while (1) {
1176
		/* Guard against races with tty->count changes elsewhere and
1177
		   opens on /dev/tty */
1178
		   
1179
		down(&tty_sem);
1187
		tty_closing = tty->count <= 1;
1180
		tty_closing = tty->count <= 1;
1188
		o_tty_closing = o_tty &&
1181
		o_tty_closing = o_tty &&
1189
			(o_tty->count <= (pty_master ? 1 : 0));
1182
			(o_tty->count <= (pty_master ? 1 : 0));
1183
		up(&tty_sem);
1190
		do_sleep = 0;
1184
		do_sleep = 0;
1191
1185
1192
		if (tty_closing) {
1186
		if (tty_closing) {
Lines 1222-1227 Link Here
1222
	 * both sides, and we've completed the last operation that could 
1216
	 * both sides, and we've completed the last operation that could 
1223
	 * block, so it's safe to proceed with closing.
1217
	 * block, so it's safe to proceed with closing.
1224
	 */
1218
	 */
1219
	 
1220
	down(&tty_sem);
1225
	if (pty_master) {
1221
	if (pty_master) {
1226
		if (--o_tty->count < 0) {
1222
		if (--o_tty->count < 0) {
1227
			printk(KERN_WARNING "release_dev: bad pty slave count "
1223
			printk(KERN_WARNING "release_dev: bad pty slave count "
Lines 1235-1241 Link Here
1235
		       tty->count, tty_name(tty, buf));
1231
		       tty->count, tty_name(tty, buf));
1236
		tty->count = 0;
1232
		tty->count = 0;
1237
	}
1233
	}
1238
1234
	up(&tty_sem);
1235
	
1239
	/*
1236
	/*
1240
	 * We've decremented tty->count, so we need to remove this file
1237
	 * We've decremented tty->count, so we need to remove this file
1241
	 * descriptor off the tty->tty_files list; this serves two
1238
	 * descriptor off the tty->tty_files list; this serves two
Lines 1343-1353 Link Here
1343
	int index;
1340
	int index;
1344
	dev_t device = inode->i_rdev;
1341
	dev_t device = inode->i_rdev;
1345
	unsigned short saved_flags = filp->f_flags;
1342
	unsigned short saved_flags = filp->f_flags;
1343
1346
retry_open:
1344
retry_open:
1347
	noctty = filp->f_flags & O_NOCTTY;
1345
	noctty = filp->f_flags & O_NOCTTY;
1346
1347
	down(&tty_sem);
1348
1348
	if (device == MKDEV(TTYAUX_MAJOR,0)) {
1349
	if (device == MKDEV(TTYAUX_MAJOR,0)) {
1349
		if (!current->signal->tty)
1350
		if (!current->signal->tty) {
1351
			up(&tty_sem);
1350
			return -ENXIO;
1352
			return -ENXIO;
1353
		}
1351
		driver = current->signal->tty->driver;
1354
		driver = current->signal->tty->driver;
1352
		index = current->signal->tty->index;
1355
		index = current->signal->tty->index;
1353
		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1356
		filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
Lines 1377-1382 Link Here
1377
			noctty = 1;
1380
			noctty = 1;
1378
			goto got_driver;
1381
			goto got_driver;
1379
		}
1382
		}
1383
		up(&tty_sem);
1380
		return -ENODEV;
1384
		return -ENODEV;
1381
	}
1385
	}
1382
1386
Lines 1402-1423 Link Here
1402
				goto ptmx_found; /* ok! */
1406
				goto ptmx_found; /* ok! */
1403
			}
1407
			}
1404
		}
1408
		}
1409
		up(&tty_sem);
1405
		return -EIO; /* no free ptys */
1410
		return -EIO; /* no free ptys */
1406
	ptmx_found:
1411
	ptmx_found:
1407
		set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
1412
		set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
1408
		if (devpts_pty_new(tty->link)) {
1413
		if (devpts_pty_new(tty->link)) {
1409
			/* BADNESS - need to destroy both ptm and pts! */
1414
			/* BADNESS - need to destroy both ptm and pts! */
1415
			up(&tty_sem);
1410
			return -ENOMEM;
1416
			return -ENOMEM;
1411
		}
1417
		}
1412
		noctty = 1;
1418
		noctty = 1;
1419
		up(&tty_sem);
1413
	} else
1420
	} else
1414
#endif
1421
#endif
1415
	{
1422
	{
1416
		driver = get_tty_driver(device, &index);
1423
		driver = get_tty_driver(device, &index);
1417
		if (!driver)
1424
		if (!driver) {
1425
			up(&tty_sem);
1418
			return -ENODEV;
1426
			return -ENODEV;
1427
		}
1419
got_driver:
1428
got_driver:
1420
		retval = init_dev(driver, index, &tty);
1429
		retval = init_dev(driver, index, &tty);
1430
		up(&tty_sem);
1421
		if (retval)
1431
		if (retval)
1422
			return retval;
1432
			return retval;
1423
	}
1433
	}
(-)linux-2.6.5.old/drivers/char/vt.c (+7 lines)
Lines 2489-2494 Link Here
2489
2489
2490
static void con_close(struct tty_struct *tty, struct file *filp)
2490
static void con_close(struct tty_struct *tty, struct file *filp)
2491
{
2491
{
2492
	down(&tty_sem);
2492
	acquire_console_sem();
2493
	acquire_console_sem();
2493
	if (tty && tty->count == 1) {
2494
	if (tty && tty->count == 1) {
2494
		struct vt_struct *vt;
2495
		struct vt_struct *vt;
Lines 2499-2507 Link Here
2499
		tty->driver_data = 0;
2500
		tty->driver_data = 0;
2500
		release_console_sem();
2501
		release_console_sem();
2501
		vcs_remove_devfs(tty);
2502
		vcs_remove_devfs(tty);
2503
		up(&tty_sem);
2504
		/*
2505
		 * tty_sem is released, but we still hold BKL, so there is
2506
		 * still exclusion against init_dev()
2507
		 */
2502
		return;
2508
		return;
2503
	}
2509
	}
2504
	release_console_sem();
2510
	release_console_sem();
2511
	up(&tty_sem);
2505
}
2512
}
2506
2513
2507
static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols, int do_clear)
2514
static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols, int do_clear)
(-)linux-2.6.5.old/include/linux/tty.h (+3 lines)
Lines 364-369 Link Here
364
extern int tty_get_baud_rate(struct tty_struct *tty);
364
extern int tty_get_baud_rate(struct tty_struct *tty);
365
extern int tty_termios_baud_rate(struct termios *termios);
365
extern int tty_termios_baud_rate(struct termios *termios);
366
366
367
struct semaphore;
368
extern struct semaphore tty_sem;
369
367
/* n_tty.c */
370
/* n_tty.c */
368
extern struct tty_ldisc tty_ldisc_N_TTY;
371
extern struct tty_ldisc tty_ldisc_N_TTY;
369
372
(-)linux-2.6.5.old/kernel/exit.c (+2 lines)
Lines 359-365 Link Here
359
	exit_mm(current);
359
	exit_mm(current);
360
360
361
	set_special_pids(1, 1);
361
	set_special_pids(1, 1);
362
	down(&tty_sem);
362
	current->signal->tty = NULL;
363
	current->signal->tty = NULL;
364
	up(&tty_sem);
363
365
364
	/* Block and flush all signals */
366
	/* Block and flush all signals */
365
	sigfillset(&blocked);
367
	sigfillset(&blocked);
(-)linux-2.6.5.old/kernel/sys.c (+3 lines)
Lines 23-28 Link Here
23
#include <linux/security.h>
23
#include <linux/security.h>
24
#include <linux/dcookies.h>
24
#include <linux/dcookies.h>
25
#include <linux/suspend.h>
25
#include <linux/suspend.h>
26
#include <linux/tty.h>
26
#include <linux/ckrm.h>
27
#include <linux/ckrm.h>
27
#include <linux/audit.h>
28
#include <linux/audit.h>
28
29
Lines 1142-1147 Link Here
1142
	if (!thread_group_leader(current))
1143
	if (!thread_group_leader(current))
1143
		return audit_result(-EINVAL);
1144
		return audit_result(-EINVAL);
1144
1145
1146
	down(&tty_sem);
1145
	write_lock_irq(&tasklist_lock);
1147
	write_lock_irq(&tasklist_lock);
1146
1148
1147
	pid = find_pid(PIDTYPE_PGID, current->pid);
1149
	pid = find_pid(PIDTYPE_PGID, current->pid);
Lines 1155-1160 Link Here
1155
	err = process_group(current);
1157
	err = process_group(current);
1156
out:
1158
out:
1157
	write_unlock_irq(&tasklist_lock);
1159
	write_unlock_irq(&tasklist_lock);
1160
	up(&tty_sem);
1158
	return audit_result(err);
1161
	return audit_result(err);
1159
}
1162
}
1160
1163

Return to bug 65372