summaryrefslogtreecommitdiff
path: root/sound/core
AgeCommit message (Collapse)AuthorFilesLines
2019-04-04ALSA: pcm: Fix potential Spectre v1 vulnerabilityGustavo A. R. Silva1-0/+2
commit 94ffb030b6d31ec840bb811be455dd2e26a4f43e upstream. stream is indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability. This issue was detected with the help of Smatch: sound/core/pcm.c:140 snd_pcm_control_ioctl() warn: potential spectre issue 'pcm->streams' [r] (local cap) Fix this by sanitizing stream before using it to index pcm->streams Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1]. [1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2 Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2019-02-11ALSA: pcm: Call snd_pcm_unlink() conditionally at closingTakashi Iwai1-1/+2
commit b51abed8355e5556886623b2772fa6b7598d2282 upstream. Currently the PCM core calls snd_pcm_unlink() always unconditionally at closing a stream. However, since snd_pcm_unlink() invokes the global rwsem down, the lock can be easily contended. More badly, when a thread runs in a high priority RT-FIFO, it may stall at spinning. Basically the call of snd_pcm_unlink() is required only for the linked streams that are already rare occasion. For normal use cases, this code path is fairly superfluous. As an optimization (and also as a workaround for the RT problem above in normal situations without linked streams), this patch adds a check before calling snd_pcm_unlink() and calls it only when needed. Reported-by: Chanho Min <chanho.min@lge.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2019-02-11ALSA: control: Fix race between adding and removing a user elementTakashi Iwai1-35/+45
commit e1a7bfe3807974e66f971f2589d4e0197ec0fced upstream. The procedure for adding a user control element has some window opened for race against the concurrent removal of a user element. This was caught by syzkaller, hitting a KASAN use-after-free error. This patch addresses the bug by wrapping the whole procedure to add a user control element with the card->controls_rwsem, instead of only around the increment of card->user_ctl_count. This required a slight code refactoring, too. The function snd_ctl_add() is split to two parts: a core function to add the control element and a part calling it. The former is called from the function for adding a user control element inside the controls_rwsem. One change to be noted is that snd_ctl_notify() for adding a control element gets called inside the controls_rwsem as well while it was called outside the rwsem. But this should be OK, as snd_ctl_notify() takes another (finer) rwlock instead of rwsem, and the call of snd_ctl_notify() inside rwsem is already done in another code path. Reported-by: syzbot+dc09047bce3820621ba2@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: - In snd_ctl_elem_add(), free _kctl on error, not kctl - Adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2019-02-11ALSA: control: fix failure to return numerical ID in 'add' eventTakashi Sakamoto1-0/+1
commit d34890cf4113397625a6629d71749fa638a7a734 upstream. Currently when adding a new control, the assigned numerical ID is not set for event data, thus userspace applications cannot realize it just by event data. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2019-02-11ALSA: oss: Use kvzalloc() for local buffer allocationsTakashi Iwai2-2/+2
commit 65766ee0bf7fe8b3be80e2e1c3ef54ad59b29476 upstream. PCM OSS layer may allocate a few temporary buffers, one for the core read/write and another for the conversions via plugins. Currently both are allocated via vmalloc(). But as the allocation size is equivalent with the PCM period size, the required size might be quite small, depending on the application. This patch replaces these vmalloc() calls with kvzalloc() for covering small period sizes better. Also, we use "z"-alloc variant here for addressing the possible uninitialized access reported by syzkaller. Reported-by: syzbot+1cb36954e127c98dd037@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: kvzalloc() does not exist, so only change to using vzalloc()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-12-17ALSA: virmidi: Fix too long output trigger loopTakashi Iwai1-0/+10
commit 50e9ffb1996a5d11ff5040a266585bad4ceeca0a upstream. The virmidi output trigger tries to parse the all available bytes and process sequencer events as much as possible. In a normal situation, this is supposed to be relatively short, but a program may give a huge buffer and it'll take a long time in a single spin lock, which may eventually lead to a soft lockup. This patch simply adds a workaround, a cond_resched() call in the loop if applicable. A better solution would be to move the event processor into a work, but let's put a duct-tape quickly at first. Reported-and-tested-by: Dae R. Jeong <threeearcat@gmail.com> Reported-by: syzbot+619d9f40141d826b097e@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-12-17ALSA: seq: Fix poll() error returnTakashi Iwai2-2/+2
commit a49a71f6e25da2acc637fcd31e73debd96ca18f8 upstream. The sanity checks in ALSA sequencer and OSS sequencer emulation codes return falsely -ENXIO from poll callback. They should be EPOLLERR instead. This was caught thanks to the recent change to the return value. Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: s/EPOLLERR/POLLERR/] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-12-17ALSA: memalloc: Don't exceed over the requested sizeTakashi Iwai1-6/+2
commit dfef01e150824b0e6da750cacda8958188d29aea upstream. snd_dma_alloc_pages_fallback() tries to allocate pages again when the allocation fails with reduced size. But the first try actually *increases* the size to power-of-two, which may give back a larger chunk than the requested size. This confuses the callers, e.g. sgbuf assumes that the size is equal or less, and it may result in a bad loop due to the underflow and eventually lead to Oops. The code of this function seems incorrectly assuming the usage of get_order(). We need to decrease at first, then align to power-of-two. Reported-and-tested-by: he, bo <bo.he@intel.com> Reported-by: zhang jun <jun.zhang@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-11-20ALSA: timer: Fix UBSAN warning at SNDRV_TIMER_IOCTL_NEXT_DEVICE ioctlTakashi Iwai1-1/+1
commit b41f794f284966fd6ec634111e3b40d241389f96 upstream. The kernel may spew a WARNING about UBSAN undefined behavior at handling ALSA timer ioctl SNDRV_TIMER_IOCTL_NEXT_DEVICE: UBSAN: Undefined behaviour in sound/core/timer.c:1524:19 signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x122/0x1c8 lib/dump_stack.c:113 ubsan_epilogue+0x12/0x86 lib/ubsan.c:159 handle_overflow+0x1c2/0x21f lib/ubsan.c:190 __ubsan_handle_add_overflow+0x2a/0x31 lib/ubsan.c:198 snd_timer_user_next_device sound/core/timer.c:1524 [inline] __snd_timer_user_ioctl+0x204d/0x2520 sound/core/timer.c:1939 snd_timer_user_ioctl+0x67/0x95 sound/core/timer.c:1994 .... It happens only when a value with INT_MAX is passed, as we're incrementing it unconditionally. So the fix is trivial, check the value with INT_MAX. Although the bug itself is fairly harmless, it's better to fix it so that fuzzers won't hit this again later. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200213 Reported-and-tested-by: Team OWL337 <icytxw@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: adjust context, indentation] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-11-20ALSA: core: Assure control device to be registered at lastTakashi Iwai1-0/+9
commit dc82e52492f684dcd5ed9e4773e72dbf2203d75e upstream. The commit 289ca025ee1d ("ALSA: Use priority list for managing device list") changed the way to register/disconnect/free devices via a single priority list. This helped to make behavior consistent, but it also changed a slight behavior change: namely, the control device is registered earlier than others, while it was supposed to be the very last one. I've put SNDRV_DEV_CONTROL in the current position as the release of ctl elements often conflict with the private ctl elements some PCM or other components may create, which often leads to a double-free. But, the order of register and disconnect should be indeed fixed as expected in the early days: the control device gets registered at last, and disconnected at first. This patch changes the priority list order to move SNDRV_DEV_CONTROL as the last guy to assure the register / disconnect order. Meanwhile, for keeping the messy resource release order, manually treat the control and lowlevel devices as last freed one. Additional note: The lowlevel device is the device where a card driver creates at probe. And, we still keep the release order control -> lowlevel, as there might be link from a control element back to a lowlevel object. Fixes: 289ca025ee1d ("ALSA: Use priority list for managing device list") Reported-by: Tzung-Bi Shih <tzungbi@google.com> Tested-by: Tzung-Bi Shih <tzungbi@google.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: timer: Fix pause event notificationBen Hutchings1-2/+2
commit 3ae180972564846e6d794e3615e1ab0a1e6c4ef9 upstream. Commit f65e0d299807 ("ALSA: timer: Call notifier in the same spinlock") combined the start/continue and stop/pause functions, and in doing so changed the event code for the pause case to SNDRV_TIMER_EVENT_CONTINUE. Change it back to SNDRV_TIMER_EVENT_PAUSE. Fixes: f65e0d299807 ("ALSA: timer: Call notifier in the same spinlock") Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: timer: Call notifier in the same spinlockTakashi Iwai1-119/+103
commit f65e0d299807d8a11812845c972493c3f9a18e10 upstream. snd_timer_notify1() is called outside the spinlock and it retakes the lock after the unlock. This is rather racy, and it's safer to move snd_timer_notify() call inside the main spinlock. The patch also contains a slight refactoring / cleanup of the code. Now all start/stop/continue/pause look more symmetric and a bit better readable. Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: - Fix up another use of "event" in _snd_timer_stop() - Adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: control: fix a redundant-copy issueWenwen Wang1-2/+1
commit 3f12888dfae2a48741c4caa9214885b3aaf350f9 upstream. In snd_ctl_elem_add_compat(), the fields of the struct 'data' need to be copied from the corresponding fields of the struct 'data32' in userspace. This is achieved by invoking copy_from_user() and get_user() functions. The problem here is that the 'type' field is copied twice. One is by copy_from_user() and one is by get_user(). Given that the 'type' field is not used between the two copies, the second copy is *completely* redundant and should be removed for better performance and cleanup. Also, these two copies can cause inconsistent data: as the struct 'data32' resides in userspace and a malicious userspace process can race to change the 'type' field between the two copies to cause inconsistent data. Depending on how the data is used in the future, such an inconsistency may cause potential security risks. For above reasons, we should take out the second copy. Signed-off-by: Wenwen Wang <wang6495@umn.edu> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Check PCM state at xfern compat ioctlTakashi Iwai1-0/+2
commit f13876e2c33a657a71bcbb10f767c0951b165020 upstream. Since snd_pcm_ioctl_xfern_compat() has no PCM state check, it may go further and hit the sanity check pcm_sanity_check() when the ioctl is called right after open. It may eventually spew a kernel warning, as triggered by syzbot, depending on kconfig. The lack of PCM state check there was just an oversight. Although it's no real crash, the spurious kernel warning is annoying, so let's add the proper check. Reported-by: syzbot+1dac3a4f6bc9c1c675d4@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: seq: Fix races at MIDI encoding in snd_virmidi_output_trigger()Takashi Iwai1-2/+2
commit 8f22e52528cc372b218b5f100457469615c733ce upstream. The sequencer virmidi code has an open race at its output trigger callback: namely, virmidi keeps only one event packet for processing while it doesn't protect for concurrent output trigger calls. snd_virmidi_output_trigger() tries to process the previously unfinished event before starting encoding the given MIDI stream, but this is done without any lock. Meanwhile, if another rawmidi stream starts the output trigger, this proceeds further, and overwrites the event package that is being processed in another thread. This eventually corrupts and may lead to the invalid memory access if the event type is like SYSEX. The fix is just to move the spinlock to cover both the pending event and the new stream. The bug was spotted by a new fuzzer, RaceFuzzer. BugLink: http://lkml.kernel.org/r/20180426045223.GA15307@dragonet.kaist.ac.kr Reported-by: DaeRyong Jeong <threeearcat@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: seq: oss: Hardening for potential Spectre v1Takashi Iwai4-40/+55
commit 8d218dd8116695ecda7164f97631c069938aa22e upstream. As Smatch recently suggested, a few places in OSS sequencer codes may expand the array directly from the user-space value with speculation, namely there are a significant amount of references to either info->ch[] or dp->synths[] array: sound/core/seq/oss/seq_oss_event.c:315 note_on_event() warn: potential spectre issue 'info->ch' (local cap) sound/core/seq/oss/seq_oss_event.c:362 note_off_event() warn: potential spectre issue 'info->ch' (local cap) sound/core/seq/oss/seq_oss_synth.c:470 snd_seq_oss_synth_load_patch() warn: potential spectre issue 'dp->synths' (local cap) sound/core/seq/oss/seq_oss_event.c:293 note_on_event() warn: potential spectre issue 'dp->synths' sound/core/seq/oss/seq_oss_event.c:353 note_off_event() warn: potential spectre issue 'dp->synths' sound/core/seq/oss/seq_oss_synth.c:506 snd_seq_oss_synth_sysex() warn: potential spectre issue 'dp->synths' sound/core/seq/oss/seq_oss_synth.c:580 snd_seq_oss_synth_ioctl() warn: potential spectre issue 'dp->synths' Although all these seem doing only the first load without further reference, we may want to stay in a safer side, so hardening with array_index_nospec() would still make sense. We may put array_index_nospec() at each place, but here we take a different approach: - For dp->synths[], change the helpers to retrieve seq_oss_synthinfo pointer directly instead of the array expansion at each place - For info->ch[], harden in a normal way, as there are only a couple of places As a result, the existing helper, snd_seq_oss_synth_is_valid() is replaced with snd_seq_oss_synth_info(). Also, we cover MIDI device where a similar array expansion is done, too, although it wasn't reported by Smatch. BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2 Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: seq: oss: Fix unbalanced use lock for synth MIDI deviceTakashi Iwai1-4/+8
commit f5e94b4c6ebdabe0f602d796e0430180927521a0 upstream. When get_synthdev() is called for a MIDI device, it returns the fixed midi_synth_dev without the use refcounting. OTOH, the caller is supposed to unreference unconditionally after the usage, so this would lead to unbalanced refcount. This patch corrects the behavior and keep up the refcount balance also for the MIDI synth device. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: core: Report audio_tstamp in snd_pcm_sync_ptrDavid Henningsson1-0/+1
commit f853dcaae2f5bbe021161e421bd1576845bae8f6 upstream. It looks like a simple mistake that this struct member was forgotten. Audio_tstamp isn't used much, and on some archs (such as x86) this ioctl is not used by default, so that might be the reason why this has slipped for so long. Fixes: 4eeaaeaea1ce ("ALSA: core: add hooks for audio timestamps") Signed-off-by: David Henningsson <diwic@ubuntu.com> Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: rawmidi: Fix missing input substream checks in compat ioctlsTakashi Iwai1-6/+12
commit 8a56ef4f3ffba9ebf4967b61ef600b0a7ba10f11 upstream. Some rawmidi compat ioctls lack of the input substream checks (although they do check only for rfile->output). This many eventually lead to an Oops as NULL substream is passed to the rawmidi core functions. Fix it by adding the proper checks before each function call. The bug was spotted by syzkaller. Reported-by: syzbot+f7a0348affc3b67bc617@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Fix endless loop for XRUN recovery in OSS emulationTakashi Iwai1-2/+3
commit e15dc99dbb9cf99f6432e8e3c0b3a8f7a3403a86 upstream. The commit 02a5d6925cd3 ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write") split the PCM preparation code to a locked version, and it added a sanity check of runtime->oss.prepare flag along with the change. This leaded to an endless loop when the stream gets XRUN: namely, snd_pcm_oss_write3() and co call snd_pcm_oss_prepare() without setting runtime->oss.prepare flag and the loop continues until the PCM state reaches to another one. As the function is supposed to execute the preparation unconditionally, drop the invalid state check there. The bug was triggered by syzkaller. Fixes: 02a5d6925cd3 ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write") Reported-by: syzbot+150189c103427d31a053@syzkaller.appspotmail.com Reported-by: syzbot+7e3f31a52646f939c052@syzkaller.appspotmail.com Reported-by: syzbot+4f2016cf5185da7759dc@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Fix UAF at PCM release via PCM timer accessTakashi Iwai1-1/+7
commit a820ccbe21e8ce8e86c39cd1d3bc8c7d1cbb949b upstream. The PCM runtime object is created and freed dynamically at PCM stream open / close time. This is tracked via substream->runtime, and it's cleared at snd_pcm_detach_substream(). The runtime object assignment is protected by PCM open_mutex, so for all PCM operations, it's safely handled. However, each PCM substream provides also an ALSA timer interface, and user-space can access to this while closing a PCM substream. This may eventually lead to a UAF, as snd_pcm_timer_resolution() tries to access the runtime while clearing it in other side. Fortunately, it's the only concurrent access from the PCM timer, and it merely reads runtime->timer_resolution field. So, we can avoid the race by reordering kfree() and wrapping the substream->runtime clearance with the corresponding timer lock. Reported-by: syzbot+8e62ff4e07aa2ce87826@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Fix mutex unbalance in OSS emulation ioctlsTakashi Iwai1-25/+42
commit f6d297df4dd47ef949540e4a201230d0c5308325 upstream. The previous fix 40cab6e88cb0 ("ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams") introduced some mutex unbalance; the check of runtime->oss.rw_ref was inserted in a wrong place after the mutex lock. This patch fixes the inconsistency by rewriting with the helper functions to lock/unlock parameters with the stream check. Fixes: 40cab6e88cb0 ("ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams") Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streamsTakashi Iwai1-9/+27
commit 40cab6e88cb0b6c56d3f30b7491a20e803f948f6 upstream. OSS PCM stream management isn't modal but it allows ioctls issued at any time for changing the parameters. In the previous hardening patch ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write"), we covered these races and prevent the corruption by protecting the concurrent accesses via params_lock mutex. However, this means that some ioctls that try to change the stream parameter (e.g. channels or format) would be blocked until the read/write finishes, and it may take really long. Basically changing the parameter while reading/writing is an invalid operation, hence it's even more user-friendly from the API POV if it returns -EBUSY in such a situation. This patch adds such checks in the relevant ioctls with the addition of read/write access refcount. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Avoid potential races between OSS ioctls and read/writeTakashi Iwai1-28/+106
commit 02a5d6925cd34c3b774bdb8eefb057c40a30e870 upstream. Although we apply the params_lock mutex to the whole read and write operations as well as snd_pcm_oss_change_params(), we may still face some races. First off, the params_lock is taken inside the read and write loop. This is intentional for avoiding the too long locking, but it allows the in-between parameter change, which might lead to invalid pointers. We check the readiness of the stream and set up via snd_pcm_oss_make_ready() at the beginning of read and write, but it's called only once, by assuming that it remains ready in the rest. Second, many ioctls that may change the actual parameters (i.e. setting runtime->oss.params=1) aren't protected, hence they can be processed in a half-baked state. This patch is an attempt to plug these holes. The stream readiness check is moved inside the read/write inner loop, so that the stream is always set up in a proper state before further processing. Also, each ioctl that may change the parameter is wrapped with the params_lock for avoiding the races. The issues were triggered by syzkaller in a few different scenarios, particularly the one below appearing as GPF in loopback_pos_update. Reported-by: syzbot+c4227aec125487ec3efa@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-10-21ALSA: pcm: Use ERESTARTSYS instead of EINTR in OSS emulationTakashi Iwai1-1/+1
commit c64ed5dd9feba193c76eb460b451225ac2a0d87b upstream. Fix the last standing EINTR in the whole subsystem. Use more correct ERESTARTSYS for pending signals. Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-09-26ALSA: rawmidi: Change resized buffers atomicallyTakashi Iwai1-6/+14
commit 39675f7a7c7e7702f7d5341f1e0d01db746543a0 upstream. The SNDRV_RAWMIDI_IOCTL_PARAMS ioctl may resize the buffers and the current code is racy. For example, the sequencer client may write to buffer while it being resized. As a simple workaround, let's switch to the resized buffer inside the stream runtime lock. Reported-by: syzbot+52f83f0ea8df16932f7f@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: pcm: potential uninitialized return valuesDan Carpenter1-2/+2
commit 5607dddbfca774fb38bffadcb077fe03aa4ac5c6 upstream. Smatch complains that "tmp" can be uninitialized if we do a zero size write. Fixes: 02a5d6925cd3 ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: pcm: Use dma_bytes as size parameter in dma_mmap_coherent()Stefan Roese1-1/+1
commit 9066ae7ff5d89c0b5daa271e2d573540097a94fa upstream. When trying to use the driver (e.g. aplay *.wav), the 4MiB DMA buffer will get mmapp'ed in 16KiB chunks. But this fails with the 2nd 16KiB area, as the page offset is outside of the VMA range (size), which is currently used as size parameter in snd_pcm_lib_default_mmap(). By using the DMA buffer size (dma_bytes) instead, the complete DMA buffer can be mmapp'ed and the issue is fixed. This issue was detected on an ARM platform (TI AM57xx) using the RME HDSP MADI PCIe soundcard. Fixes: 657b1989dacf ("ALSA: pcm - Use dma_mmap_coherent() if available") Signed-off-by: Stefan Roese <sr@denx.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: seq: Clear client entry before deleting else at closingTakashi Iwai1-2/+2
commit a2ff19f7b70118ced291a28d5313469914de451b upstream. When releasing a client, we need to clear the clienttab[] entry at first, then call snd_seq_queue_client_leave(). Otherwise, the in-flight cell in the queue might be picked up by the timer interrupt via snd_seq_check_queue() before calling snd_seq_queue_client_leave(), and it's delivered to another queue while the client is clearing queues. This may eventually result in an uncleared cell remaining in a queue, and the later snd_seq_pool_delete() may need to wait for a long time until the event gets really processed. By moving the clienttab[] clearance at the beginning of release, any event delivery of a cell belonging to this client will fail at a later point, since snd_seq_client_ptr() returns NULL. Thus the cell that was picked up by the timer interrupt will be returned immediately without further delivery, and the long stall of snd_seq_delete_pool() can be avoided, too. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: seq: Fix possible UAF in snd_seq_check_queue()Takashi Iwai3-37/+25
commit d0f833065221cbfcbadf19fd4102bcfa9330006a upstream. Although we've covered the races between concurrent write() and ioctl() in the previous patch series, there is still a possible UAF in the following scenario: A: user client closed B: timer irq -> snd_seq_release() -> snd_seq_timer_interrupt() -> snd_seq_free_client() -> snd_seq_check_queue() -> cell = snd_seq_prioq_cell_peek() -> snd_seq_prioq_leave() .... removing all cells -> snd_seq_pool_done() .... vfree() -> snd_seq_compare_tick_time(cell) ... Oops So the problem is that a cell is peeked and accessed without any protection until it's retrieved from the queue again via snd_seq_prioq_cell_out(). This patch tries to address it, also cleans up the code by a slight refactoring. snd_seq_prioq_cell_out() now receives an extra pointer argument. When it's non-NULL, the function checks the event timestamp with the given pointer. The caller needs to pass the right reference either to snd_seq_tick or snd_seq_realtime depending on the event timestamp type. A good news is that the above change allows us to remove the snd_seq_prioq_cell_peek(), too, thus the patch actually reduces the code size. Reviewed-by: Nicolai Stange <nstange@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: seq: More protection for concurrent write and ioctl racesTakashi Iwai4-13/+24
commit 7bd80091567789f1c0cb70eb4737aac8bcd2b6b9 upstream. This patch is an attempt for further hardening against races between the concurrent write and ioctls. The previous fix d15d662e89fc ("ALSA: seq: Fix racy pool initializations") covered the race of the pool initialization at writer and the pool resize ioctl by the client->ioctl_mutex (CVE-2018-1000004). However, basically this mutex should be applied more widely to the whole write operation for avoiding the unexpected pool operations by another thread. The only change outside snd_seq_write() is the additional mutex argument to helper functions, so that we can unlock / relock the given mutex temporarily during schedule() call for blocking write. Fixes: d15d662e89fc ("ALSA: seq: Fix racy pool initializations") Reported-by: 范龙飞 <long7573@126.com> Reported-by: Nicolai Stange <nstange@suse.de> Reviewed-and-tested-by: Nicolai Stange <nstange@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: seq: Don't allow resizing pool in useTakashi Iwai1-0/+3
commit d85739367c6d56e475c281945c68fdb05ca74b4c upstream. This is a fix for a (sort of) fallout in the recent commit d15d662e89fc ("ALSA: seq: Fix racy pool initializations") for CVE-2018-1000004. As the pool resize deletes the existing cells, it may lead to a race when another thread is writing concurrently, eventually resulting a UAF. A simple workaround is not to allow the pool resizing when the pool is in use. It's an invalid behavior in anyway. Fixes: d15d662e89fc ("ALSA: seq: Fix racy pool initializations") Reported-by: 范龙飞 <long7573@126.com> Reported-by: Nicolai Stange <nstange@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-06-17ALSA: seq: Fix racy pool initializationsTakashi Iwai1-2/+6
commit d15d662e89fc667b90cd294b0eb45694e33144da upstream. ALSA sequencer core initializes the event pool on demand by invoking snd_seq_pool_init() when the first write happens and the pool is empty. Meanwhile user can reset the pool size manually via ioctl concurrently, and this may lead to UAF or out-of-bound accesses since the function tries to vmalloc / vfree the buffer. A simple fix is to just wrap the snd_seq_pool_init() call with the recently introduced client->ioctl_mutex; as the calls for snd_seq_pool_init() from other side are always protected with this mutex, we can avoid the race. Reported-by: 范龙飞 <long7573@126.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: pcm: Remove yet superfluous WARN_ON()Takashi Iwai1-1/+0
commit 23b19b7b50fe1867da8d431eea9cd3e4b6328c2c upstream. muldiv32() contains a snd_BUG_ON() (which is morphed as WARN_ON() with debug option) for checking the case of 0 / 0. This would be helpful if this happens only as a logical error; however, since the hw refine is performed with any data set provided by user, the inconsistent values that can trigger such a condition might be passed easily. Actually, syzbot caught this by passing some zero'ed old hw_params ioctl. So, having snd_BUG_ON() there is simply superfluous and rather harmful to give unnecessary confusions. Let's get rid of it. Reported-by: syzbot+7e6ee55011deeebce15d@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: pcm: Allow aborting mutex lock at OSS read/write loopsTakashi Iwai1-15/+21
commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream. PCM OSS read/write loops keep taking the mutex lock for the whole read/write, and this might take very long when the exceptionally high amount of data is given. Also, since it invokes with mutex_lock(), the concurrent read/write becomes unbreakable. This patch tries to address these issues by replacing mutex_lock() with mutex_lock_interruptible(), and also splits / re-takes the lock at each read/write period chunk, so that it can switch the context more finely if requested. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: pcm: Abort properly at pending signal in OSS read/write loopsTakashi Iwai1-0/+8
commit 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b upstream. The loops for read and write in PCM OSS emulation have no proper check of pending signals, and they keep processing even after user tries to break. This results in a very long delay, often seen as RCU stall when a huge unprocessed bytes remain queued. The bug could be easily triggered by syzkaller. As a simple workaround, this patch adds the proper check of pending signals and aborts the loop appropriately. Reported-by: syzbot+993cb4cfcbbff3947c21@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: pcm: Add missing error checks in OSS emulation plugin builderTakashi Iwai1-3/+11
commit 6708913750344a900f2e73bfe4a4d6dbbce4fe8d upstream. In the OSS emulation plugin builder where the frame size is parsed in the plugin chain, some places miss the possible errors returned from the plugin src_ or dst_frames callback. This patch papers over such places. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: pcm: Remove incorrect snd_BUG_ON() usagesTakashi Iwai2-3/+2
commit fe08f34d066f4404934a509b6806db1a4f700c86 upstream. syzkaller triggered kernel warnings through PCM OSS emulation at closing a stream: WARNING: CPU: 0 PID: 3502 at sound/core/pcm_lib.c:1635 snd_pcm_hw_param_first+0x289/0x690 sound/core/pcm_lib.c:1635 Call Trace: .... snd_pcm_hw_param_near.constprop.27+0x78d/0x9a0 sound/core/oss/pcm_oss.c:457 snd_pcm_oss_change_params+0x17d3/0x3720 sound/core/oss/pcm_oss.c:969 snd_pcm_oss_make_ready+0xaa/0x130 sound/core/oss/pcm_oss.c:1128 snd_pcm_oss_sync+0x257/0x830 sound/core/oss/pcm_oss.c:1638 snd_pcm_oss_release+0x20b/0x280 sound/core/oss/pcm_oss.c:2431 __fput+0x327/0x7e0 fs/file_table.c:210 .... This happens while it tries to open and set up the aloop device concurrently. The warning above (invoked from snd_BUG_ON() macro) is to detect the unexpected logical error where snd_pcm_hw_refine() call shouldn't fail. The theory is true for the case where the hw_params config rules are static. But for an aloop device, the hw_params rule condition does vary dynamically depending on the connected target; when another device is opened and changes the parameters, the device connected in another side is also affected, and it caused the error from snd_pcm_hw_refine(). That is, the simplest "solution" for this is to remove the incorrect assumption of static rules, and treat such an error as a normal error path. As there are a couple of other places using snd_BUG_ON() incorrectly, this patch removes these spurious snd_BUG_ON() calls. Reported-by: syzbot+6f11c7e2a1b91d466432@syzkaller.appspotmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: rawmidi: Avoid racy info ioctl via ctl deviceTakashi Iwai1-3/+12
commit c1cfd9025cc394fd137a01159d74335c5ac978ce upstream. The rawmidi also allows to obtaining the information via ioctl of ctl API. It means that user can issue an ioctl to the rawmidi device even when it's being removed as long as the control device is present. Although the code has some protection via the global register_mutex, its range is limited to the search of the corresponding rawmidi object, and the mutex is already unlocked at accessing the rawmidi object. This may lead to a use-after-free. For avoiding it, this patch widens the application of register_mutex to the whole snd_rawmidi_info_select() function. We have another mutex per rawmidi object, but this operation isn't very hot path, so it shouldn't matter from the performance POV. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: pcm: prevent UAF in snd_pcm_infoRobb Glasser1-0/+2
commit 362bca57f5d78220f8b5907b875961af9436e229 upstream. When the device descriptor is closed, the `substream->runtime` pointer is freed. But another thread may be in the ioctl handler, case SNDRV_CTL_IOCTL_PCM_INFO. This case calls snd_pcm_info_user() which calls snd_pcm_info() which accesses the now freed `substream->runtime`. Note: this fixes CVE-2017-0861 Signed-off-by: Robb Glasser <rglasser@google.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: seq: Remove spurious WARN_ON() at timer checkTakashi Iwai1-1/+1
commit 43a3542870328601be02fcc9d27b09db467336ef upstream. The use of snd_BUG_ON() in ALSA sequencer timer may lead to a spurious WARN_ON() when a slave timer is deployed as its backend and a corresponding master timer stops meanwhile. The symptom was triggered by syzkaller spontaneously. Since the NULL timer is valid there, rip off snd_BUG_ON(). Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-03-03ALSA: seq: Fix regression by incorrect ioctl_mutex usagesTakashi Iwai1-8/+7
This is the revised backport of the upstream commit b3defb791b26ea0683a93a4f49c77ec45ec96f10 We had another backport (e.g. 623e5c8ae32b in 4.4.115), but it applies the new mutex also to the code paths that are invoked via faked kernel-to-kernel ioctls. As reported recently, this leads to a deadlock at suspend (or other scenarios triggering the kernel sequencer client). This patch addresses the issue by taking the mutex only in the code paths invoked by user-space, just like the original fix patch does. Reported-and-tested-by: Andres Bertens <abertensu@yahoo.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-02-13ALSA: seq: Make ioctls race-freeTakashi Iwai2-2/+9
commit b3defb791b26ea0683a93a4f49c77ec45ec96f10 upstream. The ALSA sequencer ioctls have no protection against racy calls while the concurrent operations may lead to interfere with each other. As reported recently, for example, the concurrent calls of setting client pool with a combination of write calls may lead to either the unkillable dead-lock or UAF. As a slightly big hammer solution, this patch introduces the mutex to make each ioctl exclusive. Although this may reduce performance via parallel ioctl calls, usually it's not demanded for sequencer usages, hence it should be negligible. Reported-by: Luo Quan <a4651386@163.com> Reviewed-by: Kees Cook <keescook@chromium.org> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: ioctl dispatch is done from snd_seq_do_ioctl(); take the mutex and add ret variable there.] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-02-13ALSA: timer: Remove kernel warning at compat ioctl error pathsTakashi Iwai1-6/+6
commit 3d4e8303f2c747c8540a0a0126d0151514f6468b upstream. Some timer compat ioctls have NULL checks of timer instance with snd_BUG_ON() that bring up WARN_ON() when the debug option is set. Actually the condition can be met in the normal situation and it's confusing and bad to spew kernel warnings with stack trace there. Let's remove snd_BUG_ON() invocation and replace with the simple checks. Also, correct the error code to EBADFD to follow the native ioctl error handling. Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-01-01ALSA: seq: Fix OSS sysex delivery in OSS emulationTakashi Iwai3-3/+32
commit 132d358b183ac6ad8b3fea32ad5e0663456d18d1 upstream. The SYSEX event delivery in OSS sequencer emulation assumed that the event is encoded in the variable-length data with the straight buffering. This was the normal behavior in the past, but during the development, the chained buffers were introduced for carrying more data, while the OSS code was left intact. As a result, when a SYSEX event with the chained buffer data is passed to OSS sequencer port, it may end up with the wrong memory access, as if it were having a too large buffer. This patch addresses the bug, by applying the buffer data expansion by the generic snd_seq_dump_var_event() helper function. Reported-by: syzbot <syzkaller@googlegroups.com> Reported-by: Mark Salyzyn <salyzyn@android.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-01-01ALSA: timer: Limit max instances per timerTakashi Iwai2-13/+55
commit 9b7d869ee5a77ed4a462372bb89af622e705bfb8 upstream. Currently we allow unlimited number of timer instances, and it may bring the system hogging way too much CPU when too many timer instances are opened and processed concurrently. This may end up with a soft-lockup report as triggered by syzkaller, especially when hrtimer backend is deployed. Since such insane number of instances aren't demanded by the normal use case of ALSA sequencer and it merely opens a risk only for abuse, this patch introduces the upper limit for the number of instances per timer backend. As default, it's set to 1000, but for the fine-grained timer like hrtimer, it's set to 100. Reported-by: syzbot Tested-by: Jérôme Glisse <jglisse@redhat.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-01-01ALSA: timer: Protect the whole snd_timer_close() with open raceTakashi Iwai1-27/+21
commit 9984d1b5835ca29fc7025186a891ee7398d21cc7 upstream. In order to make the open/close more robust, widen the register_mutex protection over the whole snd_timer_close() function. Also, the close procedure is slightly shuffled to be in the safer order, as well as a few code refactoring. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-01-01ALSA: seq: Fix nested rwsem annotation for lockdep splatTakashi Iwai1-1/+1
commit 1f20f9ff57ca23b9f5502fca85ce3977e8496cb1 upstream. syzkaller reported the lockdep splat due to the possible deadlock of grp->list_mutex of each sequencer client object. Actually this is rather a false-positive report due to the missing nested lock annotations. The sequencer client may deliver the event directly to another client which takes another own lock. For addressing this issue, this patch replaces the simple down_read() with down_read_nested(). As a lock subclass, the already existing "hop" can be re-used, which indicates the depth of the call. Reference: http://lkml.kernel.org/r/089e082686ac9b482e055c832617@google.com Reported-by: syzbot <bot+7feb8de6b4d6bf810cf098bef942cc387e79d0ad@syzkaller.appspotmail.com> Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-01-01ALSA: timer: Add missing mutex lock for compat ioctlsTakashi Iwai1-2/+15
commit 79fb0518fec8c8b4ea7f1729f54f293724b3dbb0 upstream. The races among ioctl and other operations were protected by the commit af368027a49a ("ALSA: timer: Fix race among timer ioctls") and later fixes, but one code path was forgotten in the scenario: the 32bit compat ioctl. As syzkaller recently spotted, a very similar use-after-free may happen with the combination of compat ioctls. The fix is simply to apply the same ioctl_lock to the compat_ioctl callback, too. Fixes: af368027a49a ("ALSA: timer: Fix race among timer ioctls") Reference: http://lkml.kernel.org/r/089e082686ac9b482e055c832617@google.com Reported-by: syzbot <bot+e5f3c9783e7048a74233054febbe9f1bdf54b6da@syzkaller.appspotmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2018-01-01ALSA: seq: Fix copy_from_user() call inside lockTakashi Iwai1-8/+19
commit 5803b023881857db32ffefa0d269c90280a67ee0 upstream. The event handler in the virmidi sequencer code takes a read-lock for the linked list traverse, while it's calling snd_seq_dump_var_event() in the loop. The latter function may expand the user-space data depending on the event type. It eventually invokes copy_from_user(), which might be a potential dead-lock. The sequencer core guarantees that the user-space data is passed only with atomic=0 argument, but snd_virmidi_dev_receive_event() ignores it and always takes read-lock(). For avoiding the problem above, this patch introduces rwsem for non-atomic case, while keeping rwlock for atomic case. Also while we're at it: the superfluous irq flags is dropped in snd_virmidi_input_open(). Reported-by: Jia-Ju Bai <baijiaju1990@163.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>