Commit Graph

1165 Commits

Author SHA1 Message Date
Charles Keepax 875f6fffa2 ALSA: compress: Replace complex if statement with switch
A switch statement looks a bit cleaner than an if statement
spread over 3 lines, as such update this to a switch.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-09 17:35:50 +02:00
Charles Keepax 1d03f2bd56 ALSA: compress: Fix poll error return codes
We can't return a negative error code from the poll callback the return
type is unsigned and is checked against the poll specific flags we need
to return POLLERR if we encounter an error.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-09 17:35:43 +02:00
Charles Keepax 5bd05390ff ALSA: compress: Remove pointless NULL check
stream can't be NULL here as we have just taken the address of it, so no
need for the check.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-09 17:35:32 +02:00
Charles Keepax 0b92b0cdbe ALSA: compress: Use snd_compr_get_poll on error path
We have a function that returns the appropriate flags for the stream
direction, so we should use it.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-09 17:35:14 +02:00
Charles Keepax e099aeea63 ALSA: pcm: Fix poll error return codes
We can't return a negative error code from the poll callback the return
type is unsigned and is checked against the poll specific flags we need
to return POLLERR if we encounter an error.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-09 17:34:49 +02:00
Kangjie Lu e4ec8cc803 ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt
The stack object “r1” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-08 11:36:17 +02:00
Kangjie Lu 9a47e9cff9 ALSA: timer: Fix leak in events via snd_timer_user_ccallback
The stack object “r1” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-08 11:36:07 +02:00
Kangjie Lu cec8f96e49 ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS
The stack object “tread” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kjlu@gatech.edu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-05-08 11:31:27 +02:00
Takashi Iwai d2c5cf88d5 ALSA: hrtimer: Handle start/stop more properly
This patch tries to address the still remaining issues in ALSA hrtimer
driver:
- Spurious use-after-free was detected in hrtimer callback
- Incorrect rescheduling due to delayed start
- WARN_ON() is triggered in hrtimer_forward() invoked in hrtimer
  callback

The first issue happens only when the new timer is scheduled even
while hrtimer is being closed.  It's related with the second and third
items; since ALSA timer core invokes hw.start callback during hrtimer
interrupt, this may result in the explicit call of hrtimer_start().

Also, the similar problem is seen for the stop; ALSA timer core
invokes hw.stop callback even in the hrtimer handler, too.  Since we
must not call the synced hrtimer_cancel() in such a context, it's just
a hrtimer_try_to_cancel() call that doesn't properly work.

Another culprit of the second and third items is the call of
hrtimer_forward_now() before snd_timer_interrupt().  The timer->stick
value may change during snd_timer_interrupt() call, but this
possibility is ignored completely.

For covering these subtle and messy issues, the following changes have
been done in this patch:
- A new flag, in_callback, is introduced in the private data to
  indicate that the hrtimer handler is being processed.
- Both start and stop callbacks skip when called from (during)
  in_callback flag.
- The hrtimer handler returns properly HRTIMER_RESTART and NORESTART
  depending on the running state now.
- The hrtimer handler reprograms the expiry properly after
  snd_timer_interrupt() call, instead of before.
- The close callback clears running flag and sets in_callback flag
  to block any further start/stop calls.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-04-26 09:34:40 +02:00
Alexandre Belloni 34ce71a96d ALSA: timer: remove legacy rtctimer
There are no users of rtctimer left. Remove its code as this is the
in-kernel user of the legacy PC RTC driver that will hopefully be removed
at some point.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-04-25 10:41:46 +02:00
Takashi Iwai 3aa02cb664 ALSA: pcm : Call kill_fasync() in stream lock
Currently kill_fasync() is called outside the stream lock in
snd_pcm_period_elapsed().  This is potentially racy, since the stream
may get released even during the irq handler is running.  Although
snd_pcm_release_substream() calls snd_pcm_drop(), this doesn't
guarantee that the irq handler finishes, thus the kill_fasync() call
outside the stream spin lock may be invoked after the substream is
detached, as recently reported by KASAN.

As a quick workaround, move kill_fasync() call inside the stream
lock.  The fasync is rarely used interface, so this shouldn't have a
big impact from the performance POV.

Ideally, we should implement some sync mechanism for the proper finish
of stream and irq handler.  But this oneliner should suffice for most
cases, so far.

Reported-by: Baozeng Ding <sploving1@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-04-14 18:02:37 +02:00
Takashi Iwai 4a07083ed6 ALSA: timer: Use mod_timer() for rearming the system timer
ALSA system timer backend stops the timer via del_timer() without sync
and leaves del_timer_sync() at the close instead.  This is because of
the restriction by the design of ALSA timer: namely, the stop callback
may be called from the timer handler, and calling the sync shall lead
to a hangup.  However, this also triggers a kernel BUG() when the
timer is rearmed immediately after stopping without sync:
 kernel BUG at kernel/time/timer.c:966!
 Call Trace:
  <IRQ>
  [<ffffffff8239c94e>] snd_timer_s_start+0x13e/0x1a0
  [<ffffffff8239e1f4>] snd_timer_interrupt+0x504/0xec0
  [<ffffffff8122fca0>] ? debug_check_no_locks_freed+0x290/0x290
  [<ffffffff8239ec64>] snd_timer_s_function+0xb4/0x120
  [<ffffffff81296b72>] call_timer_fn+0x162/0x520
  [<ffffffff81296add>] ? call_timer_fn+0xcd/0x520
  [<ffffffff8239ebb0>] ? snd_timer_interrupt+0xec0/0xec0
  ....

It's the place where add_timer() checks the pending timer.  It's clear
that this may happen after the immediate restart without sync in our
cases.

So, the workaround here is just to use mod_timer() instead of
add_timer().  This looks like a band-aid fix, but it's a right move,
as snd_timer_interrupt() takes care of the continuous rearm of timer.

Reported-by: Jiri Slaby <jslaby@suse.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-04-01 12:28:16 +02:00
Takashi Sakamoto 91d2178e26 ALSA: timer: fix gparams ioctl compatibility for different architectures
'struct snd_timer_gparams' includes some members with 'unsigned long',
therefore its size differs depending on data models of architecture. As
a result, x86/x32 applications fail to execute ioctl(2) with
SNDRV_TIMER_GPARAMS command on x86_64 machine.

This commit fixes this bug by adding a pair of structure and ioctl
command for the compatibility.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-23 08:06:16 +01:00
Takashi Sakamoto 6f02174418 ALSA: ctl: change return value in compatibility layer so that it's the same value in core implementation
In control compatibility layer, when no elements are found by
ELEM_READ/ELEM_WRITE ioctl commands, ENXIO is returned. On the other hand,
in core implementation, ENOENT is returned. This is not good for
ALSA ctl applications.

This commit changes the return value from the compatibility layer so
that the same value is returned.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-17 14:11:36 +01:00
Takashi Iwai ca80e26a59 ASoC: Updates for v4.6
The main thing in terms of the core this time around has been some
 additional framework work for dynamic topologies (though we *still*
 don't appear to have a stable ABI for the topology code, it's probably
 worth considering if this will ever happen...).  Otherwise the work has
 almost all been in the drivers:
 
  - HDMI support for Sky Lake, along with other fixes and enhancements
    for the Intel drivers.
  - Lots of improvements to the Renesas drivers.
  - Capture support for Qualcomm drivers.
  - Support for TI DaVinci DRA7xxx devices.
  - New machine drivers for Freescale systems with Cirrus CODECs,
    Mediatek systems with RT5650 CODECs.
  - New CPU drivers for Allwinner S/PDIF controllers
  - New CODEC drivers for Maxim MAX9867 and MAX98926 and Realtek RT5514.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJW5qP+AAoJECTWi3JdVIfQJhAH/RKv268gjE07uJ8jeGAT7uY4
 XM19VmUl7ZOlphctfr/I+1hRwo+mgGN4LSfKnXxsPk9Uq/WJUok4D7MjDN33jeX/
 heK9WAO8zXkgi9n2lhGI/z9uE76kPA/Qw0aEYcbmA6bDc4GF3AKphnByh6kDShtE
 BfblofsFaDywA09XQ2lh3wW0rZtJ51tQUeOi35UADyEPzQetzN+xiY85Bkia5BEt
 Yjp37nLJET8Gk0r9snE2MpACUkEyw7CiPXCjkK47npia41LVnTarZAq5+JmfKygg
 YV2EnC3AFYthhjZPfmO1usI2vJVwkN40nGrKipH2QX08TanK8r2qiTsmGADNX4E=
 =0/1R
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v4.6

The main thing in terms of the core this time around has been some
additional framework work for dynamic topologies (though we *still*
don't appear to have a stable ABI for the topology code, it's probably
worth considering if this will ever happen...).  Otherwise the work has
almost all been in the drivers:

 - HDMI support for Sky Lake, along with other fixes and enhancements
   for the Intel drivers.
 - Lots of improvements to the Renesas drivers.
 - Capture support for Qualcomm drivers.
 - Support for TI DaVinci DRA7xxx devices.
 - New machine drivers for Freescale systems with Cirrus CODECs,
   Mediatek systems with RT5650 CODECs.
 - New CPU drivers for Allwinner S/PDIF controllers
 - New CODEC drivers for Maxim MAX9867 and MAX98926 and Realtek RT5514.
2016-03-14 14:03:29 +01:00
Mark Brown 89595f5e29 Merge remote-tracking branch 'asoc/topic/core-pcm' into asoc-next 2016-03-13 15:16:21 +07:00
Takashi Iwai 0ab1ace856 ALSA: pcm: Avoid "BUG:" string for warnings again
The commit [d507941beb1e: ALSA: pcm: Correct PCM BUG error message]
made the warning prefix back to "BUG:" due to its previous wrong
prefix.  But a kernel message containing "BUG:" seems taken as an Oops
message wrongly by some brain-dead daemons, and it annoys users in the
end.  Instead of teaching daemons, change the string again to a more
reasonable one.

Fixes: 507941beb1e ('ALSA: pcm: Correct PCM BUG error message')
Cc: <stable@vger.kernel.org> # v3.19+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-10 21:00:17 +01:00
Martin Koegler a1ce94d03b ALSA: seq: Provide card number / PID via sequencer client info
rawmidi devices expose the card number via IOCTLs, which allows to
find the corresponding device in sysfs.

The sequencer provides no identifing data. Chromium works around this
issue by scanning rawmidi as well as sequencer devices and matching
them by using assumtions, how the kernel register sequencer devices.

This changes adds support for exposing the card number for kernel clients
as well as the PID for user client.

The minor of the API version is changed to distinguish between the zero
initialised reserved field and card number 0.

[minor coding style fixes by tiwai]

Signed-off-by: Martin Koegler <martin.koegler@chello.at>
Acked-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-08 10:52:52 +01:00
Vinod Koul cdb1ee3f6c ALSA: compress: fix more typos
More inspection of code revealed few more typos so fix them as well

Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-04 21:55:36 +01:00
Vinod Koul 41eb94fd26 ALSA: compress: fix some typos
Found few typos while looking at code, so fix them

Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-04 17:49:42 +01:00
Vinod Koul 862bca5d16 ALSA: compress: Add SNDRV_PCM_STATE_PREPARED state explanation
Stream states were explained in the code comments but
SNDRV_PCM_STATE_PREPARED was missed so add it

Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-04 17:49:42 +01:00
Eric Laurent 35383a2412 ALSA: compress: allow writes in SNDRV_PCM_STATE_PREPARED state
Allow writes in SNDRV_PCM_STATE_PREPARED state so that more
than one buffer fragment can be written from user space
before calling SNDRV_COMPRESS_START.

Signed-off-by: Eric Laurent <elaurent@google.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-04 14:50:46 +01:00
Takashi Iwai 6defb60ae4 Merge branch 'for-linus' into for-next
Resolved the conflicts with the latest HDA HDMI fixes.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-04 08:41:41 +01:00
Takashi Iwai 197b958c1e ALSA: seq: oss: Don't drain at closing a client
The OSS sequencer client tries to drain the pending events at
releasing.  Unfortunately, as spotted by syzkaller fuzzer, this may
lead to an unkillable process state when the event has been queued at
the far future.  Since the process being released can't be signaled
any longer, it remains and waits for the echo-back event in that far
future.

Back to history, the draining feature was implemented at the time we
misinterpreted POSIX definition for blocking file operation.
Actually, such a behavior is superfluous at release, and we should
just release the device as is instead of keeping it up forever.

This patch just removes the draining call that may block the release
for too long time unexpectedly.

BugLink: http://lkml.kernel.org/r/CACT4Y+Y4kD-aBGj37rf-xBw9bH3GMU6P+MYg4W1e-s-paVD2pg@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-03-01 20:26:40 +01:00
Takashi Iwai 97128577f3 Merge branch 'for-linus' into for-next
Back-merge of for-linus branch for further API/ABI cleanups.
2016-02-29 18:08:34 +01:00
Takashi Iwai b24e7ad1fd ALSA: timer: Fix ioctls for X32 ABI
X32 ABI takes the 64bit timespec, thus the timer user status ioctl becomes
incompatible with IA32.  This results in NOTTY error when the ioctl is
issued.

Meanwhile, this struct in X32 is essentially identical with the one in
X86-64, so we can just bypassing to the existing code for this
specific compat ioctl.

Cc: <stable@vger.kernel.org> # v3.4+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-28 17:49:30 +01:00
Takashi Iwai 3a72494ac2 ALSA: timer: Fix broken compat timer user status ioctl
The timer user status compat ioctl returned the bogus struct used for
64bit architectures instead of the 32bit one.  This patch addresses
it to return the proper struct.

Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-28 17:48:11 +01:00
Takashi Iwai 2251fbbc15 ALSA: rawmidi: Fix ioctls X32 ABI
Like the previous fixes for ctl and PCM, we need a fix for
incompatible X32 ABI regarding the rawmidi: namely, struct
snd_rawmidi_status has the timespec, and the size and the alignment on
X32 differ from IA32.

This patch fixes the incompatible ioctl for X32.

Cc: <stable@vger.kernel.org> # v3.4+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-28 17:44:51 +01:00
Takashi Iwai dd7e3f8052 ALSA: rawmidi: Use comapt_put_timespec()
Instead of open-coding, use the existing helper to copy a 32bit
timespec from/to 64bit.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-28 17:44:48 +01:00
Takashi Iwai 513ace79b6 ALSA: pcm: Fix ioctls for X32 ABI
X32 ABI uses the 64bit timespec in addition to 64bit alignment of
64bit values.  This leads to incompatibilities in some PCM ioctls
involved with snd_pcm_channel_info, snd_pcm_status and
snd_pcm_sync_ptr structs.  Fix the PCM compat ABI for these ioctls
like the previous commit for ctl API.

Reported-by: Steven Newbury <steve@snewbury.org.uk>
Cc: <stable@vger.kernel.org> # v3.4+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-28 17:44:35 +01:00
Takashi Iwai 6236d8bb2a ALSA: ctl: Fix ioctls for X32 ABI
The X32 ABI takes the same alignment like x86-64, and this may result
in the incompatible struct size from ia32.  Unfortunately, we hit this
in some control ABI: struct snd_ctl_elem_value differs between them
due to the position of 64bit variable array.  This ends up with the
unknown ioctl (ENOTTY) error.

The fix is to add the compat entries for the new aligned struct.

Reported-and-tested-by: Steven Newbury <steve@snewbury.org.uk>
Cc: <stable@vger.kernel.org> # v3.4+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-28 17:43:54 +01:00
Takashi Iwai d61b04f801 Merge branch 'for-linus' into for-next 2016-02-26 20:26:09 +01:00
Takashi Iwai fe0d128c57 ALSA: jack: Allow building the jack layer without input device
Since the recent integration of kctl jack and input jack layers, we
can basically build the jack layer even without input devices.  That
is, the jack layer itself can be built with conditional to enable the
input device support or not, while the users may enable always
CONFIG_SND_JACK unconditionally.

For achieving it, this patch changes the following:
- A new Kconfig, CONFIG_SND_JACK_INPUT_DEV, was introduced to indicate
  whether the jack layer supports the input device,
- A few items in snd_jack struct and relevant codes are conditionally
  built upon CONFIG_SND_JACK_INPUT_DEV,
- The users of CONFIG_SND_JACK drop the messy dependency on
  CONFIG_INPUT.

This change also automagically fixes a potential bug in HD-audio
driver Arnd reported, where the NULL or uninitialized jack instance is
dereferenced.

Reported-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-23 09:03:07 +01:00
Takashi Iwai 67ec1072b0 ALSA: pcm: Fix rwsem deadlock for non-atomic PCM stream
A non-atomic PCM stream may take snd_pcm_link_rwsem rw semaphore twice
in the same code path, e.g. one in snd_pcm_action_nonatomic() and
another in snd_pcm_stream_lock().  Usually this is OK, but when a
write lock is issued between these two read locks, the problem
happens: the write lock is blocked due to the first reade lock, and
the second read lock is also blocked by the write lock.  This
eventually deadlocks.

The reason is the way rwsem manages waiters; it's queued like FIFO, so
even if the writer itself doesn't take the lock yet, it blocks all the
waiters (including reads) queued after it.

As a workaround, in this patch, we replace the standard down_write()
with an spinning loop.  This is far from optimal, but it's good
enough, as the spinning time is supposed to be relatively short for
normal PCM operations, and the code paths requiring the write lock
aren't called so often.

Reported-by: Vinod Koul <vinod.koul@intel.com>
Tested-by: Ramesh Babu <ramesh.babu@intel.com>
Cc: <stable@vger.kernel.org> # v3.18+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-18 11:27:52 +01:00
Takashi Iwai 13d5e5d472 ALSA: seq: Fix double port list deletion
The commit [7f0973e973cd: ALSA: seq: Fix lockdep warnings due to
double mutex locks] split the management of two linked lists (source
and destination) into two individual calls for avoiding the AB/BA
deadlock.  However, this may leave the possible double deletion of one
of two lists when the counterpart is being deleted concurrently.
It ends up with a list corruption, as revealed by syzkaller fuzzer.

This patch fixes it by checking the list emptiness and skipping the
deletion and the following process.

BugLink: http://lkml.kernel.org/r/CACT4Y+bay9qsrz6dQu31EcGaH9XwfW7o3oBzSQUG9fMszoh=Sg@mail.gmail.com
Fixes: 7f0973e973 ('ALSA: seq: Fix lockdep warnings due to 'double mutex locks)
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-16 14:37:19 +01:00
Takashi Iwai d99a36f472 ALSA: seq: Fix leak of pool buffer at concurrent writes
When multiple concurrent writes happen on the ALSA sequencer device
right after the open, it may try to allocate vmalloc buffer for each
write and leak some of them.  It's because the presence check and the
assignment of the buffer is done outside the spinlock for the pool.

The fix is to move the check and the assignment into the spinlock.

(The current implementation is suboptimal, as there can be multiple
 unnecessary vmallocs because the allocation is done before the check
 in the spinlock.  But the pool size is already checked beforehand, so
 this isn't a big problem; that is, the only possible path is the
 multiple writes before any pool assignment, and practically seen, the
 current coverage should be "good enough".)

The issue was triggered by syzkaller fuzzer.

BugLink: http://lkml.kernel.org/r/CACT4Y+bSzazpXNvtAr=WXaL8hptqjHwqEyFA+VN2AWEx=aurkg@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-15 16:26:52 +01:00
Takashi Iwai f65e0d2998 ALSA: timer: Call notifier in the same spinlock
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>
2016-02-12 15:07:31 +01:00
Takashi Iwai 9984d1b583 ALSA: timer: Protect the whole snd_timer_close() with open race
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>
2016-02-10 12:56:07 +01:00
Takashi Iwai 4dff5c7b70 ALSA: timer: Fix race at concurrent reads
snd_timer_user_read() has a potential race among parallel reads, as
qhead and qused are updated outside the critical section due to
copy_to_user() calls.  Move them into the critical section, and also
sanitize the relevant code a bit.

Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-09 12:23:42 +01:00
Takashi Iwai ed8b1d6d2c ALSA: timer: Fix race between stop and interrupt
A slave timer element also unlinks at snd_timer_stop() but it takes
only slave_active_lock.  When a slave is assigned to a master,
however, this may become a race against the master's interrupt
handling, eventually resulting in a list corruption.  The actual bug
could be seen with a syzkaller fuzzer test case in BugLink below.

As a fix, we need to take timeri->timer->lock when timer isn't NULL,
i.e. assigned to a master, while the assignment to a master itself is
protected by slave_active_lock.

BugLink: http://lkml.kernel.org/r/CACT4Y+Y_Bm+7epAb=8Wi=AaWd+DYS7qawX52qxdCfOfY49vozQ@mail.gmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-09 12:02:32 +01:00
Takashi Iwai 117159f0b9 ALSA: timer: Fix wrong instance passed to slave callbacks
In snd_timer_notify1(), the wrong timer instance was passed for slave
ccallback function.  This leads to the access to the wrong data when
an incompatible master is handled (e.g. the master is the sequencer
timer and the slave is a user timer), as spotted by syzkaller fuzzer.

This patch fixes that wrong assignment.

BugLink: http://lkml.kernel.org/r/CACT4Y+Y_Bm+7epAb=8Wi=AaWd+DYS7qawX52qxdCfOfY49vozQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-08 17:40:08 +01:00
Mengdong Lin 3bdff244a2 ALSA: pcm: Add snd_pcm_rate_range_to_bits()
This helper function can convert a given sample rate range to
SNDRV_PCM_RATE_xxx bits.

Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
Acked-by: Takashi Iwai <tiwai@suse.de>
Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2016-02-05 18:49:00 +00:00
Takashi Iwai 094fd3be87 ALSA: timer: Fix leftover link at closing
In ALSA timer core, the active timer instance is managed in
active_list linked list.  Each element is added / removed dynamically
at timer start, stop and in timer interrupt.  The problem is that
snd_timer_interrupt() has a thinko and leaves the element in
active_list when it's the last opened element.  This eventually leads
to list corruption or use-after-free error.

This hasn't been revealed because we used to delete the list forcibly
in snd_timer_stop() in the past.  However, the recent fix avoids the
double-stop behavior (in commit [f784beb75ce8: ALSA: timer: Fix link
corruption due to double start or stop]), and this leak hits reality.

This patch fixes the link management in snd_timer_interrupt().  Now it
simply unlinks no matter which stream is.

BugLink: http://lkml.kernel.org/r/CACT4Y+Yy2aukHP-EDp8-ziNqNNmb-NTf=jDWXMP7jB8HDa2vng@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-04 17:19:09 +01:00
Takashi Iwai 7f0973e973 ALSA: seq: Fix lockdep warnings due to double mutex locks
The port subscription code uses double mutex locks for source and
destination ports, and this may become racy once when wrongly set up.
It leads to lockdep warning splat, typically triggered by fuzzer like
syzkaller, although the actual deadlock hasn't been seen, so far.

This patch simplifies the handling by reducing to two single locks, so
that no lockdep warning will be trigger any longer.

By splitting to two actions, a still-in-progress element shall be
added in one list while handling another.  For ignoring this element,
a new check is added in deliver_to_subscribers().

Along with it, the code to add/remove the subscribers list element was
cleaned up and refactored.

BugLink: http://lkml.kernel.org/r/CACT4Y+aKQXV7xkBW9hpQbzaDO7LrUvohxWh-UwMxXjDy-yBD=A@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-03 14:51:51 +01:00
Takashi Iwai 81f577542a ALSA: rawmidi: Fix race at copying & updating the position
The rawmidi read and write functions manage runtime stream status
such as runtime->appl_ptr and runtime->avail.  These point where to
copy the new data and how many bytes have been copied (or to be
read).  The problem is that rawmidi read/write call copy_from_user()
or copy_to_user(), and the runtime spinlock is temporarily unlocked
and relocked while copying user-space.  Since the current code
advances and updates the runtime status after the spin unlock/relock,
the copy and the update may be asynchronous, and eventually
runtime->avail might go to a negative value when many concurrent
accesses are done.  This may lead to memory corruption in the end.

For fixing this race, in this patch, the status update code is
performed in the same lock before the temporary unlock.  Also, the
spinlock is now taken more widely in snd_rawmidi_kernel_read1() for
protecting more properly during the whole operation.

BugLink: http://lkml.kernel.org/r/CACT4Y+b-dCmNf1GpgPKfDO0ih+uZCL2JV4__j-r1kdhPLSgQCQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-03 14:51:42 +01:00
Takashi Iwai 06ab30034e ALSA: rawmidi: Make snd_rawmidi_transmit() race-free
A kernel WARNING in snd_rawmidi_transmit_ack() is triggered by
syzkaller fuzzer:
  WARNING: CPU: 1 PID: 20739 at sound/core/rawmidi.c:1136
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff82999e2d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
 [<ffffffff81352089>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
 [<ffffffff813522b9>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
 [<ffffffff84f80bd5>] snd_rawmidi_transmit_ack+0x275/0x400 sound/core/rawmidi.c:1136
 [<ffffffff84fdb3c1>] snd_virmidi_output_trigger+0x4b1/0x5a0 sound/core/seq/seq_virmidi.c:163
 [<     inline     >] snd_rawmidi_output_trigger sound/core/rawmidi.c:150
 [<ffffffff84f87ed9>] snd_rawmidi_kernel_write1+0x549/0x780 sound/core/rawmidi.c:1223
 [<ffffffff84f89fd3>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1273
 [<ffffffff817b0323>] __vfs_write+0x113/0x480 fs/read_write.c:528
 [<ffffffff817b1db7>] vfs_write+0x167/0x4a0 fs/read_write.c:577
 [<     inline     >] SYSC_write fs/read_write.c:624
 [<ffffffff817b50a1>] SyS_write+0x111/0x220 fs/read_write.c:616
 [<ffffffff86336c36>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185

Also a similar warning is found but in another path:
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff82be2c0d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
 [<ffffffff81355139>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
 [<ffffffff81355369>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
 [<ffffffff8527e69a>] rawmidi_transmit_ack+0x24a/0x3b0 sound/core/rawmidi.c:1133
 [<ffffffff8527e851>] snd_rawmidi_transmit_ack+0x51/0x80 sound/core/rawmidi.c:1163
 [<ffffffff852d9046>] snd_virmidi_output_trigger+0x2b6/0x570 sound/core/seq/seq_virmidi.c:185
 [<     inline     >] snd_rawmidi_output_trigger sound/core/rawmidi.c:150
 [<ffffffff85285a0b>] snd_rawmidi_kernel_write1+0x4bb/0x760 sound/core/rawmidi.c:1252
 [<ffffffff85287b73>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1302
 [<ffffffff817ba5f3>] __vfs_write+0x113/0x480 fs/read_write.c:528
 [<ffffffff817bc087>] vfs_write+0x167/0x4a0 fs/read_write.c:577
 [<     inline     >] SYSC_write fs/read_write.c:624
 [<ffffffff817bf371>] SyS_write+0x111/0x220 fs/read_write.c:616
 [<ffffffff86660276>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185

In the former case, the reason is that virmidi has an open code
calling snd_rawmidi_transmit_ack() with the value calculated outside
the spinlock.   We may use snd_rawmidi_transmit() in a loop just for
consuming the input data, but even there, there is a race between
snd_rawmidi_transmit_peek() and snd_rawmidi_tranmit_ack().

Similarly in the latter case, it calls snd_rawmidi_transmit_peek() and
snd_rawmidi_tranmit_ack() separately without protection, so they are
racy as well.

The patch tries to address these issues by the following ways:
- Introduce the unlocked versions of snd_rawmidi_transmit_peek() and
  snd_rawmidi_transmit_ack() to be called inside the explicit lock.
- Rewrite snd_rawmidi_transmit() to be race-free (the former case).
- Make the split calls (the latter case) protected in the rawmidi spin
  lock.

BugLink: http://lkml.kernel.org/r/CACT4Y+YPq1+cYLkadwjWa5XjzF1_Vki1eHnVn-Lm0hzhSpu5PA@mail.gmail.com
BugLink: http://lkml.kernel.org/r/CACT4Y+acG4iyphdOZx47Nyq_VHGbpJQK-6xNpiqUjaZYqsXOGw@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-03 14:51:28 +01:00
Takashi Iwai f146357f06 ALSA: timer: Sync timer deletion at closing the system timer
ALSA timer core framework has no sync point at stopping because it's
called inside the spinlock.  Thus we need a sync point at close for
avoiding the stray timer task.  This is simply done by implementing
the close callback just calling del_timer_sync().  (It's harmless to
call it unconditionally, as the core timer itself cares of the already
deleted timer instance.)

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-03 00:15:42 +01:00
Takashi Iwai f784beb75c ALSA: timer: Fix link corruption due to double start or stop
Although ALSA timer code got hardening for races, it still causes
use-after-free error.  This is however rather a corrupted linked list,
not actually the concurrent accesses.  Namely, when timer start is
triggered twice, list_add_tail() is called twice, too.  This ends
up with the link corruption and triggers KASAN error.

The simplest fix would be replacing list_add_tail() with
list_move_tail(), but fundamentally it's the problem that we don't
check the double start/stop correctly.  So, the right fix here is to
add the proper checks to snd_timer_start() and snd_timer_stop() (and
their variants).

BugLink: http://lkml.kernel.org/r/CACT4Y+ZyPRoMQjmawbvmCEDrkBD2BQuH7R09=eOkf5ESK8kJAw@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-01 12:23:29 +01:00
Takashi Iwai 2cdc7b636d ALSA: seq: Fix yet another races among ALSA timer accesses
ALSA sequencer may open/close and control ALSA timer instance
dynamically either via sequencer events or direct ioctls.  These are
done mostly asynchronously, and it may call still some timer action
like snd_timer_start() while another is calling snd_timer_close().
Since the instance gets removed by snd_timer_close(), it may lead to
a use-after-free.

This patch tries to address such a race by protecting each
snd_timer_*() call via the existing spinlock and also by avoiding the
access to timer during close call.

BugLink: http://lkml.kernel.org/r/CACT4Y+Z6RzW5MBr-HUdV-8zwg71WQfKTdPpYGvOeS7v4cyurNQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-01 12:23:29 +01:00
Takashi Iwai b248371628 ALSA: pcm: Fix potential deadlock in OSS emulation
There are potential deadlocks in PCM OSS emulation code while
accessing read/write and mmap concurrently.  This comes from the
infamous mmap_sem usage in copy_from/to_user().  Namely,

   snd_pcm_oss_write() ->
     &runtime->oss.params_lock ->
        copy_to_user() ->
          &mm->mmap_sem
  mmap() ->
    &mm->mmap_sem ->
      snd_pcm_oss_mmap() ->
        &runtime->oss.params_lock

Since we can't avoid taking params_lock from mmap code path, use
trylock variant and aborts with -EAGAIN as a workaround of this AB/BA
deadlock.

BugLink: http://lkml.kernel.org/r/CACT4Y+bVrBKDG0G2_AcUgUQa+X91VKTeS4v+wN7BSHwHtqn3kQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2016-02-01 12:23:29 +01:00