aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c132
1 files changed, 114 insertions, 18 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index be94ddebb413..0697fd089de8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1238,7 +1238,10 @@ out:
1238 return ~0U; 1238 return ~0U;
1239} 1239}
1240 1240
1241static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) 1241#define PROC_FDINFO_MAX 64
1242
1243static int proc_fd_info(struct inode *inode, struct dentry **dentry,
1244 struct vfsmount **mnt, char *info)
1242{ 1245{
1243 struct task_struct *task = get_proc_task(inode); 1246 struct task_struct *task = get_proc_task(inode);
1244 struct files_struct *files = NULL; 1247 struct files_struct *files = NULL;
@@ -1257,8 +1260,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
1257 spin_lock(&files->file_lock); 1260 spin_lock(&files->file_lock);
1258 file = fcheck_files(files, fd); 1261 file = fcheck_files(files, fd);
1259 if (file) { 1262 if (file) {
1260 *mnt = mntget(file->f_path.mnt); 1263 if (mnt)
1261 *dentry = dget(file->f_path.dentry); 1264 *mnt = mntget(file->f_path.mnt);
1265 if (dentry)
1266 *dentry = dget(file->f_path.dentry);
1267 if (info)
1268 snprintf(info, PROC_FDINFO_MAX,
1269 "pos:\t%lli\n"
1270 "flags:\t0%o\n",
1271 (long long) file->f_pos,
1272 file->f_flags);
1262 spin_unlock(&files->file_lock); 1273 spin_unlock(&files->file_lock);
1263 put_files_struct(files); 1274 put_files_struct(files);
1264 return 0; 1275 return 0;
@@ -1269,6 +1280,12 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
1269 return -ENOENT; 1280 return -ENOENT;
1270} 1281}
1271 1282
1283static int proc_fd_link(struct inode *inode, struct dentry **dentry,
1284 struct vfsmount **mnt)
1285{
1286 return proc_fd_info(inode, dentry, mnt, NULL);
1287}
1288
1272static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) 1289static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
1273{ 1290{
1274 struct inode *inode = dentry->d_inode; 1291 struct inode *inode = dentry->d_inode;
@@ -1364,7 +1381,9 @@ out_iput:
1364 goto out; 1381 goto out;
1365} 1382}
1366 1383
1367static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) 1384static struct dentry *proc_lookupfd_common(struct inode *dir,
1385 struct dentry *dentry,
1386 instantiate_t instantiate)
1368{ 1387{
1369 struct task_struct *task = get_proc_task(dir); 1388 struct task_struct *task = get_proc_task(dir);
1370 unsigned fd = name_to_int(dentry); 1389 unsigned fd = name_to_int(dentry);
@@ -1375,23 +1394,15 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
1375 if (fd == ~0U) 1394 if (fd == ~0U)
1376 goto out; 1395 goto out;
1377 1396
1378 result = proc_fd_instantiate(dir, dentry, task, &fd); 1397 result = instantiate(dir, dentry, task, &fd);
1379out: 1398out:
1380 put_task_struct(task); 1399 put_task_struct(task);
1381out_no_task: 1400out_no_task:
1382 return result; 1401 return result;
1383} 1402}
1384 1403
1385static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 1404static int proc_readfd_common(struct file * filp, void * dirent,
1386 struct task_struct *task, int fd) 1405 filldir_t filldir, instantiate_t instantiate)
1387{
1388 char name[PROC_NUMBUF];
1389 int len = snprintf(name, sizeof(name), "%d", fd);
1390 return proc_fill_cache(filp, dirent, filldir, name, len,
1391 proc_fd_instantiate, task, &fd);
1392}
1393
1394static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1395{ 1406{
1396 struct dentry *dentry = filp->f_path.dentry; 1407 struct dentry *dentry = filp->f_path.dentry;
1397 struct inode *inode = dentry->d_inode; 1408 struct inode *inode = dentry->d_inode;
@@ -1427,12 +1438,17 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
1427 for (fd = filp->f_pos-2; 1438 for (fd = filp->f_pos-2;
1428 fd < fdt->max_fds; 1439 fd < fdt->max_fds;
1429 fd++, filp->f_pos++) { 1440 fd++, filp->f_pos++) {
1441 char name[PROC_NUMBUF];
1442 int len;
1430 1443
1431 if (!fcheck_files(files, fd)) 1444 if (!fcheck_files(files, fd))
1432 continue; 1445 continue;
1433 rcu_read_unlock(); 1446 rcu_read_unlock();
1434 1447
1435 if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) { 1448 len = snprintf(name, sizeof(name), "%d", fd);
1449 if (proc_fill_cache(filp, dirent, filldir,
1450 name, len, instantiate,
1451 p, &fd) < 0) {
1436 rcu_read_lock(); 1452 rcu_read_lock();
1437 break; 1453 break;
1438 } 1454 }
@@ -1447,6 +1463,32 @@ out_no_task:
1447 return retval; 1463 return retval;
1448} 1464}
1449 1465
1466static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
1467 struct nameidata *nd)
1468{
1469 return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
1470}
1471
1472static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
1473{
1474 return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
1475}
1476
1477static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
1478 size_t len, loff_t *ppos)
1479{
1480 char tmp[PROC_FDINFO_MAX];
1481 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
1482 if (!err)
1483 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
1484 return err;
1485}
1486
1487static const struct file_operations proc_fdinfo_file_operations = {
1488 .open = nonseekable_open,
1489 .read = proc_fdinfo_read,
1490};
1491
1450static const struct file_operations proc_fd_operations = { 1492static const struct file_operations proc_fd_operations = {
1451 .read = generic_read_dir, 1493 .read = generic_read_dir,
1452 .readdir = proc_readfd, 1494 .readdir = proc_readfd,
@@ -1478,6 +1520,58 @@ static const struct inode_operations proc_fd_inode_operations = {
1478 .setattr = proc_setattr, 1520 .setattr = proc_setattr,
1479}; 1521};
1480 1522
1523static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
1524 struct dentry *dentry, struct task_struct *task, const void *ptr)
1525{
1526 unsigned fd = *(unsigned *)ptr;
1527 struct inode *inode;
1528 struct proc_inode *ei;
1529 struct dentry *error = ERR_PTR(-ENOENT);
1530
1531 inode = proc_pid_make_inode(dir->i_sb, task);
1532 if (!inode)
1533 goto out;
1534 ei = PROC_I(inode);
1535 ei->fd = fd;
1536 inode->i_mode = S_IFREG | S_IRUSR;
1537 inode->i_fop = &proc_fdinfo_file_operations;
1538 dentry->d_op = &tid_fd_dentry_operations;
1539 d_add(dentry, inode);
1540 /* Close the race of the process dying before we return the dentry */
1541 if (tid_fd_revalidate(dentry, NULL))
1542 error = NULL;
1543
1544 out:
1545 return error;
1546}
1547
1548static struct dentry *proc_lookupfdinfo(struct inode *dir,
1549 struct dentry *dentry,
1550 struct nameidata *nd)
1551{
1552 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
1553}
1554
1555static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
1556{
1557 return proc_readfd_common(filp, dirent, filldir,
1558 proc_fdinfo_instantiate);
1559}
1560
1561static const struct file_operations proc_fdinfo_operations = {
1562 .read = generic_read_dir,
1563 .readdir = proc_readfdinfo,
1564};
1565
1566/*
1567 * proc directories can do almost nothing..
1568 */
1569static const struct inode_operations proc_fdinfo_inode_operations = {
1570 .lookup = proc_lookupfdinfo,
1571 .setattr = proc_setattr,
1572};
1573
1574
1481static struct dentry *proc_pident_instantiate(struct inode *dir, 1575static struct dentry *proc_pident_instantiate(struct inode *dir,
1482 struct dentry *dentry, struct task_struct *task, const void *ptr) 1576 struct dentry *dentry, struct task_struct *task, const void *ptr)
1483{ 1577{
@@ -1888,6 +1982,7 @@ static const struct inode_operations proc_task_inode_operations;
1888static const struct pid_entry tgid_base_stuff[] = { 1982static const struct pid_entry tgid_base_stuff[] = {
1889 DIR("task", S_IRUGO|S_IXUGO, task), 1983 DIR("task", S_IRUGO|S_IXUGO, task),
1890 DIR("fd", S_IRUSR|S_IXUSR, fd), 1984 DIR("fd", S_IRUSR|S_IXUSR, fd),
1985 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
1891 INF("environ", S_IRUSR, pid_environ), 1986 INF("environ", S_IRUSR, pid_environ),
1892 INF("auxv", S_IRUSR, pid_auxv), 1987 INF("auxv", S_IRUSR, pid_auxv),
1893 INF("status", S_IRUGO, pid_status), 1988 INF("status", S_IRUGO, pid_status),
@@ -2041,7 +2136,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
2041 inode->i_op = &proc_tgid_base_inode_operations; 2136 inode->i_op = &proc_tgid_base_inode_operations;
2042 inode->i_fop = &proc_tgid_base_operations; 2137 inode->i_fop = &proc_tgid_base_operations;
2043 inode->i_flags|=S_IMMUTABLE; 2138 inode->i_flags|=S_IMMUTABLE;
2044 inode->i_nlink = 4; 2139 inode->i_nlink = 5;
2045#ifdef CONFIG_SECURITY 2140#ifdef CONFIG_SECURITY
2046 inode->i_nlink += 1; 2141 inode->i_nlink += 1;
2047#endif 2142#endif
@@ -2171,6 +2266,7 @@ out_no_task:
2171 */ 2266 */
2172static const struct pid_entry tid_base_stuff[] = { 2267static const struct pid_entry tid_base_stuff[] = {
2173 DIR("fd", S_IRUSR|S_IXUSR, fd), 2268 DIR("fd", S_IRUSR|S_IXUSR, fd),
2269 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
2174 INF("environ", S_IRUSR, pid_environ), 2270 INF("environ", S_IRUSR, pid_environ),
2175 INF("auxv", S_IRUSR, pid_auxv), 2271 INF("auxv", S_IRUSR, pid_auxv),
2176 INF("status", S_IRUGO, pid_status), 2272 INF("status", S_IRUGO, pid_status),
@@ -2251,7 +2347,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
2251 inode->i_op = &proc_tid_base_inode_operations; 2347 inode->i_op = &proc_tid_base_inode_operations;
2252 inode->i_fop = &proc_tid_base_operations; 2348 inode->i_fop = &proc_tid_base_operations;
2253 inode->i_flags|=S_IMMUTABLE; 2349 inode->i_flags|=S_IMMUTABLE;
2254 inode->i_nlink = 3; 2350 inode->i_nlink = 4;
2255#ifdef CONFIG_SECURITY 2351#ifdef CONFIG_SECURITY
2256 inode->i_nlink += 1; 2352 inode->i_nlink += 1;
2257#endif 2353#endif