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