Commit 97f084b8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'driver-core-3.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core

Pull sysfs fixes from Greg Kroah-Hartman:
 "Here are two fixes for sysfs that resolve issues that have been found
  by the Trinity fuzz tool, causing oopses in sysfs.  They both have
  been in linux-next for a while to ensure that they do not cause any
  other problems."

* tag 'driver-core-3.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  sysfs: handle failure path correctly for readdir()
  sysfs: fix race between readdir and lseek
parents 1b6a4db2 e5110f41
...@@ -1020,6 +1020,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -1020,6 +1020,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
ino = parent_sd->s_ino; ino = parent_sd->s_ino;
if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
filp->f_pos++; filp->f_pos++;
else
return 0;
} }
if (filp->f_pos == 1) { if (filp->f_pos == 1) {
if (parent_sd->s_parent) if (parent_sd->s_parent)
...@@ -1028,6 +1030,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -1028,6 +1030,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
ino = parent_sd->s_ino; ino = parent_sd->s_ino;
if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
filp->f_pos++; filp->f_pos++;
else
return 0;
} }
mutex_lock(&sysfs_mutex); mutex_lock(&sysfs_mutex);
for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);
...@@ -1058,10 +1062,21 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) ...@@ -1058,10 +1062,21 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
return 0; return 0;
} }
static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence)
{
struct inode *inode = file_inode(file);
loff_t ret;
mutex_lock(&inode->i_mutex);
ret = generic_file_llseek(file, offset, whence);
mutex_unlock(&inode->i_mutex);
return ret;
}
const struct file_operations sysfs_dir_operations = { const struct file_operations sysfs_dir_operations = {
.read = generic_read_dir, .read = generic_read_dir,
.readdir = sysfs_readdir, .readdir = sysfs_readdir,
.release = sysfs_dir_release, .release = sysfs_dir_release,
.llseek = generic_file_llseek, .llseek = sysfs_dir_llseek,
}; };
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