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