[PATCH] vt: fix potential race in VT_WAITACTIVE handler
On a multiprocessor machine the VT_WAITACTIVE ioctl call may return 0 if fg_console has already been updated in redraw_screen() but the console switch itself hasn't been completed. Fix this by checking fg_console in vt_waitactive() with the console sem held. Signed-off-by: Michal Januszewski <spock@gentoo.org> Acked-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
1d64b9cb1d
commit
f991519c19
@@ -1039,10 +1039,22 @@ int vt_waitactive(int vt)
|
|||||||
|
|
||||||
add_wait_queue(&vt_activate_queue, &wait);
|
add_wait_queue(&vt_activate_queue, &wait);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
set_current_state(TASK_INTERRUPTIBLE);
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
if (vt == fg_console)
|
|
||||||
|
/*
|
||||||
|
* Synchronize with redraw_screen(). By acquiring the console
|
||||||
|
* semaphore we make sure that the console switch is completed
|
||||||
|
* before we return. If we didn't wait for the semaphore, we
|
||||||
|
* could return at a point where fg_console has already been
|
||||||
|
* updated, but the console switch hasn't been completed.
|
||||||
|
*/
|
||||||
|
acquire_console_sem();
|
||||||
|
set_current_state(TASK_INTERRUPTIBLE);
|
||||||
|
if (vt == fg_console) {
|
||||||
|
release_console_sem();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
release_console_sem();
|
||||||
retval = -EINTR;
|
retval = -EINTR;
|
||||||
if (signal_pending(current))
|
if (signal_pending(current))
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user