diff options
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/base.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index c4fcd6465f73..725e279c3bdf 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1377,12 +1377,13 @@ out: | |||
1377 | /* SMP-safe */ | 1377 | /* SMP-safe */ |
1378 | static struct dentry *proc_pident_lookup(struct inode *dir, | 1378 | static struct dentry *proc_pident_lookup(struct inode *dir, |
1379 | struct dentry *dentry, | 1379 | struct dentry *dentry, |
1380 | struct pid_entry *ents) | 1380 | struct pid_entry *ents, |
1381 | unsigned int nents) | ||
1381 | { | 1382 | { |
1382 | struct inode *inode; | 1383 | struct inode *inode; |
1383 | struct dentry *error; | 1384 | struct dentry *error; |
1384 | struct task_struct *task = get_proc_task(dir); | 1385 | struct task_struct *task = get_proc_task(dir); |
1385 | struct pid_entry *p; | 1386 | struct pid_entry *p, *last; |
1386 | 1387 | ||
1387 | error = ERR_PTR(-ENOENT); | 1388 | error = ERR_PTR(-ENOENT); |
1388 | inode = NULL; | 1389 | inode = NULL; |
@@ -1394,13 +1395,14 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
1394 | * Yes, it does not scale. And it should not. Don't add | 1395 | * Yes, it does not scale. And it should not. Don't add |
1395 | * new entries into /proc/<tgid>/ without very good reasons. | 1396 | * new entries into /proc/<tgid>/ without very good reasons. |
1396 | */ | 1397 | */ |
1397 | for (p = ents; p->name; p++) { | 1398 | last = &ents[nents - 1]; |
1399 | for (p = ents; p <= last; p++) { | ||
1398 | if (p->len != dentry->d_name.len) | 1400 | if (p->len != dentry->d_name.len) |
1399 | continue; | 1401 | continue; |
1400 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | 1402 | if (!memcmp(dentry->d_name.name, p->name, p->len)) |
1401 | break; | 1403 | break; |
1402 | } | 1404 | } |
1403 | if (!p->name) | 1405 | if (p > last) |
1404 | goto out; | 1406 | goto out; |
1405 | 1407 | ||
1406 | error = proc_pident_instantiate(dir, dentry, task, p); | 1408 | error = proc_pident_instantiate(dir, dentry, task, p); |
@@ -1426,7 +1428,7 @@ static int proc_pident_readdir(struct file *filp, | |||
1426 | struct dentry *dentry = filp->f_dentry; | 1428 | struct dentry *dentry = filp->f_dentry; |
1427 | struct inode *inode = dentry->d_inode; | 1429 | struct inode *inode = dentry->d_inode; |
1428 | struct task_struct *task = get_proc_task(inode); | 1430 | struct task_struct *task = get_proc_task(inode); |
1429 | struct pid_entry *p; | 1431 | struct pid_entry *p, *last; |
1430 | ino_t ino; | 1432 | ino_t ino; |
1431 | int ret; | 1433 | int ret; |
1432 | 1434 | ||
@@ -1459,7 +1461,8 @@ static int proc_pident_readdir(struct file *filp, | |||
1459 | goto out; | 1461 | goto out; |
1460 | } | 1462 | } |
1461 | p = ents + i; | 1463 | p = ents + i; |
1462 | while (p->name) { | 1464 | last = &ents[nents - 1]; |
1465 | while (p <= last) { | ||
1463 | if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0) | 1466 | if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0) |
1464 | goto out; | 1467 | goto out; |
1465 | filp->f_pos++; | 1468 | filp->f_pos++; |
@@ -1556,7 +1559,6 @@ static struct pid_entry attr_dir_stuff[] = { | |||
1556 | REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), | 1559 | REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), |
1557 | REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), | 1560 | REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), |
1558 | REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), | 1561 | REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), |
1559 | {} | ||
1560 | }; | 1562 | }; |
1561 | 1563 | ||
1562 | static int proc_attr_dir_readdir(struct file * filp, | 1564 | static int proc_attr_dir_readdir(struct file * filp, |
@@ -1574,7 +1576,8 @@ static struct file_operations proc_attr_dir_operations = { | |||
1574 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, | 1576 | static struct dentry *proc_attr_dir_lookup(struct inode *dir, |
1575 | struct dentry *dentry, struct nameidata *nd) | 1577 | struct dentry *dentry, struct nameidata *nd) |
1576 | { | 1578 | { |
1577 | return proc_pident_lookup(dir, dentry, attr_dir_stuff); | 1579 | return proc_pident_lookup(dir, dentry, |
1580 | attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); | ||
1578 | } | 1581 | } |
1579 | 1582 | ||
1580 | static struct inode_operations proc_attr_dir_inode_operations = { | 1583 | static struct inode_operations proc_attr_dir_inode_operations = { |
@@ -1618,7 +1621,6 @@ static struct inode_operations proc_self_inode_operations = { | |||
1618 | static struct pid_entry proc_base_stuff[] = { | 1621 | static struct pid_entry proc_base_stuff[] = { |
1619 | NOD("self", S_IFLNK|S_IRWXUGO, | 1622 | NOD("self", S_IFLNK|S_IRWXUGO, |
1620 | &proc_self_inode_operations, NULL, {}), | 1623 | &proc_self_inode_operations, NULL, {}), |
1621 | {} | ||
1622 | }; | 1624 | }; |
1623 | 1625 | ||
1624 | /* | 1626 | /* |
@@ -1695,7 +1697,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | |||
1695 | { | 1697 | { |
1696 | struct dentry *error; | 1698 | struct dentry *error; |
1697 | struct task_struct *task = get_proc_task(dir); | 1699 | struct task_struct *task = get_proc_task(dir); |
1698 | struct pid_entry *p; | 1700 | struct pid_entry *p, *last; |
1699 | 1701 | ||
1700 | error = ERR_PTR(-ENOENT); | 1702 | error = ERR_PTR(-ENOENT); |
1701 | 1703 | ||
@@ -1703,13 +1705,14 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | |||
1703 | goto out_no_task; | 1705 | goto out_no_task; |
1704 | 1706 | ||
1705 | /* Lookup the directory entry */ | 1707 | /* Lookup the directory entry */ |
1706 | for (p = proc_base_stuff; p->name; p++) { | 1708 | last = &proc_base_stuff[ARRAY_SIZE(proc_base_stuff) - 1]; |
1709 | for (p = proc_base_stuff; p <= last; p++) { | ||
1707 | if (p->len != dentry->d_name.len) | 1710 | if (p->len != dentry->d_name.len) |
1708 | continue; | 1711 | continue; |
1709 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | 1712 | if (!memcmp(dentry->d_name.name, p->name, p->len)) |
1710 | break; | 1713 | break; |
1711 | } | 1714 | } |
1712 | if (!p->name) | 1715 | if (p > last) |
1713 | goto out; | 1716 | goto out; |
1714 | 1717 | ||
1715 | error = proc_base_instantiate(dir, dentry, task, p); | 1718 | error = proc_base_instantiate(dir, dentry, task, p); |
@@ -1775,7 +1778,6 @@ static struct pid_entry tgid_base_stuff[] = { | |||
1775 | #ifdef CONFIG_AUDITSYSCALL | 1778 | #ifdef CONFIG_AUDITSYSCALL |
1776 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 1779 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
1777 | #endif | 1780 | #endif |
1778 | {} | ||
1779 | }; | 1781 | }; |
1780 | 1782 | ||
1781 | static int proc_tgid_base_readdir(struct file * filp, | 1783 | static int proc_tgid_base_readdir(struct file * filp, |
@@ -1791,7 +1793,8 @@ static struct file_operations proc_tgid_base_operations = { | |||
1791 | }; | 1793 | }; |
1792 | 1794 | ||
1793 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 1795 | static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ |
1794 | return proc_pident_lookup(dir, dentry, tgid_base_stuff); | 1796 | return proc_pident_lookup(dir, dentry, |
1797 | tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); | ||
1795 | } | 1798 | } |
1796 | 1799 | ||
1797 | static struct inode_operations proc_tgid_base_inode_operations = { | 1800 | static struct inode_operations proc_tgid_base_inode_operations = { |
@@ -1961,7 +1964,7 @@ retry: | |||
1961 | return task; | 1964 | return task; |
1962 | } | 1965 | } |
1963 | 1966 | ||
1964 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + (ARRAY_SIZE(proc_base_stuff) - 1)) | 1967 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + ARRAY_SIZE(proc_base_stuff)) |
1965 | 1968 | ||
1966 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1969 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
1967 | struct task_struct *task, int tgid) | 1970 | struct task_struct *task, int tgid) |
@@ -1983,7 +1986,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
1983 | if (!reaper) | 1986 | if (!reaper) |
1984 | goto out_no_task; | 1987 | goto out_no_task; |
1985 | 1988 | ||
1986 | for (; nr < (ARRAY_SIZE(proc_base_stuff) - 1); filp->f_pos++, nr++) { | 1989 | for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) { |
1987 | struct pid_entry *p = &proc_base_stuff[nr]; | 1990 | struct pid_entry *p = &proc_base_stuff[nr]; |
1988 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) | 1991 | if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0) |
1989 | goto out; | 1992 | goto out; |
@@ -2050,7 +2053,6 @@ static struct pid_entry tid_base_stuff[] = { | |||
2050 | #ifdef CONFIG_AUDITSYSCALL | 2053 | #ifdef CONFIG_AUDITSYSCALL |
2051 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2054 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
2052 | #endif | 2055 | #endif |
2053 | {} | ||
2054 | }; | 2056 | }; |
2055 | 2057 | ||
2056 | static int proc_tid_base_readdir(struct file * filp, | 2058 | static int proc_tid_base_readdir(struct file * filp, |
@@ -2061,7 +2063,8 @@ static int proc_tid_base_readdir(struct file * filp, | |||
2061 | } | 2063 | } |
2062 | 2064 | ||
2063 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ | 2065 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){ |
2064 | return proc_pident_lookup(dir, dentry, tid_base_stuff); | 2066 | return proc_pident_lookup(dir, dentry, |
2067 | tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); | ||
2065 | } | 2068 | } |
2066 | 2069 | ||
2067 | static struct file_operations proc_tid_base_operations = { | 2070 | static struct file_operations proc_tid_base_operations = { |