@@ -103,8 +103,8 @@ static void __proc_set_tty(struct tty_struct *tty)
103
103
put_pid (tty -> session );
104
104
put_pid (tty -> pgrp );
105
105
tty -> pgrp = get_pid (task_pgrp (current ));
106
- spin_unlock_irqrestore (& tty -> ctrl_lock , flags );
107
106
tty -> session = get_pid (task_session (current ));
107
+ spin_unlock_irqrestore (& tty -> ctrl_lock , flags );
108
108
if (current -> signal -> tty ) {
109
109
tty_debug (tty , "current tty %s not NULL!!\n" ,
110
110
current -> signal -> tty -> name );
@@ -293,20 +293,23 @@ void disassociate_ctty(int on_exit)
293
293
spin_lock_irq (& current -> sighand -> siglock );
294
294
put_pid (current -> signal -> tty_old_pgrp );
295
295
current -> signal -> tty_old_pgrp = NULL ;
296
-
297
296
tty = tty_kref_get (current -> signal -> tty );
297
+ spin_unlock_irq (& current -> sighand -> siglock );
298
+
298
299
if (tty ) {
299
300
unsigned long flags ;
301
+
302
+ tty_lock (tty );
300
303
spin_lock_irqsave (& tty -> ctrl_lock , flags );
301
304
put_pid (tty -> session );
302
305
put_pid (tty -> pgrp );
303
306
tty -> session = NULL ;
304
307
tty -> pgrp = NULL ;
305
308
spin_unlock_irqrestore (& tty -> ctrl_lock , flags );
309
+ tty_unlock (tty );
306
310
tty_kref_put (tty );
307
311
}
308
312
309
- spin_unlock_irq (& current -> sighand -> siglock );
310
313
/* Now clear signal->tty under the lock */
311
314
read_lock (& tasklist_lock );
312
315
session_clear_tty (task_session (current ));
@@ -477,14 +480,19 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
477
480
return - ENOTTY ;
478
481
if (retval )
479
482
return retval ;
480
- if (!current -> signal -> tty ||
481
- (current -> signal -> tty != real_tty ) ||
482
- (real_tty -> session != task_session (current )))
483
- return - ENOTTY ;
483
+
484
484
if (get_user (pgrp_nr , p ))
485
485
return - EFAULT ;
486
486
if (pgrp_nr < 0 )
487
487
return - EINVAL ;
488
+
489
+ spin_lock_irq (& real_tty -> ctrl_lock );
490
+ if (!current -> signal -> tty ||
491
+ (current -> signal -> tty != real_tty ) ||
492
+ (real_tty -> session != task_session (current ))) {
493
+ retval = - ENOTTY ;
494
+ goto out_unlock_ctrl ;
495
+ }
488
496
rcu_read_lock ();
489
497
pgrp = find_vpid (pgrp_nr );
490
498
retval = - ESRCH ;
@@ -494,12 +502,12 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
494
502
if (session_of_pgrp (pgrp ) != task_session (current ))
495
503
goto out_unlock ;
496
504
retval = 0 ;
497
- spin_lock_irq (& tty -> ctrl_lock );
498
505
put_pid (real_tty -> pgrp );
499
506
real_tty -> pgrp = get_pid (pgrp );
500
- spin_unlock_irq (& tty -> ctrl_lock );
501
507
out_unlock :
502
508
rcu_read_unlock ();
509
+ out_unlock_ctrl :
510
+ spin_unlock_irq (& real_tty -> ctrl_lock );
503
511
return retval ;
504
512
}
505
513
@@ -511,20 +519,30 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
511
519
*
512
520
* Obtain the session id of the tty. If there is no session
513
521
* return an error.
514
- *
515
- * Locking: none. Reference to current->signal->tty is safe.
516
522
*/
517
523
static int tiocgsid (struct tty_struct * tty , struct tty_struct * real_tty , pid_t __user * p )
518
524
{
525
+ unsigned long flags ;
526
+ pid_t sid ;
527
+
519
528
/*
520
529
* (tty == real_tty) is a cheap way of
521
530
* testing if the tty is NOT a master pty.
522
531
*/
523
532
if (tty == real_tty && current -> signal -> tty != real_tty )
524
533
return - ENOTTY ;
534
+
535
+ spin_lock_irqsave (& real_tty -> ctrl_lock , flags );
525
536
if (!real_tty -> session )
526
- return - ENOTTY ;
527
- return put_user (pid_vnr (real_tty -> session ), p );
537
+ goto err ;
538
+ sid = pid_vnr (real_tty -> session );
539
+ spin_unlock_irqrestore (& real_tty -> ctrl_lock , flags );
540
+
541
+ return put_user (sid , p );
542
+
543
+ err :
544
+ spin_unlock_irqrestore (& real_tty -> ctrl_lock , flags );
545
+ return - ENOTTY ;
528
546
}
529
547
530
548
/*
0 commit comments