]>
Commit | Line | Data |
---|---|---|
eba31af1 GKH |
1 | From 50e7044535537b2a54c7ab798cd34c7f6d900bd2 Mon Sep 17 00:00:00 2001 |
2 | From: Oliver Neukum <oneukum@suse.com> | |
3 | Date: Mon, 8 Jan 2018 09:21:07 -0500 | |
4 | Subject: media: usbtv: prevent double free in error case | |
5 | ||
6 | From: Oliver Neukum <oneukum@suse.com> | |
7 | ||
8 | commit 50e7044535537b2a54c7ab798cd34c7f6d900bd2 upstream. | |
9 | ||
10 | Quoting the original report: | |
11 | ||
12 | It looks like there is a double-free vulnerability in Linux usbtv driver | |
13 | on an error path of usbtv_probe function. When audio registration fails, | |
14 | usbtv_video_free function ends up freeing usbtv data structure, which | |
15 | gets freed the second time under usbtv_video_fail label. | |
16 | ||
17 | usbtv_audio_fail: | |
18 | ||
19 | usbtv_video_free(usbtv); => | |
20 | ||
21 | v4l2_device_put(&usbtv->v4l2_dev); | |
22 | ||
23 | => v4l2_device_put | |
24 | ||
25 | => kref_put | |
26 | ||
27 | => v4l2_device_release | |
28 | ||
29 | => usbtv_release (CALLBACK) | |
30 | ||
31 | => kfree(usbtv) (1st time) | |
32 | ||
33 | usbtv_video_fail: | |
34 | ||
35 | usb_set_intfdata(intf, NULL); | |
36 | ||
37 | usb_put_dev(usbtv->udev); | |
38 | ||
39 | kfree(usbtv); (2nd time) | |
40 | ||
41 | So, as we have refcounting, use it | |
42 | ||
43 | Reported-by: Yavuz, Tuba <tuba@ece.ufl.edu> | |
44 | Signed-off-by: Oliver Neukum <oneukum@suse.com> | |
45 | CC: stable@vger.kernel.org | |
46 | Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> | |
47 | Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> | |
48 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
49 | ||
50 | --- | |
51 | drivers/media/usb/usbtv/usbtv-core.c | 2 ++ | |
52 | 1 file changed, 2 insertions(+) | |
53 | ||
54 | --- a/drivers/media/usb/usbtv/usbtv-core.c | |
55 | +++ b/drivers/media/usb/usbtv/usbtv-core.c | |
56 | @@ -95,6 +95,8 @@ static int usbtv_probe(struct usb_interf | |
57 | return 0; | |
58 | ||
59 | usbtv_audio_fail: | |
60 | + /* we must not free at this point */ | |
61 | + usb_get_dev(usbtv->udev); | |
62 | usbtv_video_free(usbtv); | |
63 | ||
64 | usbtv_video_fail: |