Commit 59b52d25 authored by Robert Love's avatar Robert Love Committed by Linus Torvalds

[PATCH] proper lseek locking in ALSA, take 3

The attached patch implements proper locking in ALSA lseek methods.
Note ALSA has 3 lseek implementations, but only:

	sound/core/info.c :: snd_info_entry_llseek()

requires locking.  I wrapped the function in the BKL.  According to
Jaroslav Kysela the gus_mem_proc method is only called from above.  The
third lseek, in hwdep.c, clearly doesn't need locking.  Without this
patch, the above lseek is not safe.

	Robert Love
parent 41ae709d
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <sound/info.h> #include <sound/info.h>
#include <sound/version.h> #include <sound/version.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#ifdef CONFIG_DEVFS_FS #ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#endif #endif
...@@ -162,31 +163,40 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) ...@@ -162,31 +163,40 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
{ {
snd_info_private_data_t *data; snd_info_private_data_t *data;
struct snd_info_entry *entry; struct snd_info_entry *entry;
int ret = -EINVAL;
data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO); data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
entry = data->entry; entry = data->entry;
lock_kernel();
switch (entry->content) { switch (entry->content) {
case SNDRV_INFO_CONTENT_TEXT: case SNDRV_INFO_CONTENT_TEXT:
switch (orig) { switch (orig) {
case 0: /* SEEK_SET */ case 0: /* SEEK_SET */
file->f_pos = offset; file->f_pos = offset;
return file->f_pos; ret = file->f_pos;
goto out;
case 1: /* SEEK_CUR */ case 1: /* SEEK_CUR */
file->f_pos += offset; file->f_pos += offset;
return file->f_pos; ret = file->f_pos;
goto out;
case 2: /* SEEK_END */ case 2: /* SEEK_END */
default: default:
return -EINVAL; goto out;
} }
break; break;
case SNDRV_INFO_CONTENT_DATA: case SNDRV_INFO_CONTENT_DATA:
if (entry->c.ops->llseek) if (entry->c.ops->llseek) {
return entry->c.ops->llseek(entry, ret = entry->c.ops->llseek(entry,
data->file_private_data, data->file_private_data,
file, offset, orig); file, offset, orig);
goto out;
}
break; break;
} }
return -ENXIO; ret = -ENXIO;
out:
unlock_kernel();
return ret;
} }
static ssize_t snd_info_entry_read(struct file *file, char *buffer, static ssize_t snd_info_entry_read(struct file *file, char *buffer,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment