diff options
| author | Takashi Iwai <tiwai@suse.de> | 2010-04-13 05:33:54 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2010-04-13 06:01:14 -0400 |
| commit | d97e1b78239c7e7e441088e0b644bd3b076002e6 (patch) | |
| tree | b05b5085bea932662ce60061d5b4b93834683327 /sound/drivers/opl4 | |
| parent | 24e4a1211f691fc671de44685430dbad757d8487 (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/drivers/opl4')
| -rw-r--r-- | sound/drivers/opl4/opl4_proc.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index eb72814dfd5f..210b89de06d7 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c | |||
| @@ -55,25 +55,18 @@ static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry, | |||
| 55 | size_t count, loff_t pos) | 55 | size_t count, loff_t pos) |
| 56 | { | 56 | { |
| 57 | struct snd_opl4 *opl4 = entry->private_data; | 57 | struct snd_opl4 *opl4 = entry->private_data; |
| 58 | long size; | ||
| 59 | char* buf; | 58 | char* buf; |
| 60 | 59 | ||
| 61 | size = count; | 60 | buf = vmalloc(count); |
| 62 | if (pos + size > entry->size) | 61 | if (!buf) |
| 63 | size = entry->size - pos; | 62 | return -ENOMEM; |
| 64 | if (size > 0) { | 63 | snd_opl4_read_memory(opl4, buf, pos, count); |
| 65 | buf = vmalloc(size); | 64 | if (copy_to_user(_buf, buf, count)) { |
| 66 | if (!buf) | ||
| 67 | return -ENOMEM; | ||
| 68 | snd_opl4_read_memory(opl4, buf, pos, size); | ||
| 69 | if (copy_to_user(_buf, buf, size)) { | ||
| 70 | vfree(buf); | ||
| 71 | return -EFAULT; | ||
| 72 | } | ||
| 73 | vfree(buf); | 65 | vfree(buf); |
| 74 | return size; | 66 | return -EFAULT; |
| 75 | } | 67 | } |
| 76 | return 0; | 68 | vfree(buf); |
| 69 | return count; | ||
| 77 | } | 70 | } |
| 78 | 71 | ||
| 79 | static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, | 72 | static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, |
| @@ -83,25 +76,18 @@ static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, | |||
| 83 | size_t count, size_t pos) | 76 | size_t count, size_t pos) |
| 84 | { | 77 | { |
| 85 | struct snd_opl4 *opl4 = entry->private_data; | 78 | struct snd_opl4 *opl4 = entry->private_data; |
| 86 | long size; | ||
| 87 | char *buf; | 79 | char *buf; |
| 88 | 80 | ||
| 89 | size = count; | 81 | buf = vmalloc(count); |
| 90 | if (pos + size > entry->size) | 82 | if (!buf) |
| 91 | size = entry->size - pos; | 83 | return -ENOMEM; |
| 92 | if (size > 0) { | 84 | if (copy_from_user(buf, _buf, count)) { |
| 93 | buf = vmalloc(size); | ||
| 94 | if (!buf) | ||
| 95 | return -ENOMEM; | ||
| 96 | if (copy_from_user(buf, _buf, size)) { | ||
| 97 | vfree(buf); | ||
| 98 | return -EFAULT; | ||
| 99 | } | ||
| 100 | snd_opl4_write_memory(opl4, buf, pos, size); | ||
| 101 | vfree(buf); | 85 | vfree(buf); |
| 102 | return size; | 86 | return -EFAULT; |
| 103 | } | 87 | } |
| 104 | return 0; | 88 | snd_opl4_write_memory(opl4, buf, pos, count); |
| 89 | vfree(buf); | ||
| 90 | return count; | ||
| 105 | } | 91 | } |
| 106 | 92 | ||
| 107 | static loff_t snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, | 93 | static loff_t snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, |
