linux_dsm_epyc7002/drivers
Hans de Goede e3e72f39b6 [media] v4l2-event: Don't set sev->fh to NULL on unsubscribe
Setting sev->fh to NULL causes problems for the del op added in the next
patch of this series, since this op needs a way to get to its own data
structures, and typically this will be done by using container_of on an
embedded v4l2_fh struct.

The reason the original code is setting sev->fh to NULL is to signal
to users of the event framework that the unsubscription has happened,
but since their is no shared lock between the event framework and users
of it, this is inherently racy, and it also turns out to be unnecessary
as long as both the event framework and the user of the framework do their
own locking properly and the user guarantees that it holds no references
to the subcribed_event structure after its del operation has been called.

This is best explained by looking at the only code currently checking for
sev->fh being set to NULL on unsubscribe, which is the v4l2-ctrls.c send_event
function. Here is the relevant code from v4l2-ctrls: send_event():

	if (sev->fh && (sev->fh != fh ||
			(sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)))
		v4l2_event_queue_fh(sev->fh, &ev);

Now lets say that v4l2_event_unsubscribe and v4l2-ctrls: send_event() race
on the same sev, then the following could happens:

1) send_event checks sev->fh, finds it is not NULL
<thread switch>
2) v4l2_event_unsubscribe sets sev->fh NULL
3) v4l2_event_unsubscribe calls v4l2_ctrls del_event function, this blocks
   as the thread calling send_event holds the ctrl_lock
<thread switch>
4) send_event calls v4l2_event_queue_fh(sev->fh, &ev) which not is equivalent
   to calling: v4l2_event_queue_fh(NULL, &ev)
5) oops, NULL pointer deref.

Now again without setting sev->fh to NULL in v4l2_event_unsubscribe and
without the (now senseless since always true) sev->fh != NULL check in

1) send_event is about to call v4l2_event_queue_fh(sev->fh, &ev)
<thread switch>
2) v4l2_event_unsubscribe removes sev->list from the fh->subscribed list
<thread switch>
3) send_event calls v4l2_event_queue_fh(sev->fh, &ev)
4) v4l2_event_queue_fh blocks on the fh_lock spinlock
<thread switch>
5) v4l2_event_unsubscribe unlocks the fh_lock spinlock
6) v4l2_event_unsubscribe calls v4l2_ctrls del_event function, this blocks
   as the thread calling send_event holds the ctrl_lock
<thread switch>
8) v4l2_event_queue_fh takes the fh_lock
7) v4l2_event_queue_fh calls v4l2_event_subscribed, does not find it since
   sev->list has been removed from fh->subscribed already -> does nothing
9) v4l2_event_queue_fh releases the fh_lock
10) the caller of send_event releases the ctrl lock (mutex)
<thread switch>
11) v4l2_ctrls del_event takes the ctrl lock
12) v4l2_ctrls del_event removes sev->node from the ev_subs list
13) v4l2_ctrls del_event releases the ctrl lock
14) v4l2_event_unsubscribe frees the sev, to which no references are being
    held anymore

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-11-08 10:29:51 -02:00
..
accessibility
acpi Merge branch 'next-rebase' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci 2011-10-28 14:20:44 -07:00
amba
ata Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6 2011-10-28 16:44:18 -07:00
atm Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2011-10-25 13:25:22 +02:00
auxdisplay
base Merge branch 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm 2011-10-25 15:18:39 +02:00
bcma
block Merge branch 'for-linus' of git://ceph.newdream.net/git/ceph-client 2011-10-28 16:42:18 -07:00
bluetooth Merge branch 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm 2011-10-25 15:18:39 +02:00
cdrom
char Merge branch 'drm-core-next' of git://people.freedesktop.org/~airlied/linux 2011-10-28 05:54:23 -07:00
clk
clocksource Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-26 17:15:03 +02:00
connector
cpufreq Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-26 17:15:03 +02:00
cpuidle
crypto
dca
devfreq
dio
dma [media] dmaengine: ipu-idmac: add support for the DMA_PAUSE control 2011-11-03 18:28:33 -02:00
edac amd64_edac: Cleanup return type of amd64_determine_edac_cap() 2011-10-06 12:35:46 +02:00
eisa
firewire
firmware
gpio Merge branch 'gpio/next' of git://git.secretlab.ca/git/linux-2.6 2011-10-29 07:27:45 -07:00
gpu Merge branch 'drm-core-next' of git://people.freedesktop.org/~airlied/linux 2011-10-28 05:54:23 -07:00
hid Merge branch 'next' into for-linus 2011-10-26 21:46:20 -07:00
hv hv: remove struct hv_device_info from hyperv.h 2011-10-11 09:51:22 -06:00
hwmon Merge branch 'x86-microcode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-28 05:14:48 -07:00
hwspinlock
i2c i2c-algo-pca: Return standard fault codes 2011-10-30 13:47:25 +01:00
ide Merge branch 'gpio' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm 2011-10-27 08:39:10 +02:00
idle
ieee802154
infiniband Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6 2011-10-28 16:44:18 -07:00
input Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media 2011-10-31 15:42:54 -07:00
iommu Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu 2011-10-30 15:46:19 -07:00
isdn Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty 2011-10-26 15:11:09 +02:00
leds Merge branch 'x86-geode-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-28 05:04:26 -07:00
lguest lguest: move process freezing before pending signals check 2011-10-27 10:56:18 +10:30
macintosh
mca
md Merge branch 'for-linus' of git://neil.brown.name/md 2011-10-31 15:21:29 -07:00
media [media] v4l2-event: Don't set sev->fh to NULL on unsubscribe 2011-11-08 10:29:51 -02:00
memstick
message
mfd Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound 2011-10-28 14:25:01 -07:00
misc Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media 2011-10-31 15:42:54 -07:00
mmc Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc 2011-10-28 14:16:11 -07:00
mtd Merge branch 'gpio' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm 2011-10-27 08:39:10 +02:00
net Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2011-10-31 15:22:44 -07:00
nfc
nubus
of of_mdio: Don't phy_scan_fixups() twice 2011-10-25 06:55:52 +02:00
oprofile
parisc
parport parport_pc: release IO region properly if unsupported ITE887x card is found 2011-10-18 14:17:40 -07:00
pci Merge branch 'next-rebase' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci 2011-10-28 14:20:44 -07:00
pcmcia Merge branch 'gpio' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm 2011-10-27 08:39:10 +02:00
pinctrl pinctrl/sirf: fix sirfsoc_get_group_pins prototype 2011-10-25 10:43:57 +02:00
platform thinkpad_acpi: Fix printk typo 'bluestooth' 2011-10-07 09:39:51 +02:00
pnp
power
pps
ps3
ptp
rapidio
regulator regulator: Add WM1811 support 2011-10-07 12:49:18 +01:00
rtc
s390 Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6 2011-10-28 16:44:18 -07:00
sbus
scsi Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6 2011-10-28 16:44:18 -07:00
sfi
sh
sn
spi Merge branch 'spi/next' of git://git.secretlab.ca/git/linux-2.6 2011-10-29 07:28:36 -07:00
ssb
staging staging: Move media drivers to staging/media 2011-11-03 07:59:03 -02:00
target Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2011-10-25 12:11:02 +02:00
tc
telephony
thermal
tty Merge branch 'spi/next' of git://git.secretlab.ca/git/linux-2.6 2011-10-29 07:28:36 -07:00
uio uio: Support physical addresses >32 bits on 32-bit systems 2011-10-18 11:18:57 -07:00
usb Merge branch 'devel-stable' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm 2011-10-28 12:02:27 -07:00
uwb
vhost
video Merge branch 'fbdev-next' of git://github.com/schandinat/linux-2.6 2011-10-30 15:30:01 -07:00
virt
virtio Add ethtool -g support to virtio_net 2011-10-24 02:07:21 -04:00
vlynq
w1
watchdog Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-26 17:03:38 +02:00
xen Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-26 16:44:09 +02:00
zorro zorro: Fix four checkpatch warnings 2011-10-24 21:00:34 +02:00
Kconfig Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging 2011-10-26 15:39:02 +02:00
Makefile Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging 2011-10-26 15:39:02 +02:00