diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/proc/base.c | 269 |
1 files changed, 158 insertions, 111 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 7832efbd43a6..e8084eb037e3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1254,21 +1254,15 @@ static struct dentry_operations tid_fd_dentry_operations = | |||
1254 | .d_delete = pid_delete_dentry, | 1254 | .d_delete = pid_delete_dentry, |
1255 | }; | 1255 | }; |
1256 | 1256 | ||
1257 | /* SMP-safe */ | 1257 | static struct dentry *proc_fd_instantiate(struct inode *dir, |
1258 | static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) | 1258 | struct dentry *dentry, struct task_struct *task, void *ptr) |
1259 | { | 1259 | { |
1260 | struct task_struct *task = get_proc_task(dir); | 1260 | unsigned fd = *(unsigned *)ptr; |
1261 | unsigned fd = name_to_int(dentry); | 1261 | struct file *file; |
1262 | struct dentry *result = ERR_PTR(-ENOENT); | 1262 | struct files_struct *files; |
1263 | struct file * file; | 1263 | struct inode *inode; |
1264 | struct files_struct * files; | 1264 | struct proc_inode *ei; |
1265 | struct inode *inode; | 1265 | struct dentry *error = ERR_PTR(-ENOENT); |
1266 | struct proc_inode *ei; | ||
1267 | |||
1268 | if (!task) | ||
1269 | goto out_no_task; | ||
1270 | if (fd == ~0U) | ||
1271 | goto out; | ||
1272 | 1266 | ||
1273 | inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd); | 1267 | inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd); |
1274 | if (!inode) | 1268 | if (!inode) |
@@ -1277,7 +1271,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1277 | ei->fd = fd; | 1271 | ei->fd = fd; |
1278 | files = get_files_struct(task); | 1272 | files = get_files_struct(task); |
1279 | if (!files) | 1273 | if (!files) |
1280 | goto out_unlock; | 1274 | goto out_iput; |
1281 | inode->i_mode = S_IFLNK; | 1275 | inode->i_mode = S_IFLNK; |
1282 | 1276 | ||
1283 | /* | 1277 | /* |
@@ -1287,13 +1281,14 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1287 | spin_lock(&files->file_lock); | 1281 | spin_lock(&files->file_lock); |
1288 | file = fcheck_files(files, fd); | 1282 | file = fcheck_files(files, fd); |
1289 | if (!file) | 1283 | if (!file) |
1290 | goto out_unlock2; | 1284 | goto out_unlock; |
1291 | if (file->f_mode & 1) | 1285 | if (file->f_mode & 1) |
1292 | inode->i_mode |= S_IRUSR | S_IXUSR; | 1286 | inode->i_mode |= S_IRUSR | S_IXUSR; |
1293 | if (file->f_mode & 2) | 1287 | if (file->f_mode & 2) |
1294 | inode->i_mode |= S_IWUSR | S_IXUSR; | 1288 | inode->i_mode |= S_IWUSR | S_IXUSR; |
1295 | spin_unlock(&files->file_lock); | 1289 | spin_unlock(&files->file_lock); |
1296 | put_files_struct(files); | 1290 | put_files_struct(files); |
1291 | |||
1297 | inode->i_op = &proc_pid_link_inode_operations; | 1292 | inode->i_op = &proc_pid_link_inode_operations; |
1298 | inode->i_size = 64; | 1293 | inode->i_size = 64; |
1299 | ei->op.proc_get_link = proc_fd_link; | 1294 | ei->op.proc_get_link = proc_fd_link; |
@@ -1301,20 +1296,37 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1301 | d_add(dentry, inode); | 1296 | d_add(dentry, inode); |
1302 | /* Close the race of the process dying before we return the dentry */ | 1297 | /* Close the race of the process dying before we return the dentry */ |
1303 | if (tid_fd_revalidate(dentry, NULL)) | 1298 | if (tid_fd_revalidate(dentry, NULL)) |
1304 | result = NULL; | 1299 | error = NULL; |
1305 | out: | ||
1306 | put_task_struct(task); | ||
1307 | out_no_task: | ||
1308 | return result; | ||
1309 | 1300 | ||
1310 | out_unlock2: | 1301 | out: |
1302 | return error; | ||
1303 | out_unlock: | ||
1311 | spin_unlock(&files->file_lock); | 1304 | spin_unlock(&files->file_lock); |
1312 | put_files_struct(files); | 1305 | put_files_struct(files); |
1313 | out_unlock: | 1306 | out_iput: |
1314 | iput(inode); | 1307 | iput(inode); |
1315 | goto out; | 1308 | goto out; |
1316 | } | 1309 | } |
1317 | 1310 | ||
1311 | /* SMP-safe */ | ||
1312 | static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) | ||
1313 | { | ||
1314 | struct task_struct *task = get_proc_task(dir); | ||
1315 | unsigned fd = name_to_int(dentry); | ||
1316 | struct dentry *result = ERR_PTR(-ENOENT); | ||
1317 | |||
1318 | if (!task) | ||
1319 | goto out_no_task; | ||
1320 | if (fd == ~0U) | ||
1321 | goto out; | ||
1322 | |||
1323 | result = proc_fd_instantiate(dir, dentry, task, &fd); | ||
1324 | out: | ||
1325 | put_task_struct(task); | ||
1326 | out_no_task: | ||
1327 | return result; | ||
1328 | } | ||
1329 | |||
1318 | static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) | 1330 | static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) |
1319 | { | 1331 | { |
1320 | struct dentry *dentry = filp->f_dentry; | 1332 | struct dentry *dentry = filp->f_dentry; |
@@ -1395,6 +1407,36 @@ static struct inode_operations proc_fd_inode_operations = { | |||
1395 | .setattr = proc_setattr, | 1407 | .setattr = proc_setattr, |
1396 | }; | 1408 | }; |
1397 | 1409 | ||
1410 | static struct dentry *proc_pident_instantiate(struct inode *dir, | ||
1411 | struct dentry *dentry, struct task_struct *task, void *ptr) | ||
1412 | { | ||
1413 | struct pid_entry *p = ptr; | ||
1414 | struct inode *inode; | ||
1415 | struct proc_inode *ei; | ||
1416 | struct dentry *error = ERR_PTR(-EINVAL); | ||
1417 | |||
1418 | inode = proc_pid_make_inode(dir->i_sb, task, p->type); | ||
1419 | if (!inode) | ||
1420 | goto out; | ||
1421 | |||
1422 | ei = PROC_I(inode); | ||
1423 | inode->i_mode = p->mode; | ||
1424 | if (S_ISDIR(inode->i_mode)) | ||
1425 | inode->i_nlink = 2; /* Use getattr to fix if necessary */ | ||
1426 | if (p->iop) | ||
1427 | inode->i_op = p->iop; | ||
1428 | if (p->fop) | ||
1429 | inode->i_fop = p->fop; | ||
1430 | ei->op = p->op; | ||
1431 | dentry->d_op = &pid_dentry_operations; | ||
1432 | d_add(dentry, inode); | ||
1433 | /* Close the race of the process dying before we return the dentry */ | ||
1434 | if (pid_revalidate(dentry, NULL)) | ||
1435 | error = NULL; | ||
1436 | out: | ||
1437 | return error; | ||
1438 | } | ||
1439 | |||
1398 | /* SMP-safe */ | 1440 | /* SMP-safe */ |
1399 | static struct dentry *proc_pident_lookup(struct inode *dir, | 1441 | static struct dentry *proc_pident_lookup(struct inode *dir, |
1400 | struct dentry *dentry, | 1442 | struct dentry *dentry, |
@@ -1404,7 +1446,6 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
1404 | struct dentry *error; | 1446 | struct dentry *error; |
1405 | struct task_struct *task = get_proc_task(dir); | 1447 | struct task_struct *task = get_proc_task(dir); |
1406 | struct pid_entry *p; | 1448 | struct pid_entry *p; |
1407 | struct proc_inode *ei; | ||
1408 | 1449 | ||
1409 | error = ERR_PTR(-ENOENT); | 1450 | error = ERR_PTR(-ENOENT); |
1410 | inode = NULL; | 1451 | inode = NULL; |
@@ -1425,25 +1466,7 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
1425 | if (!p->name) | 1466 | if (!p->name) |
1426 | goto out; | 1467 | goto out; |
1427 | 1468 | ||
1428 | error = ERR_PTR(-EINVAL); | 1469 | error = proc_pident_instantiate(dir, dentry, task, p); |
1429 | inode = proc_pid_make_inode(dir->i_sb, task, p->type); | ||
1430 | if (!inode) | ||
1431 | goto out; | ||
1432 | |||
1433 | ei = PROC_I(inode); | ||
1434 | inode->i_mode = p->mode; | ||
1435 | if (S_ISDIR(inode->i_mode)) | ||
1436 | inode->i_nlink = 2; /* Use getattr to fix if necessary */ | ||
1437 | if (p->iop) | ||
1438 | inode->i_op = p->iop; | ||
1439 | if (p->fop) | ||
1440 | inode->i_fop = p->fop; | ||
1441 | ei->op = p->op; | ||
1442 | dentry->d_op = &pid_dentry_operations; | ||
1443 | d_add(dentry, inode); | ||
1444 | /* Close the race of the process dying before we return the dentry */ | ||
1445 | if (pid_revalidate(dentry, NULL)) | ||
1446 | error = NULL; | ||
1447 | out: | 1470 | out: |
1448 | put_task_struct(task); | 1471 | put_task_struct(task); |
1449 | out_no_task: | 1472 | out_no_task: |
@@ -1709,29 +1732,13 @@ static struct dentry_operations proc_base_dentry_operations = | |||
1709 | .d_delete = pid_delete_dentry, | 1732 | .d_delete = pid_delete_dentry, |
1710 | }; | 1733 | }; |
1711 | 1734 | ||
1712 | static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | 1735 | static struct dentry *proc_base_instantiate(struct inode *dir, |
1736 | struct dentry *dentry, struct task_struct *task, void *ptr) | ||
1713 | { | 1737 | { |
1738 | struct pid_entry *p = ptr; | ||
1714 | struct inode *inode; | 1739 | struct inode *inode; |
1715 | struct dentry *error; | ||
1716 | struct task_struct *task = get_proc_task(dir); | ||
1717 | struct pid_entry *p; | ||
1718 | struct proc_inode *ei; | 1740 | struct proc_inode *ei; |
1719 | 1741 | struct dentry *error = ERR_PTR(-EINVAL); | |
1720 | error = ERR_PTR(-ENOENT); | ||
1721 | inode = NULL; | ||
1722 | |||
1723 | if (!task) | ||
1724 | goto out_no_task; | ||
1725 | |||
1726 | /* Lookup the directory entry */ | ||
1727 | for (p = proc_base_stuff; p->name; p++) { | ||
1728 | if (p->len != dentry->d_name.len) | ||
1729 | continue; | ||
1730 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | ||
1731 | break; | ||
1732 | } | ||
1733 | if (!p->name) | ||
1734 | goto out; | ||
1735 | 1742 | ||
1736 | /* Allocate the inode */ | 1743 | /* Allocate the inode */ |
1737 | error = ERR_PTR(-ENOMEM); | 1744 | error = ERR_PTR(-ENOMEM); |
@@ -1767,14 +1774,41 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | |||
1767 | d_add(dentry, inode); | 1774 | d_add(dentry, inode); |
1768 | error = NULL; | 1775 | error = NULL; |
1769 | out: | 1776 | out: |
1770 | put_task_struct(task); | ||
1771 | out_no_task: | ||
1772 | return error; | 1777 | return error; |
1773 | out_iput: | 1778 | out_iput: |
1774 | iput(inode); | 1779 | iput(inode); |
1775 | goto out; | 1780 | goto out; |
1776 | } | 1781 | } |
1777 | 1782 | ||
1783 | static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) | ||
1784 | { | ||
1785 | struct dentry *error; | ||
1786 | struct task_struct *task = get_proc_task(dir); | ||
1787 | struct pid_entry *p; | ||
1788 | |||
1789 | error = ERR_PTR(-ENOENT); | ||
1790 | |||
1791 | if (!task) | ||
1792 | goto out_no_task; | ||
1793 | |||
1794 | /* Lookup the directory entry */ | ||
1795 | for (p = proc_base_stuff; p->name; p++) { | ||
1796 | if (p->len != dentry->d_name.len) | ||
1797 | continue; | ||
1798 | if (!memcmp(dentry->d_name.name, p->name, p->len)) | ||
1799 | break; | ||
1800 | } | ||
1801 | if (!p->name) | ||
1802 | goto out; | ||
1803 | |||
1804 | error = proc_base_instantiate(dir, dentry, task, p); | ||
1805 | |||
1806 | out: | ||
1807 | put_task_struct(task); | ||
1808 | out_no_task: | ||
1809 | return error; | ||
1810 | } | ||
1811 | |||
1778 | /* | 1812 | /* |
1779 | * Thread groups | 1813 | * Thread groups |
1780 | */ | 1814 | */ |
@@ -1915,12 +1949,40 @@ out: | |||
1915 | return; | 1949 | return; |
1916 | } | 1950 | } |
1917 | 1951 | ||
1952 | struct dentry *proc_pid_instantiate(struct inode *dir, | ||
1953 | struct dentry * dentry, struct task_struct *task, void *ptr) | ||
1954 | { | ||
1955 | struct dentry *error = ERR_PTR(-ENOENT); | ||
1956 | struct inode *inode; | ||
1957 | |||
1958 | inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); | ||
1959 | if (!inode) | ||
1960 | goto out; | ||
1961 | |||
1962 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; | ||
1963 | inode->i_op = &proc_tgid_base_inode_operations; | ||
1964 | inode->i_fop = &proc_tgid_base_operations; | ||
1965 | inode->i_flags|=S_IMMUTABLE; | ||
1966 | inode->i_nlink = 4; | ||
1967 | #ifdef CONFIG_SECURITY | ||
1968 | inode->i_nlink += 1; | ||
1969 | #endif | ||
1970 | |||
1971 | dentry->d_op = &pid_dentry_operations; | ||
1972 | |||
1973 | d_add(dentry, inode); | ||
1974 | /* Close the race of the process dying before we return the dentry */ | ||
1975 | if (pid_revalidate(dentry, NULL)) | ||
1976 | error = NULL; | ||
1977 | out: | ||
1978 | return error; | ||
1979 | } | ||
1980 | |||
1918 | /* SMP-safe */ | 1981 | /* SMP-safe */ |
1919 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 1982 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) |
1920 | { | 1983 | { |
1921 | struct dentry *result = ERR_PTR(-ENOENT); | 1984 | struct dentry *result = ERR_PTR(-ENOENT); |
1922 | struct task_struct *task; | 1985 | struct task_struct *task; |
1923 | struct inode *inode; | ||
1924 | unsigned tgid; | 1986 | unsigned tgid; |
1925 | 1987 | ||
1926 | result = proc_base_lookup(dir, dentry); | 1988 | result = proc_base_lookup(dir, dentry); |
@@ -1939,28 +2001,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
1939 | if (!task) | 2001 | if (!task) |
1940 | goto out; | 2002 | goto out; |
1941 | 2003 | ||
1942 | inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); | 2004 | result = proc_pid_instantiate(dir, dentry, task, NULL); |
1943 | if (!inode) | ||
1944 | goto out_put_task; | ||
1945 | |||
1946 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; | ||
1947 | inode->i_op = &proc_tgid_base_inode_operations; | ||
1948 | inode->i_fop = &proc_tgid_base_operations; | ||
1949 | inode->i_flags|=S_IMMUTABLE; | ||
1950 | #ifdef CONFIG_SECURITY | ||
1951 | inode->i_nlink = 5; | ||
1952 | #else | ||
1953 | inode->i_nlink = 4; | ||
1954 | #endif | ||
1955 | |||
1956 | dentry->d_op = &pid_dentry_operations; | ||
1957 | |||
1958 | d_add(dentry, inode); | ||
1959 | /* Close the race of the process dying before we return the dentry */ | ||
1960 | if (pid_revalidate(dentry, NULL)) | ||
1961 | result = NULL; | ||
1962 | |||
1963 | out_put_task: | ||
1964 | put_task_struct(task); | 2005 | put_task_struct(task); |
1965 | out: | 2006 | out: |
1966 | return result; | 2007 | return result; |
@@ -2107,13 +2148,40 @@ static struct inode_operations proc_tid_base_inode_operations = { | |||
2107 | .setattr = proc_setattr, | 2148 | .setattr = proc_setattr, |
2108 | }; | 2149 | }; |
2109 | 2150 | ||
2151 | static struct dentry *proc_task_instantiate(struct inode *dir, | ||
2152 | struct dentry *dentry, struct task_struct *task, void *ptr) | ||
2153 | { | ||
2154 | struct dentry *error = ERR_PTR(-ENOENT); | ||
2155 | struct inode *inode; | ||
2156 | inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); | ||
2157 | |||
2158 | if (!inode) | ||
2159 | goto out; | ||
2160 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; | ||
2161 | inode->i_op = &proc_tid_base_inode_operations; | ||
2162 | inode->i_fop = &proc_tid_base_operations; | ||
2163 | inode->i_flags|=S_IMMUTABLE; | ||
2164 | inode->i_nlink = 3; | ||
2165 | #ifdef CONFIG_SECURITY | ||
2166 | inode->i_nlink += 1; | ||
2167 | #endif | ||
2168 | |||
2169 | dentry->d_op = &pid_dentry_operations; | ||
2170 | |||
2171 | d_add(dentry, inode); | ||
2172 | /* Close the race of the process dying before we return the dentry */ | ||
2173 | if (pid_revalidate(dentry, NULL)) | ||
2174 | error = NULL; | ||
2175 | out: | ||
2176 | return error; | ||
2177 | } | ||
2178 | |||
2110 | /* SMP-safe */ | 2179 | /* SMP-safe */ |
2111 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 2180 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) |
2112 | { | 2181 | { |
2113 | struct dentry *result = ERR_PTR(-ENOENT); | 2182 | struct dentry *result = ERR_PTR(-ENOENT); |
2114 | struct task_struct *task; | 2183 | struct task_struct *task; |
2115 | struct task_struct *leader = get_proc_task(dir); | 2184 | struct task_struct *leader = get_proc_task(dir); |
2116 | struct inode *inode; | ||
2117 | unsigned tid; | 2185 | unsigned tid; |
2118 | 2186 | ||
2119 | if (!leader) | 2187 | if (!leader) |
@@ -2133,28 +2201,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2133 | if (leader->tgid != task->tgid) | 2201 | if (leader->tgid != task->tgid) |
2134 | goto out_drop_task; | 2202 | goto out_drop_task; |
2135 | 2203 | ||
2136 | inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); | 2204 | result = proc_task_instantiate(dir, dentry, task, NULL); |
2137 | |||
2138 | |||
2139 | if (!inode) | ||
2140 | goto out_drop_task; | ||
2141 | inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; | ||
2142 | inode->i_op = &proc_tid_base_inode_operations; | ||
2143 | inode->i_fop = &proc_tid_base_operations; | ||
2144 | inode->i_flags|=S_IMMUTABLE; | ||
2145 | #ifdef CONFIG_SECURITY | ||
2146 | inode->i_nlink = 4; | ||
2147 | #else | ||
2148 | inode->i_nlink = 3; | ||
2149 | #endif | ||
2150 | |||
2151 | dentry->d_op = &pid_dentry_operations; | ||
2152 | |||
2153 | d_add(dentry, inode); | ||
2154 | /* Close the race of the process dying before we return the dentry */ | ||
2155 | if (pid_revalidate(dentry, NULL)) | ||
2156 | result = NULL; | ||
2157 | |||
2158 | out_drop_task: | 2205 | out_drop_task: |
2159 | put_task_struct(task); | 2206 | put_task_struct(task); |
2160 | out: | 2207 | out: |