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/core | |
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/core')
-rw-r--r-- | sound/core/info.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sound/core/info.c b/sound/core/info.c index ff968be81678..f90a6fd43fb4 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -232,10 +232,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, | |||
232 | return -EFAULT; | 232 | return -EFAULT; |
233 | break; | 233 | break; |
234 | case SNDRV_INFO_CONTENT_DATA: | 234 | case SNDRV_INFO_CONTENT_DATA: |
235 | if (entry->c.ops->read) | 235 | if (pos >= entry->size) |
236 | return 0; | ||
237 | if (entry->c.ops->read) { | ||
238 | size = entry->size - pos; | ||
239 | size = min(count, size); | ||
236 | size = entry->c.ops->read(entry, | 240 | size = entry->c.ops->read(entry, |
237 | data->file_private_data, | 241 | data->file_private_data, |
238 | file, buffer, count, pos); | 242 | file, buffer, size, pos); |
243 | } | ||
239 | break; | 244 | break; |
240 | } | 245 | } |
241 | if ((ssize_t) size > 0) | 246 | if ((ssize_t) size > 0) |
@@ -282,10 +287,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer | |||
282 | size = count; | 287 | size = count; |
283 | break; | 288 | break; |
284 | case SNDRV_INFO_CONTENT_DATA: | 289 | case SNDRV_INFO_CONTENT_DATA: |
285 | if (entry->c.ops->write) | 290 | if (entry->c.ops->write && count > 0) { |
291 | size_t maxsize = entry->size - pos; | ||
292 | count = min(count, maxsize); | ||
286 | size = entry->c.ops->write(entry, | 293 | size = entry->c.ops->write(entry, |
287 | data->file_private_data, | 294 | data->file_private_data, |
288 | file, buffer, count, pos); | 295 | file, buffer, count, pos); |
296 | } | ||
289 | break; | 297 | break; |
290 | } | 298 | } |
291 | if ((ssize_t) size > 0) | 299 | if ((ssize_t) size > 0) |