linux/drivers/char
Peter Huewe 39a088528e tpm: Propagate error from tpm_transmit to fix a timeout hang
commit abce9ac292 upstream.

tpm_write calls tpm_transmit without checking the return value and
assigns the return value unconditionally to chip->pending_data, even if
it's an error value.
This causes three bugs.

So if we write to /dev/tpm0 with a tpm_param_size bigger than
TPM_BUFSIZE=0x1000 (e.g. 0x100a)
and a bufsize also bigger than TPM_BUFSIZE (e.g. 0x100a)
tpm_transmit returns -E2BIG which is assigned to chip->pending_data as
-7, but tpm_write returns that TPM_BUFSIZE bytes have been successfully
been written to the TPM, altough this is not true (bug #1).

As we did write more than than TPM_BUFSIZE bytes but tpm_write reports
that only TPM_BUFSIZE bytes have been written the vfs tries to write
the remaining bytes (in this case 10 bytes) to the tpm device driver via
tpm_write which then blocks at

 /* cannot perform a write until the read has cleared
 either via tpm_read or a user_read_timer timeout */
 while (atomic_read(&chip->data_pending) != 0)
	 msleep(TPM_TIMEOUT);

for 60 seconds, since data_pending is -7 and nobody is able to
read it (since tpm_read luckily checks if data_pending is greater than
0) (#bug 2).

After that the remaining bytes are written to the TPM which are
interpreted by the tpm as a normal command. (bug #3)
So if the last bytes of the command stream happen to be a e.g.
tpm_force_clear this gets accidentally sent to the TPM.

This patch fixes all three bugs, by propagating the error code of
tpm_write and returning -E2BIG if the input buffer is too big,
since the response from the tpm for a truncated value is bogus anyway.
Moreover it returns -EBUSY to userspace if there is a response ready to be
read.

Signed-off-by: Peter Huewe <peter.huewe@infineon.com>
Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-21 09:17:12 -07:00
..
agp char/agp: add another Ironlake host bridge 2012-06-17 11:23:10 -07:00
hw_random Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2011-05-20 17:24:14 -07:00
ipmi ipmi: convert to seq_file interface 2011-05-26 17:12:37 -07:00
mwave Fix common misspellings 2011-03-31 11:26:23 -03:00
pcmcia pcmcia: Convert pcmcia_device_id declarations to const 2011-05-06 07:46:22 +02:00
tpm tpm: Propagate error from tpm_transmit to fix a timeout hang 2012-10-21 09:17:12 -07:00
xilinx_hwicap drivercore: revert addition of of_match to struct device 2011-05-18 12:32:23 -06:00
apm-emulation.c apm-emulation: apm_mutex breaks ACK; remove it 2011-05-23 12:50:43 +02:00
applicom.c drivers/char/applicom.c: fix information leak to userland 2010-10-27 18:03:14 -07:00
applicom.h
bfin-otp.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
briq_panel.c BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
bsr.c powerpc/pseries/bsr: Remove redundant initialization of bsr dev_t declaration. 2011-05-04 16:02:40 +10:00
ds1302.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
ds1620.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
dsp56k.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
dtlk.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
efirtc.c
generic_nvram.c drivers: autoconvert trivial BKL users to private mutex 2010-10-05 15:01:04 +02:00
genrtc.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
hangcheck-timer.c Input: sysrq - drop tty argument form handle_sysrq() 2010-08-21 00:34:45 -07:00
hpet.c drivers/char/hpet.c: fix periodic-emulation for delayed interrupts 2011-06-15 20:04:02 -07:00
i8k.c i8k: Integrate with the hwmon subsystem 2011-05-25 20:43:33 +02:00
Kconfig Allow setting of number of raw devices as a module parameter 2011-05-06 17:52:31 -07:00
lp.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
Makefile drivers/char: add MSM smd_pkt driver 2011-03-23 19:46:38 -07:00
mbcs.c drivers: autoconvert trivial BKL users to private mutex 2010-10-05 15:01:04 +02:00
mbcs.h Fix common misspellings 2011-03-31 11:26:23 -03:00
mem.c kmsg: properly support writev to avoid interleaved printk lines fix 2011-04-19 17:00:48 -07:00
misc.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
mmtimer.c posix-timers: Cleanup namespace 2011-02-02 15:28:19 +01:00
msm_smd_pkt.c drivers/char: add MSM smd_pkt driver 2011-03-23 19:46:38 -07:00
mspec.c Redefine ATOMIC_INIT and ATOMIC64_INIT to drop the casts 2012-08-15 12:04:09 -07:00
nsc_gpio.c
nvram.c drivers: autoconvert trivial BKL users to private mutex 2010-10-05 15:01:04 +02:00
nwbutton.c Fix common misspellings 2011-03-31 11:26:23 -03:00
nwbutton.h
nwflash.c drivers: autoconvert trivial BKL users to private mutex 2010-10-05 15:01:04 +02:00
pc8736x_gpio.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
ppdev.c drivers/char/ppdev.c: put gotten port value 2011-05-26 17:12:37 -07:00
ps3flash.c drop unused dentry argument to ->fsync 2010-05-27 22:05:02 -04:00
ramoops.c ramoops: fix types, remove typecasts 2011-01-13 08:03:23 -08:00
random.c random: mix in architectural randomness in extract_buf() 2012-08-15 12:04:29 -07:00
raw.c RAW driver: Remove call to kobject_put(). 2011-05-06 17:52:32 -07:00
rtc.c of/device: Replace struct of_device with struct platform_device 2010-08-06 09:25:50 -06:00
scc.h
scx200_gpio.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
snsc_event.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
snsc.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
snsc.h headers: kobject.h redux 2011-01-10 08:51:44 -08:00
sonypi.c Fix common misspellings 2011-03-31 11:26:23 -03:00
tb0219.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
tlclk.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
toshiba.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
ttyprintk.c TTY: ttyprintk, don't touch behind tty->write_buf 2012-10-07 08:27:25 -07:00
uv_mmtimer.c BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
viotape.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
virtio_console.c virtio console: don't manually set or finalize VIRTIO_CONSOLE_F_MULTIPORT. 2011-05-30 11:14:13 +09:30