aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-04-13 05:33:54 -0400
committerTakashi Iwai <tiwai@suse.de>2010-04-13 06:01:14 -0400
commitd97e1b78239c7e7e441088e0b644bd3b076002e6 (patch)
treeb05b5085bea932662ce60061d5b4b93834683327 /sound/pci/emu10k1
parent24e4a1211f691fc671de44685430dbad757d8487 (diff)
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,
346 struct file *file, char __user *buf, 346 struct file *file, char __user *buf,
347 size_t count, loff_t pos) 347 size_t count, loff_t pos)
348{ 348{
349 long size;
350 struct snd_emu10k1 *emu = entry->private_data; 349 struct snd_emu10k1 *emu = entry->private_data;
351 unsigned int offset; 350 unsigned int offset;
352 int tram_addr = 0; 351 int tram_addr = 0;
352 unsigned int *tmp;
353 long res;
354 unsigned int idx;
353 355
354 if (!strcmp(entry->name, "fx8010_tram_addr")) { 356 if (!strcmp(entry->name, "fx8010_tram_addr")) {
355 offset = TANKMEMADDRREGBASE; 357 offset = TANKMEMADDRREGBASE;
@@ -361,30 +363,25 @@ static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
361 } else { 363 } else {
362 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; 364 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
363 } 365 }
364 size = count; 366
365 if (pos + size > entry->size) 367 tmp = kmalloc(count + 8, GFP_KERNEL);
366 size = (long)entry->size - pos; 368 if (!tmp)
367 if (size > 0) { 369 return -ENOMEM;
368 unsigned int *tmp; 370 for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
369 long res; 371 unsigned int val;
370 unsigned int idx; 372 val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
371 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) 373 if (tram_addr && emu->audigy) {
372 return -ENOMEM; 374 val >>= 11;
373 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) 375 val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
374 if (tram_addr && emu->audigy) {
375 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
376 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
377 } else
378 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
380 res = -EFAULT;
381 else {
382 res = size;
383 } 376 }
384 kfree(tmp); 377 tmp[idx] = val;
385 return res;
386 } 378 }
387 return 0; 379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
380 res = -EFAULT;
381 else
382 res = count;
383 kfree(tmp);
384 return res;
388} 385}
389 386
390static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, 387static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,