summaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-04-13 11:33:54 +0200
committerTakashi Iwai <tiwai@suse.de>2010-04-13 12:01:14 +0200
commitd97e1b78239c7e7e441088e0b644bd3b076002e6 (patch)
treeb05b5085bea932662ce60061d5b4b93834683327 /sound/pci/emu10k1
parentALSA: info - Use standard types for info callbacks (diff)
downloadlinux-d97e1b78239c7e7e441088e0b644bd3b076002e6.tar.xz
linux-d97e1b78239c7e7e441088e0b644bd3b076002e6.zip
ALSA: info - Check file position validity in common layer
Check the validity of the file position in the common info layer before calling read or write callbacks in assumption that entry->size is set up properly to indicate the max file size. Removed the redundant checks from the callbacks as well. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r--sound/pci/emu10k1/emuproc.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 347b2415db59..bc38dd4d071f 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -346,10 +346,12 @@ static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
struct file *file, char __user *buf,
size_t count, loff_t pos)
{
- long size;
struct snd_emu10k1 *emu = entry->private_data;
unsigned int offset;
int tram_addr = 0;
+ unsigned int *tmp;
+ long res;
+ unsigned int idx;
if (!strcmp(entry->name, "fx8010_tram_addr")) {
offset = TANKMEMADDRREGBASE;
@@ -361,30 +363,25 @@ static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
} else {
offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
}
- size = count;
- if (pos + size > entry->size)
- size = (long)entry->size - pos;
- if (size > 0) {
- unsigned int *tmp;
- long res;
- unsigned int idx;
- if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL)
- return -ENOMEM;
- for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++)
- if (tram_addr && emu->audigy) {
- tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
- tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
- } else
- tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
- if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
- res = -EFAULT;
- else {
- res = size;
+
+ tmp = kmalloc(count + 8, GFP_KERNEL);
+ if (!tmp)
+ return -ENOMEM;
+ for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
+ unsigned int val;
+ val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
+ if (tram_addr && emu->audigy) {
+ val >>= 11;
+ val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
}
- kfree(tmp);
- return res;
+ tmp[idx] = val;
}
- return 0;
+ if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
+ res = -EFAULT;
+ else
+ res = count;
+ kfree(tmp);
+ return res;
}
static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,