diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2016-03-23 02:03:59 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-03-23 10:06:16 +0300 |
commit | 91d2178e26fdc806f33063f9df5904a48e3b6aeb (patch) | |
tree | bba54fcb578a5fc30a8b4f953cf2e98d628786da /sound/core/timer.c | |
parent | c64c1437afb14ebc900e40910f31ffb20bf652ad (diff) | |
download | linux-91d2178e26fdc806f33063f9df5904a48e3b6aeb.tar.xz |
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>
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r-- | sound/core/timer.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c index aa1b15c155d1..ea4d999113ef 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1502,17 +1502,13 @@ static int snd_timer_user_ginfo(struct file *file, return err; } -static int snd_timer_user_gparams(struct file *file, - struct snd_timer_gparams __user *_gparams) +static int timer_set_gparams(struct snd_timer_gparams *gparams) { - struct snd_timer_gparams gparams; struct snd_timer *t; int err; - if (copy_from_user(&gparams, _gparams, sizeof(gparams))) - return -EFAULT; mutex_lock(®ister_mutex); - t = snd_timer_find(&gparams.tid); + t = snd_timer_find(&gparams->tid); if (!t) { err = -ENODEV; goto _error; @@ -1525,12 +1521,22 @@ static int snd_timer_user_gparams(struct file *file, err = -ENOSYS; goto _error; } - err = t->hw.set_period(t, gparams.period_num, gparams.period_den); + err = t->hw.set_period(t, gparams->period_num, gparams->period_den); _error: mutex_unlock(®ister_mutex); return err; } +static int snd_timer_user_gparams(struct file *file, + struct snd_timer_gparams __user *_gparams) +{ + struct snd_timer_gparams gparams; + + if (copy_from_user(&gparams, _gparams, sizeof(gparams))) + return -EFAULT; + return timer_set_gparams(&gparams); +} + static int snd_timer_user_gstatus(struct file *file, struct snd_timer_gstatus __user *_gstatus) { |