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, |