1#include <linux/sched.h>
2#include <linux/errno.h>
3#include <linux/dcache.h>
4#include <linux/path.h>
5#include <linux/fdtable.h>
6#include <linux/namei.h>
7#include <linux/pid.h>
8#include <linux/security.h>
9#include <linux/file.h>
10#include <linux/seq_file.h>
11#include <linux/fs.h>
12
13#include <linux/proc_fs.h>
14
15#include "../mount.h"
16#include "internal.h"
17#include "fd.h"
18
19static int seq_show(struct seq_file *m, void *v)
20{
21 struct files_struct *files = NULL;
22 int f_flags = 0, ret = -ENOENT;
23 struct file *file = NULL;
24 struct task_struct *task;
25
26 task = get_proc_task(m->private);
27 if (!task)
28 return -ENOENT;
29
30 files = get_files_struct(task);
31 put_task_struct(task);
32
33 if (files) {
34 int fd = proc_fd(m->private);
35
36 spin_lock(&files->file_lock);
37 file = fcheck_files(files, fd);
38 if (file) {
39 struct fdtable *fdt = files_fdtable(files);
40
41 f_flags = file->f_flags;
42 if (close_on_exec(fd, fdt))
43 f_flags |= O_CLOEXEC;
44
45 get_file(file);
46 ret = 0;
47 }
48 spin_unlock(&files->file_lock);
49 put_files_struct(files);
50 }
51
52 if (ret)
53 return ret;
54
55 seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n",
56 (long long)file->f_pos, f_flags,
57 real_mount(file->f_path.mnt)->mnt_id);
58
59 show_fd_locks(m, file, files);
60
61 if (file->f_op->show_fdinfo)
62 ret = file->f_op->show_fdinfo(m, file);
63
64 fput(file);
65 return 0;
66}
67
68static int seq_fdinfo_open(struct inode *inode, struct file *file)
69{
70 return single_open(file, seq_show, inode);
71}
72
73static const struct file_operations proc_fdinfo_file_operations = {
74 .open = seq_fdinfo_open,
75 .read = seq_read,
76 .llseek = seq_lseek,
77 .release = single_release,
78};
79
80static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
81{
82 struct files_struct *files;
83 struct task_struct *task;
84 const struct cred *cred;
85 struct inode *inode;
86 int fd;
87
88 if (flags & LOOKUP_RCU)
89 return -ECHILD;
90
91 inode = dentry->d_inode;
92 task = get_proc_task(inode);
93 fd = proc_fd(inode);
94
95 if (task) {
96 files = get_files_struct(task);
97 if (files) {
98 struct file *file;
99
100 rcu_read_lock();
101 file = fcheck_files(files, fd);
102 if (file) {
103 unsigned f_mode = file->f_mode;
104
105 rcu_read_unlock();
106 put_files_struct(files);
107
108 if (task_dumpable(task)) {
109 rcu_read_lock();
110 cred = __task_cred(task);
111 inode->i_uid = cred->euid;
112 inode->i_gid = cred->egid;
113 rcu_read_unlock();
114 } else {
115 inode->i_uid = GLOBAL_ROOT_UID;
116 inode->i_gid = GLOBAL_ROOT_GID;
117 }
118
119 if (S_ISLNK(inode->i_mode)) {
120 unsigned i_mode = S_IFLNK;
121 if (f_mode & FMODE_READ)
122 i_mode |= S_IRUSR | S_IXUSR;
123 if (f_mode & FMODE_WRITE)
124 i_mode |= S_IWUSR | S_IXUSR;
125 inode->i_mode = i_mode;
126 }
127
128 security_task_to_inode(task, inode);
129 put_task_struct(task);
130 return 1;
131 }
132 rcu_read_unlock();
133 put_files_struct(files);
134 }
135 put_task_struct(task);
136 }
137 return 0;
138}
139
140static const struct dentry_operations tid_fd_dentry_operations = {
141 .d_revalidate = tid_fd_revalidate,
142 .d_delete = pid_delete_dentry,
143};
144
145static int proc_fd_link(struct dentry *dentry, struct path *path)
146{
147 struct files_struct *files = NULL;
148 struct task_struct *task;
149 int ret = -ENOENT;
150
151 task = get_proc_task(dentry->d_inode);
152 if (task) {
153 files = get_files_struct(task);
154 put_task_struct(task);
155 }
156
157 if (files) {
158 int fd = proc_fd(dentry->d_inode);
159 struct file *fd_file;
160
161 spin_lock(&files->file_lock);
162 fd_file = fcheck_files(files, fd);
163 if (fd_file) {
164 *path = fd_file->f_path;
165 path_get(&fd_file->f_path);
166 ret = 0;
167 }
168 spin_unlock(&files->file_lock);
169 put_files_struct(files);
170 }
171
172 return ret;
173}
174
175static struct dentry *
176proc_fd_instantiate(struct inode *dir, struct dentry *dentry,
177 struct task_struct *task, const void *ptr)
178{
179 struct dentry *error = ERR_PTR(-ENOENT);
180 unsigned fd = (unsigned long)ptr;
181 struct proc_inode *ei;
182 struct inode *inode;
183
184 inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK);
185 if (!inode)
186 goto out;
187
188 ei = PROC_I(inode);
189 ei->fd = fd;
190
191 inode->i_op = &proc_pid_link_inode_operations;
192 inode->i_size = 64;
193
194 ei->op.proc_get_link = proc_fd_link;
195
196 d_set_d_op(dentry, &tid_fd_dentry_operations);
197 d_add(dentry, inode);
198
199
200 if (tid_fd_revalidate(dentry, 0))
201 error = NULL;
202 out:
203 return error;
204}
205
206static struct dentry *proc_lookupfd_common(struct inode *dir,
207 struct dentry *dentry,
208 instantiate_t instantiate)
209{
210 struct task_struct *task = get_proc_task(dir);
211 struct dentry *result = ERR_PTR(-ENOENT);
212 unsigned fd = name_to_int(dentry);
213
214 if (!task)
215 goto out_no_task;
216 if (fd == ~0U)
217 goto out;
218
219 result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
220out:
221 put_task_struct(task);
222out_no_task:
223 return result;
224}
225
226static int proc_readfd_common(struct file * filp, void * dirent,
227 filldir_t filldir, instantiate_t instantiate)
228{
229 struct dentry *dentry = filp->f_path.dentry;
230 struct inode *inode = dentry->d_inode;
231 struct task_struct *p = get_proc_task(inode);
232 struct files_struct *files;
233 unsigned int fd, ino;
234 int retval;
235
236 retval = -ENOENT;
237 if (!p)
238 goto out_no_task;
239 retval = 0;
240
241 fd = filp->f_pos;
242 switch (fd) {
243 case 0:
244 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
245 goto out;
246 filp->f_pos++;
247 case 1:
248 ino = parent_ino(dentry);
249 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
250 goto out;
251 filp->f_pos++;
252 default:
253 files = get_files_struct(p);
254 if (!files)
255 goto out;
256 rcu_read_lock();
257 for (fd = filp->f_pos - 2;
258 fd < files_fdtable(files)->max_fds;
259 fd++, filp->f_pos++) {
260 char name[PROC_NUMBUF];
261 int len;
262 int rv;
263
264 if (!fcheck_files(files, fd))
265 continue;
266 rcu_read_unlock();
267
268 len = snprintf(name, sizeof(name), "%d", fd);
269 rv = proc_fill_cache(filp, dirent, filldir,
270 name, len, instantiate, p,
271 (void *)(unsigned long)fd);
272 if (rv < 0)
273 goto out_fd_loop;
274 rcu_read_lock();
275 }
276 rcu_read_unlock();
277out_fd_loop:
278 put_files_struct(files);
279 }
280out:
281 put_task_struct(p);
282out_no_task:
283 return retval;
284}
285
286static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
287{
288 return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
289}
290
291const struct file_operations proc_fd_operations = {
292 .read = generic_read_dir,
293 .readdir = proc_readfd,
294 .llseek = default_llseek,
295};
296
297static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
298 unsigned int flags)
299{
300 return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
301}
302
303
304
305
306
307int proc_fd_permission(struct inode *inode, int mask)
308{
309 int rv = generic_permission(inode, mask);
310 if (rv == 0)
311 return 0;
312 if (task_tgid(current) == proc_pid(inode))
313 rv = 0;
314 return rv;
315}
316
317const struct inode_operations proc_fd_inode_operations = {
318 .lookup = proc_lookupfd,
319 .permission = proc_fd_permission,
320 .setattr = proc_setattr,
321};
322
323static struct dentry *
324proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry,
325 struct task_struct *task, const void *ptr)
326{
327 struct dentry *error = ERR_PTR(-ENOENT);
328 unsigned fd = (unsigned long)ptr;
329 struct proc_inode *ei;
330 struct inode *inode;
331
332 inode = proc_pid_make_inode(dir->i_sb, task, S_IFREG | S_IRUSR);
333 if (!inode)
334 goto out;
335
336 ei = PROC_I(inode);
337 ei->fd = fd;
338
339 inode->i_fop = &proc_fdinfo_file_operations;
340
341 d_set_d_op(dentry, &tid_fd_dentry_operations);
342 d_add(dentry, inode);
343
344
345 if (tid_fd_revalidate(dentry, 0))
346 error = NULL;
347 out:
348 return error;
349}
350
351static struct dentry *
352proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
353{
354 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
355}
356
357static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
358{
359 return proc_readfd_common(filp, dirent, filldir,
360 proc_fdinfo_instantiate);
361}
362
363const struct inode_operations proc_fdinfo_inode_operations = {
364 .lookup = proc_lookupfdinfo,
365 .setattr = proc_setattr,
366};
367
368const struct file_operations proc_fdinfo_operations = {
369 .read = generic_read_dir,
370 .readdir = proc_readfdinfo,
371 .llseek = default_llseek,
372};
373