ALSA: info - Check file position validity in common layer
[deliverable/linux.git] / sound / core / info.c
index cc4a53d4b7f87155386697318d037671e75dab55..f90a6fd43fb4b43b363f718e7ffc671a56bd166d 100644 (file)
@@ -168,7 +168,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
 
        data = file->private_data;
        entry = data->entry;
-       lock_kernel();
+       mutex_lock(&entry->access);
        switch (entry->content) {
        case SNDRV_INFO_CONTENT_TEXT:
                switch (orig) {
@@ -197,7 +197,7 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
        }
        ret = -ENXIO;
 out:
-       unlock_kernel();
+       mutex_unlock(&entry->access);
        return ret;
 }
 
@@ -232,10 +232,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
                        return -EFAULT;
                break;
        case SNDRV_INFO_CONTENT_DATA:
-               if (entry->c.ops->read)
+               if (pos >= entry->size)
+                       return 0;
+               if (entry->c.ops->read) {
+                       size = entry->size - pos;
+                       size = min(count, size);
                        size = entry->c.ops->read(entry,
                                                  data->file_private_data,
-                                                 file, buffer, count, pos);
+                                                 file, buffer, size, pos);
+               }
                break;
        }
        if ((ssize_t) size > 0)
@@ -282,10 +287,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
                size = count;
                break;
        case SNDRV_INFO_CONTENT_DATA:
-               if (entry->c.ops->write)
+               if (entry->c.ops->write && count > 0) {
+                       size_t maxsize = entry->size - pos;
+                       count = min(count, maxsize);
                        size = entry->c.ops->write(entry,
                                                   data->file_private_data,
                                                   file, buffer, count, pos);
+               }
                break;
        }
        if ((ssize_t) size > 0)
This page took 0.025221 seconds and 5 git commands to generate.