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 | |
| 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>
| -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; |
