aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-06-26 03:25:49 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:25 -0400
commitcd6a3ce9ec040c0b56ea92a81ff710417798c559 (patch)
tree350c0b4bb63a971c9409be8459a45b690ef4ac67
parent48e6484d49020dba3578ad117b461e8a391e8f0f (diff)
[PATCH] proc: Close the race of a process dying durning lookup
proc_lookup and task exiting are not synchronized, although some of the previous code may have suggested that. Every time before we reuse a dentry namei.c calls d_op->derevalidate which prevents us from reusing a stale dcache entry. Unfortunately it does not prevent us from returning a stale dcache entry. This race has been explicitly plugged in proc_pid_lookup but there is nothing to confine it to just that proc lookup function. So to prevent the race I call revalidate explictily in all of the proc lookup functions after I call d_add, and report an error if the revalidate does not succeed. Years ago Al Viro did something similar but those changes got lost in the churn. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/proc/base.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f435932e6432..98eaeaa9fdd1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1402,6 +1402,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1402{ 1402{
1403 struct task_struct *task = proc_task(dir); 1403 struct task_struct *task = proc_task(dir);
1404 unsigned fd = name_to_int(dentry); 1404 unsigned fd = name_to_int(dentry);
1405 struct dentry *result = ERR_PTR(-ENOENT);
1405 struct file * file; 1406 struct file * file;
1406 struct files_struct * files; 1407 struct files_struct * files;
1407 struct inode *inode; 1408 struct inode *inode;
@@ -1441,15 +1442,18 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1441 ei->op.proc_get_link = proc_fd_link; 1442 ei->op.proc_get_link = proc_fd_link;
1442 dentry->d_op = &tid_fd_dentry_operations; 1443 dentry->d_op = &tid_fd_dentry_operations;
1443 d_add(dentry, inode); 1444 d_add(dentry, inode);
1444 return NULL; 1445 /* Close the race of the process dying before we return the dentry */
1446 if (tid_fd_revalidate(dentry, NULL))
1447 result = NULL;
1448out:
1449 return result;
1445 1450
1446out_unlock2: 1451out_unlock2:
1447 spin_unlock(&files->file_lock); 1452 spin_unlock(&files->file_lock);
1448 put_files_struct(files); 1453 put_files_struct(files);
1449out_unlock: 1454out_unlock:
1450 iput(inode); 1455 iput(inode);
1451out: 1456 goto out;
1452 return ERR_PTR(-ENOENT);
1453} 1457}
1454 1458
1455static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir); 1459static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir);
@@ -1549,12 +1553,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1549 struct pid_entry *ents) 1553 struct pid_entry *ents)
1550{ 1554{
1551 struct inode *inode; 1555 struct inode *inode;
1552 int error; 1556 struct dentry *error;
1553 struct task_struct *task = proc_task(dir); 1557 struct task_struct *task = proc_task(dir);
1554 struct pid_entry *p; 1558 struct pid_entry *p;
1555 struct proc_inode *ei; 1559 struct proc_inode *ei;
1556 1560
1557 error = -ENOENT; 1561 error = ERR_PTR(-ENOENT);
1558 inode = NULL; 1562 inode = NULL;
1559 1563
1560 if (!pid_alive(task)) 1564 if (!pid_alive(task))
@@ -1569,7 +1573,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1569 if (!p->name) 1573 if (!p->name)
1570 goto out; 1574 goto out;
1571 1575
1572 error = -EINVAL; 1576 error = ERR_PTR(-EINVAL);
1573 inode = proc_pid_make_inode(dir->i_sb, task, p->type); 1577 inode = proc_pid_make_inode(dir->i_sb, task, p->type);
1574 if (!inode) 1578 if (!inode)
1575 goto out; 1579 goto out;
@@ -1736,14 +1740,16 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1736 default: 1740 default:
1737 printk("procfs: impossible type (%d)",p->type); 1741 printk("procfs: impossible type (%d)",p->type);
1738 iput(inode); 1742 iput(inode);
1739 return ERR_PTR(-EINVAL); 1743 error = ERR_PTR(-EINVAL);
1744 goto out;
1740 } 1745 }
1741 dentry->d_op = &pid_dentry_operations; 1746 dentry->d_op = &pid_dentry_operations;
1742 d_add(dentry, inode); 1747 d_add(dentry, inode);
1743 return NULL; 1748 /* Close the race of the process dying before we return the dentry */
1744 1749 if (pid_revalidate(dentry, NULL))
1750 error = NULL;
1745out: 1751out:
1746 return ERR_PTR(error); 1752 return error;
1747} 1753}
1748 1754
1749static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ 1755static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
@@ -1911,6 +1917,7 @@ out:
1911/* SMP-safe */ 1917/* SMP-safe */
1912struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) 1918struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
1913{ 1919{
1920 struct dentry *result = ERR_PTR(-ENOENT);
1914 struct task_struct *task; 1921 struct task_struct *task;
1915 struct inode *inode; 1922 struct inode *inode;
1916 struct proc_inode *ei; 1923 struct proc_inode *ei;
@@ -1944,12 +1951,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
1944 goto out; 1951 goto out;
1945 1952
1946 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); 1953 inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
1954 if (!inode)
1955 goto out_put_task;
1947 1956
1948
1949 if (!inode) {
1950 put_task_struct(task);
1951 goto out;
1952 }
1953 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; 1957 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
1954 inode->i_op = &proc_tgid_base_inode_operations; 1958 inode->i_op = &proc_tgid_base_inode_operations;
1955 inode->i_fop = &proc_tgid_base_operations; 1959 inode->i_fop = &proc_tgid_base_operations;
@@ -1963,21 +1967,20 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
1963 dentry->d_op = &pid_dentry_operations; 1967 dentry->d_op = &pid_dentry_operations;
1964 1968
1965 d_add(dentry, inode); 1969 d_add(dentry, inode);
1966 if (!pid_alive(task)) { 1970 /* Close the race of the process dying before we return the dentry */
1967 d_drop(dentry); 1971 if (pid_revalidate(dentry, NULL))
1968 shrink_dcache_parent(dentry); 1972 result = NULL;
1969 goto out;
1970 }
1971 1973
1974out_put_task:
1972 put_task_struct(task); 1975 put_task_struct(task);
1973 return NULL;
1974out: 1976out:
1975 return ERR_PTR(-ENOENT); 1977 return result;
1976} 1978}
1977 1979
1978/* SMP-safe */ 1980/* SMP-safe */
1979static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) 1981static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
1980{ 1982{
1983 struct dentry *result = ERR_PTR(-ENOENT);
1981 struct task_struct *task; 1984 struct task_struct *task;
1982 struct task_struct *leader = proc_task(dir); 1985 struct task_struct *leader = proc_task(dir);
1983 struct inode *inode; 1986 struct inode *inode;
@@ -2015,13 +2018,14 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
2015 dentry->d_op = &pid_dentry_operations; 2018 dentry->d_op = &pid_dentry_operations;
2016 2019
2017 d_add(dentry, inode); 2020 d_add(dentry, inode);
2021 /* Close the race of the process dying before we return the dentry */
2022 if (pid_revalidate(dentry, NULL))
2023 result = NULL;
2018 2024
2019 put_task_struct(task);
2020 return NULL;
2021out_drop_task: 2025out_drop_task:
2022 put_task_struct(task); 2026 put_task_struct(task);
2023out: 2027out:
2024 return ERR_PTR(-ENOENT); 2028 return result;
2025} 2029}
2026 2030
2027#define PROC_NUMBUF 10 2031#define PROC_NUMBUF 10