]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
a02dafd8c074f268768550ba9586212d3a643cb6
[thirdparty/kernel/stable-queue.git] /
1 From 52759c0963510a2843774aac9b65ccaed3308dc0 Mon Sep 17 00:00:00 2001
2 From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
3 Date: Sun, 29 Apr 2018 15:01:46 +0900
4 Subject: ALSA: dice: fix kernel NULL pointer dereference due to invalid calculation for array index
5
6 From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
7
8 commit 52759c0963510a2843774aac9b65ccaed3308dc0 upstream.
9
10 At a commit f91c9d7610a ('ALSA: firewire-lib: cache maximum length of
11 payload to reduce function calls'), maximum size of payload for tx
12 isochronous packet is cached to reduce the number of function calls.
13
14 This cache was programmed to updated at a first callback of ohci1394 IR
15 context. However, the maximum size is required to queueing packets before
16 starting the isochronous context.
17
18 As a result, the cached value is reused to queue packets in next time to
19 starting the isochronous context. Then the cache is updated in a first
20 callback of the isochronous context. This can cause kernel NULL pointer
21 dereference in a below call graph:
22
23 (sound/firewire/amdtp-stream.c)
24 amdtp_stream_start()
25 ->queue_in_packet()
26 ->queue_packet()
27 (drivers/firewire/core-iso.c)
28 ->fw_iso_context_queue()
29 ->struct fw_card_driver.queue_iso()
30 (drivers/firewire/ohci.c)
31 = ohci_queue_iso()
32 ->queue_iso_packet_per_buffer()
33 buffer->pages[page]
34
35 The issued dereference occurs in a case that:
36 - target unit supports different stream formats for sampling transmission
37 frequency.
38 - maximum length of payload for tx stream in a first trial is bigger
39 than the length in a second trial.
40
41 In this case, correct number of pages are allocated for DMA and the 'pages'
42 array has enough elements, while index of the element is wrongly calculated
43 according to the old value of length of payload in a call of
44 'queue_in_packet()'. Then it causes the issue.
45
46 This commit fixes the critical bug. This affects all of drivers in ALSA
47 firewire stack in Linux kernel v4.12 or later.
48
49 [12665.302360] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
50 [12665.302415] IP: ohci_queue_iso+0x47c/0x800 [firewire_ohci]
51 [12665.302439] PGD 0
52 [12665.302440] P4D 0
53 [12665.302450]
54 [12665.302470] Oops: 0000 [#1] SMP PTI
55 [12665.302487] Modules linked in: ...
56 [12665.303096] CPU: 1 PID: 12760 Comm: jackd Tainted: P OE 4.13.0-38-generic #43-Ubuntu
57 [12665.303154] Hardware name: /DH77DF, BIOS KCH7710H.86A.0069.2012.0224.1825 02/24/2012
58 [12665.303215] task: ffff9ce87da2ae80 task.stack: ffffb5b8823d0000
59 [12665.303258] RIP: 0010:ohci_queue_iso+0x47c/0x800 [firewire_ohci]
60 [12665.303301] RSP: 0018:ffffb5b8823d3ab8 EFLAGS: 00010086
61 [12665.303337] RAX: ffff9ce4f4876930 RBX: 0000000000000008 RCX: ffff9ce88a3955e0
62 [12665.303384] RDX: 0000000000000000 RSI: 0000000034877f00 RDI: 0000000000000000
63 [12665.303427] RBP: ffffb5b8823d3b68 R08: ffff9ce8ccb390a0 R09: ffff9ce877639ab0
64 [12665.303475] R10: 0000000000000108 R11: 0000000000000000 R12: 0000000000000003
65 [12665.303513] R13: 0000000000000000 R14: ffff9ce4f4876950 R15: 0000000000000000
66 [12665.303554] FS: 00007f2ec467f8c0(0000) GS:ffff9ce8df280000(0000) knlGS:0000000000000000
67 [12665.303600] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
68 [12665.303633] CR2: 0000000000000030 CR3: 00000002dcf90004 CR4: 00000000000606e0
69 [12665.303674] Call Trace:
70 [12665.303698] fw_iso_context_queue+0x18/0x20 [firewire_core]
71 [12665.303735] queue_packet+0x88/0xe0 [snd_firewire_lib]
72 [12665.303770] amdtp_stream_start+0x19b/0x270 [snd_firewire_lib]
73 [12665.303811] start_streams+0x276/0x3c0 [snd_dice]
74 [12665.303840] snd_dice_stream_start_duplex+0x1bf/0x480 [snd_dice]
75 [12665.303882] ? vma_gap_callbacks_rotate+0x1e/0x30
76 [12665.303914] ? __rb_insert_augmented+0xab/0x240
77 [12665.303936] capture_prepare+0x3c/0x70 [snd_dice]
78 [12665.303961] snd_pcm_do_prepare+0x1d/0x30 [snd_pcm]
79 [12665.303985] snd_pcm_action_single+0x3b/0x90 [snd_pcm]
80 [12665.304009] snd_pcm_action_nonatomic+0x68/0x70 [snd_pcm]
81 [12665.304035] snd_pcm_prepare+0x68/0x90 [snd_pcm]
82 [12665.304058] snd_pcm_common_ioctl1+0x4c0/0x940 [snd_pcm]
83 [12665.304083] snd_pcm_capture_ioctl1+0x19b/0x250 [snd_pcm]
84 [12665.304108] snd_pcm_capture_ioctl+0x27/0x40 [snd_pcm]
85 [12665.304131] do_vfs_ioctl+0xa8/0x630
86 [12665.304148] ? entry_SYSCALL_64_after_hwframe+0xe9/0x139
87 [12665.304172] ? entry_SYSCALL_64_after_hwframe+0xe2/0x139
88 [12665.304195] ? entry_SYSCALL_64_after_hwframe+0xdb/0x139
89 [12665.304218] ? entry_SYSCALL_64_after_hwframe+0xd4/0x139
90 [12665.304242] ? entry_SYSCALL_64_after_hwframe+0xcd/0x139
91 [12665.304265] ? entry_SYSCALL_64_after_hwframe+0xc6/0x139
92 [12665.304288] ? entry_SYSCALL_64_after_hwframe+0xbf/0x139
93 [12665.304312] ? entry_SYSCALL_64_after_hwframe+0xb8/0x139
94 [12665.304335] ? entry_SYSCALL_64_after_hwframe+0xb1/0x139
95 [12665.304358] SyS_ioctl+0x79/0x90
96 [12665.304374] ? entry_SYSCALL_64_after_hwframe+0x72/0x139
97 [12665.304397] entry_SYSCALL_64_fastpath+0x24/0xab
98 [12665.304417] RIP: 0033:0x7f2ec3750ef7
99 [12665.304433] RSP: 002b:00007fff99e31388 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
100 [12665.304465] RAX: ffffffffffffffda RBX: 00007fff99e312f0 RCX: 00007f2ec3750ef7
101 [12665.304494] RDX: 0000000000000000 RSI: 0000000000004140 RDI: 0000000000000007
102 [12665.304522] RBP: 0000556ebc63fd60 R08: 0000556ebc640560 R09: 0000000000000000
103 [12665.304553] R10: 0000000000000001 R11: 0000000000000246 R12: 0000556ebc63fcf0
104 [12665.304584] R13: 0000000000000000 R14: 0000000000000007 R15: 0000000000000000
105 [12665.304612] Code: 01 00 00 44 89 eb 45 31 ed 45 31 db 66 41 89 1e 66 41 89 5e 0c 66 45 89 5e 0e 49 8b 49 08 49 63 d4 4d 85 c0 49 63 ff 48 8b 14 d1 <48> 8b 72 30 41 8d 14 37 41 89 56 04 48 63 d3 0f 84 ce 00 00 00
106 [12665.304713] RIP: ohci_queue_iso+0x47c/0x800 [firewire_ohci] RSP: ffffb5b8823d3ab8
107 [12665.304743] CR2: 0000000000000030
108 [12665.317701] ---[ end trace 9d55b056dd52a19f ]---
109
110 Fixes: f91c9d7610a ('ALSA: firewire-lib: cache maximum length of payload to reduce function calls')
111 Cc: <stable@vger.kernel.org> # v4.12+
112 Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
113 Signed-off-by: Takashi Iwai <tiwai@suse.de>
114 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
115
116 ---
117 sound/firewire/amdtp-stream.c | 5 +++--
118 1 file changed, 3 insertions(+), 2 deletions(-)
119
120 --- a/sound/firewire/amdtp-stream.c
121 +++ b/sound/firewire/amdtp-stream.c
122 @@ -773,8 +773,6 @@ static void amdtp_stream_first_callback(
123 u32 cycle;
124 unsigned int packets;
125
126 - s->max_payload_length = amdtp_stream_get_max_payload(s);
127 -
128 /*
129 * For in-stream, first packet has come.
130 * For out-stream, prepared to transmit first packet
131 @@ -879,6 +877,9 @@ int amdtp_stream_start(struct amdtp_stre
132
133 amdtp_stream_update(s);
134
135 + if (s->direction == AMDTP_IN_STREAM)
136 + s->max_payload_length = amdtp_stream_get_max_payload(s);
137 +
138 if (s->flags & CIP_NO_HEADER)
139 s->tag = TAG_NO_CIP_HEADER;
140 else