linux/drivers/char
Paul Mackerras f786648b89 [PATCH] Remove race between con_open and con_close
[ Same race and same patch also by Steven Rostedt <rostedt@goodmis.org> ]

I have a laptop (G3 powerbook) which will pretty reliably hit a race
between con_open and con_close late in the boot process and oops in
vt_ioctl due to tty->driver_data being NULL.

What happens is this: process A opens /dev/tty6; it comes into
con_open() (drivers/char/vt.c) and assign a non-NULL value to
tty->driver_data.  Then process A closes that and concurrently process
B opens /dev/tty6.  Process A gets through con_close() and clears
tty->driver_data, since tty->count == 1.  However, before process A
can decrement tty->count, we switch to process B (e.g. at the
down(&tty_sem) call at drivers/char/tty_io.c line 1626).

So process B gets to run and comes into con_open with tty->count == 2,
as tty->count is incremented (in init_dev) before con_open is called.
Because tty->count != 1, we don't set tty->driver_data.  Then when the
process tries to do anything with that fd, it oopses.

The simple and effective fix for this is to test tty->driver_data
rather than tty->count in con_open.  The testing and setting of
tty->driver_data is serialized with respect to the clearing of
tty->driver_data in con_close by the console_sem.  We can't get a
situation where con_open sees tty->driver_data != NULL and then
con_close on a different fd clears tty->driver_data, because
tty->count is incremented before con_open is called.  Thus this patch
eliminates the race, and in fact with this patch my laptop doesn't
oops.

Signed-off-by: Paul Mackerras <paulus@samba.org>
[ Same patch
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  in http://marc.theaimsgroup.com/?l=linux-kernel&m=112450820432121&w=2 ]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-08-27 18:03:42 -07:00
..
agp [PATCH] agp: restore APBASE after setting APSIZE 2005-07-29 15:01:15 -07:00
drm [PATCH] drm: via: fix sparse warnings 2005-07-27 16:25:54 -07:00
ftape [PATCH] printk: drivers/char/ftape/compressor/zftape-compress.c 2005-06-25 16:25:02 -07:00
ip2 [PATCH] drivers/char/ip2*: cleanups 2005-06-25 16:25:06 -07:00
ipmi [PATCH] clean up inline static vs static inline 2005-07-27 16:26:20 -07:00
mwave [PATCH] drivers/char/mwave/tp3780i.c: remove dead code 2005-06-25 16:25:05 -07:00
pcmcia [PATCH] pcmcia: remove references to pcmcia/version.h 2005-07-07 18:24:07 -07:00
rio [PATCH] turn many #if $undefined_string into #ifdef $undefined_string 2005-07-27 16:26:08 -07:00
tpm [PATCH] tpm_infineon: Support for new TPM 1.2 and PNPACPI 2005-08-05 12:22:37 -07:00
watchdog [PATCH] i8xx_tco.c: arm watchdog only when started 2005-08-09 12:08:21 -07:00
ChangeLog Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
Kconfig [PATCH] Kconfig fix (sparc32 drivers/char dependencies) 2005-08-23 18:43:43 -07:00
Makefile [PATCH] hvc_console: Separate hvc_console and vio code 2 2005-07-07 18:23:39 -07:00
amiserial.c [PATCH] Serial: remove unnecessary register_serial/unregister_serial 2005-06-25 16:24:25 -07:00
applicom.c [PATCH] printk: drivers/char/applicom.c 2005-06-25 16:25:01 -07:00
applicom.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cd1865.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
consolemap.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cp437.uni Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cyclades.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
decserial.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
defkeymap.c_shipped Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
defkeymap.map Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
digi.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
digi1.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
digiFep1.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
digiPCI.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ds1286.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ds1302.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ds1620.c [PATCH] char/ds1620: use msleep() instead of schedule_timeout() 2005-06-25 16:24:57 -07:00
dsp56k.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
dtlk.c [PATCH] misc verify_area cleanups 2005-05-01 08:59:08 -07:00
ec3104_keyb.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
efirtc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
epca.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
epca.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
epcaconfig.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
esp.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
generic_nvram.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
generic_serial.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
genrtc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hangcheck-timer.c [PATCH] In hangcheck-timer.c call emergency_restart() 2005-07-26 14:35:44 -07:00
hpet.c [PATCH] hpet: do_div fix 2005-06-25 16:24:40 -07:00
hvc_console.c [PATCH] hvc_console: Register ops when setting up hvc_console 2005-07-07 18:23:39 -07:00
hvc_vio.c [PATCH] hvc_console: Separate the NUL character filtering from get_hvc_chars 2005-07-07 18:23:40 -07:00
hvcs.c [PATCH] Driver Core: drivers/base - drivers/i2c/chips/adm1026.c: update device attribute callbacks 2005-06-20 15:15:32 -07:00
hvsi.c [PATCH] hvc_console: Use hvc_get_chars in hvsi code 2005-07-07 18:23:40 -07:00
hw_random.c [PATCH] PCI: clean up dynamic pci id logic 2005-07-01 13:35:50 -07:00
i8k.c [PATCH] I8K: add new BIOS signatures 2005-06-25 16:24:25 -07:00
ip2.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ip2main.c [PATCH] drivers/char/ip2*: cleanups 2005-06-25 16:25:06 -07:00
ip27-rtc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
isicom.c [PATCH] drivers/char/isicom.c: section fixes 2005-06-25 16:25:00 -07:00
istallion.c [PATCH] drivers/char/istallion.c: remove an unneeded variable 2005-06-25 16:25:03 -07:00
ite_gpio.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
keyboard.c Input: check keycodesize when adjusting keymaps 2005-07-24 00:50:03 -05:00
lcd.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
lcd.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
lp.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
mbcs.c [PATCH] Driver Core: drivers/base - drivers/i2c/chips/adm1026.c: update device attribute callbacks 2005-06-20 15:15:32 -07:00
mbcs.h [PATCH] mbcs trivial user annotations 2005-05-04 07:33:13 -07:00
mem.c Fix up mmap of /dev/kmem 2005-08-13 14:22:59 -07:00
misc.c [PATCH] ppc32: Remove CONFIG_PMAC_PBOOK 2005-06-27 15:11:43 -07:00
mmtimer.c [PATCH] mmtimer build fix 2005-04-16 15:23:53 -07:00
moxa.c [PATCH] pci: remove deprecates 2005-06-27 21:52:38 -07:00
mxser.c [PATCH] moxa: do not ignore input 2005-06-06 14:42:23 -07:00
mxser.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
n_hdlc.c [PATCH] Convert users to tty_unregister_ldisc() 2005-06-23 09:45:36 -07:00
n_r3964.c [PATCH] Convert users to tty_unregister_ldisc() 2005-06-23 09:45:36 -07:00
n_tty.c [PATCH] tty output lossage fix 2005-07-07 18:23:45 -07:00
nvram.c [PATCH] drivers/char/nvram.c: possible cleanups 2005-06-25 16:25:03 -07:00
nwbutton.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
nwbutton.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
nwflash.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ppdev.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
pty.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
qtronix.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
qtronixmap.c_shipped Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
qtronixmap.map Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
random.c [PATCH] mostly_read data section 2005-07-07 18:23:46 -07:00
raw.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
riscom8.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
riscom8.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
riscom8_reg.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
rocket.c [PATCH] rocket.c: Fix ldisc ref count handling 2005-07-15 09:54:51 -07:00
rocket.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
rocket_int.h [PATCH] drivers/char/rocket.c: cleanups 2005-06-25 16:25:04 -07:00
rtc.c [PATCH] rtc: msleep() cannot be used from interrupt 2005-08-05 06:57:44 -07:00
s3c2410-rtc.c [PATCH] ARM: RTC: allow driver methods to return error 2005-04-30 12:19:28 +01:00
scan_keyb.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
scan_keyb.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
scc.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
scx200_gpio.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
selection.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ser_a2232.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ser_a2232.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ser_a2232fw.ax Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ser_a2232fw.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
serial167.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
snsc.c [PATCH] Fix typo in scdrv_init() 2005-06-20 15:15:27 -07:00
snsc.h [IA64] Altix system controller event handling 2005-04-25 13:28:52 -07:00
snsc_event.c [IA64-SGI] snsc_event.c new file 2005-04-25 13:29:46 -07:00
sonypi.c Input: make name, phys and uniq be 'const char *' because once 2005-06-30 00:50:38 -05:00
specialix.c [PATCH] misc verify_area cleanups 2005-05-01 08:59:08 -07:00
specialix_io8.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
stallion.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
sx.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sx.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sxboards.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sxwindow.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
synclink.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
synclinkmp.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sysrq.c [PATCH] Update sysrq-B to use emergency_restart() 2005-07-26 14:35:43 -07:00
tb0219.c [PATCH] TB0219: add PCI IRQ initialization 2005-07-12 16:01:02 -07:00
tipar.c [PATCH] drivers/char/tipar.c: off by one array access 2005-06-28 21:20:29 -07:00
toshiba.c [PATCH] Toshiba driver cleanup 2005-06-25 16:24:24 -07:00
tty_io.c [PATCH] char/tty_io: replace schedule_timeout() with msleep_interruptible() 2005-06-25 16:24:58 -07:00
tty_ioctl.c [PATCH] coverity: tty_ldisc_ref return null check 2005-06-28 21:20:34 -07:00
vc_screen.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
viocons.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
viotape.c [PATCH] class: convert drivers/char/* to use the new class api instead of class_simple 2005-06-20 15:15:08 -07:00
vme_scc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
vr41xx_giu.c [PATCH] mips: add vr41xx gpio support 2005-06-21 18:46:32 -07:00
vr41xx_rtc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
vt.c [PATCH] Remove race between con_open and con_close 2005-08-27 18:03:42 -07:00
vt_ioctl.c [PATCH] Adapt drivers/char/vt_ioctl.c to non-x86 2005-06-28 21:20:30 -07:00