diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-22 01:32:44 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-22 19:55:03 -0400 |
commit | 9b4f526cdc0f95f635607dfba6ac788b3deca188 (patch) | |
tree | f9f324dbd88856fdaeff1d0146059806bacba26f /fs | |
parent | ed1524371716466e9c762808b02601d0d0276a92 (diff) |
[PATCH] proc_readfd_common() race fix
Since we drop the rcu_read_lock inside the loop, we can't assume
that files->fdt will remain unchanged (and not freed) between
iterations.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/proc/base.c | 4 |
1 files changed, 1 insertions, 3 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 81d7d145292a..7313c62e3e9d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1626,7 +1626,6 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
1626 | unsigned int fd, ino; | 1626 | unsigned int fd, ino; |
1627 | int retval; | 1627 | int retval; |
1628 | struct files_struct * files; | 1628 | struct files_struct * files; |
1629 | struct fdtable *fdt; | ||
1630 | 1629 | ||
1631 | retval = -ENOENT; | 1630 | retval = -ENOENT; |
1632 | if (!p) | 1631 | if (!p) |
@@ -1649,9 +1648,8 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
1649 | if (!files) | 1648 | if (!files) |
1650 | goto out; | 1649 | goto out; |
1651 | rcu_read_lock(); | 1650 | rcu_read_lock(); |
1652 | fdt = files_fdtable(files); | ||
1653 | for (fd = filp->f_pos-2; | 1651 | for (fd = filp->f_pos-2; |
1654 | fd < fdt->max_fds; | 1652 | fd < files_fdtable(files)->max_fds; |
1655 | fd++, filp->f_pos++) { | 1653 | fd++, filp->f_pos++) { |
1656 | char name[PROC_NUMBUF]; | 1654 | char name[PROC_NUMBUF]; |
1657 | int len; | 1655 | int len; |