aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-10-29 06:02:04 -0400
committerTakashi Iwai <tiwai@suse.de>2017-10-31 03:28:16 -0400
commit79fb0518fec8c8b4ea7f1729f54f293724b3dbb0 (patch)
tree18d39bf1e0f6241a4ec148415b423e1f3f940251 /sound/core
parentf265788c336979090ac80b9ae173aa817c4fe40d (diff)
ALSA: timer: Add missing mutex lock for compat ioctls
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> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/timer_compat.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index 6a437eb66115..59127b6ef39e 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -133,7 +133,8 @@ enum {
133#endif /* CONFIG_X86_X32 */ 133#endif /* CONFIG_X86_X32 */
134}; 134};
135 135
136static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 136static long __snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
137 unsigned long arg)
137{ 138{
138 void __user *argp = compat_ptr(arg); 139 void __user *argp = compat_ptr(arg);
139 140
@@ -153,7 +154,7 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
153 case SNDRV_TIMER_IOCTL_PAUSE: 154 case SNDRV_TIMER_IOCTL_PAUSE:
154 case SNDRV_TIMER_IOCTL_PAUSE_OLD: 155 case SNDRV_TIMER_IOCTL_PAUSE_OLD:
155 case SNDRV_TIMER_IOCTL_NEXT_DEVICE: 156 case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
156 return snd_timer_user_ioctl(file, cmd, (unsigned long)argp); 157 return __snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
157 case SNDRV_TIMER_IOCTL_GPARAMS32: 158 case SNDRV_TIMER_IOCTL_GPARAMS32:
158 return snd_timer_user_gparams_compat(file, argp); 159 return snd_timer_user_gparams_compat(file, argp);
159 case SNDRV_TIMER_IOCTL_INFO32: 160 case SNDRV_TIMER_IOCTL_INFO32:
@@ -167,3 +168,15 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
167 } 168 }
168 return -ENOIOCTLCMD; 169 return -ENOIOCTLCMD;
169} 170}
171
172static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
173 unsigned long arg)
174{
175 struct snd_timer_user *tu = file->private_data;
176 long ret;
177
178 mutex_lock(&tu->ioctl_lock);
179 ret = __snd_timer_user_ioctl_compat(file, cmd, arg);
180 mutex_unlock(&tu->ioctl_lock);
181 return ret;
182}