From: Mauro Carvalho Chehab Date: Fri, 14 Nov 2008 13:46:59 +0000 (-0300) Subject: V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble X-Git-Tag: v2.6.28-rc5~7^2 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9;p=linux-2.6-omap-h63xx.git V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble This bug were supposed to be fixed by 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1, where a call to NULL happens. Not all tvaudio chips allow controlling bass/treble. So, the driver has a table with a flag to indicate if the chip does support it. Unfortunately, the handling of this logic were broken for a very long time (probably since the first module version). Due to that, an OOPS were generated for devices that don't support bass/treble. This were the resulting OOPS message before the patch, with debug messages enabled: tvaudio' 1-005b: VIDIOC_S_CTRL BUG: unable to handle kernel NULL pointer dereference at 00000000 IP: [<00000000>] *pde = 22fda067 *pte = 00000000 Oops: 0000 [#1] SMP Modules linked in: snd_hda_intel snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_hwdep snd soundcore tuner_simple tuner_types tea5767 tuner tvaudio bttv bridgebnep rfcomm l2cap bluetooth it87 hwmon_vid hwmon fuse sunrpc ipt_REJECT nf_conntrack_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 dm_mirrordm_multipath dm_mod configfs videodev v4l1_compat ir_common 8139cp compat_ioctl32 v4l2_common 8139too videobuf_dma_sg videobuf_core mii btcx_risc tveeprom i915 button snd_page_alloc serio_raw drm pcspkr i2c_algo_bit i2c_i801 i2c_core iTCO_wdt iTCO_vendor_support sr_mod cdrom sg ata_generic pata_acpi ata_piix libata sd_mod scsi_mod ext3 jbdmbcache uhci_hcd ohci_hcd ehci_hcd [last unloaded: soundcore] Pid: 15413, comm: qv4l2 Not tainted (2.6.25.14-108.fc9.i686 #1) EIP: 0060:[<00000000>] EFLAGS: 00210246 CPU: 0 EIP is at 0x0 EAX: 00008000 EBX: ebd21600 ECX: e2fd9ec4 EDX: 00200046 ESI: f8c0f0c4 EDI: f8c0f0c4 EBP: e2fd9d50 ESP: e2fd9d2c DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Process qv4l2 (pid: 15413, ti=e2fd9000 task=ebe44000 task.ti=e2fd9000) Stack: f8c0c6ae e2ff2a00 00000d00 e2fd9ec4 ebc4e000 e2fd9d5c f8c0c448 00000000 f899c12a e2fd9d5c f899c154 e2fd9d68 e2fd9d80 c0560185 e2fd9d88 f8f3e1d8 f8f3e1dc ebc4e034 f8f3e18c e2fd9ec4 00000000 e2fd9d90 f899c286 c008561c Call Trace: [] ? chip_command+0x266/0x4b6 [tvaudio] [] ? chip_command+0x0/0x4b6 [tvaudio] [] ? i2c_cmd+0x0/0x2f [i2c_core] [] ? i2c_cmd+0x2a/0x2f [i2c_core] [] ? device_for_each_child+0x21/0x49 [] ? i2c_clients_command+0x1c/0x1e [i2c_core] [] ? bttv_call_i2c_clients+0x14/0x16 [bttv] [] ? bttv_s_ctrl+0x1bc/0x313 [bttv] [] ? bttv_s_ctrl+0x0/0x313 [bttv] [] ? __video_do_ioctl+0x1f84/0x3726 [videodev] [] ? sock_aio_write+0x100/0x10d [] ? kmap_atomic_prot+0x1dd/0x1df [] ? enqueue_hrtimer+0xc2/0xcd [] ? copy_from_user+0x39/0x121 [] ? __video_ioctl2+0x1aa/0x24a [videodev] [] ? do_notify_resume+0x768/0x795 [] ? getnstimeofday+0x34/0xd1 [] ? autoremove_wake_function+0x0/0x33 [] ? video_ioctl2+0xf/0x13 [videodev] [] ? vfs_ioctl+0x50/0x69 [] ? do_vfs_ioctl+0x239/0x24c [] ? sys_ioctl+0x40/0x5b [] ? syscall_call+0x7/0xb [] ? cpuid4_cache_sysfs_exit+0x3d/0x69 ======================= Code: Bad EIP value. EIP: [<00000000>] 0x0 SS:ESP 0068:e2fd9d2c Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index fb46ce4a109..3720f0e03a1 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1639,13 +1639,13 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip, return 0; } case V4L2_CID_AUDIO_BASS: - if (desc->flags & CHIP_HAS_BASSTREBLE) + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) break; ctrl->value = chip->bass; return 0; case V4L2_CID_AUDIO_TREBLE: - if (desc->flags & CHIP_HAS_BASSTREBLE) - return -EINVAL; + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) + break; ctrl->value = chip->treble; return 0; } @@ -1705,16 +1705,15 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip, return 0; } case V4L2_CID_AUDIO_BASS: - if (desc->flags & CHIP_HAS_BASSTREBLE) + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) break; chip->bass = ctrl->value; chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); return 0; case V4L2_CID_AUDIO_TREBLE: - if (desc->flags & CHIP_HAS_BASSTREBLE) - return -EINVAL; - + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) + break; chip->treble = ctrl->value; chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); @@ -1761,7 +1760,7 @@ static int chip_command(struct i2c_client *client, break; case V4L2_CID_AUDIO_BASS: case V4L2_CID_AUDIO_TREBLE: - if (desc->flags & CHIP_HAS_BASSTREBLE) + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) return -EINVAL; break; default: