.. | .. |
---|
6 | 6 | #include <linux/fdtable.h> |
---|
7 | 7 | #include <linux/namei.h> |
---|
8 | 8 | #include <linux/pid.h> |
---|
| 9 | +#include <linux/ptrace.h> |
---|
9 | 10 | #include <linux/security.h> |
---|
10 | 11 | #include <linux/file.h> |
---|
11 | 12 | #include <linux/seq_file.h> |
---|
.. | .. |
---|
53 | 54 | if (ret) |
---|
54 | 55 | return ret; |
---|
55 | 56 | |
---|
56 | | - seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n", |
---|
| 57 | + seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\nino:\t%lu\n", |
---|
57 | 58 | (long long)file->f_pos, f_flags, |
---|
58 | | - real_mount(file->f_path.mnt)->mnt_id); |
---|
| 59 | + real_mount(file->f_path.mnt)->mnt_id, |
---|
| 60 | + file_inode(file)->i_ino); |
---|
59 | 61 | |
---|
60 | 62 | show_fd_locks(m, file, files); |
---|
61 | 63 | if (seq_has_overflowed(m)) |
---|
.. | .. |
---|
69 | 71 | return 0; |
---|
70 | 72 | } |
---|
71 | 73 | |
---|
| 74 | +static int proc_fdinfo_access_allowed(struct inode *inode) |
---|
| 75 | +{ |
---|
| 76 | + bool allowed = false; |
---|
| 77 | + struct task_struct *task = get_proc_task(inode); |
---|
| 78 | + |
---|
| 79 | + if (!task) |
---|
| 80 | + return -ESRCH; |
---|
| 81 | + |
---|
| 82 | + allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); |
---|
| 83 | + put_task_struct(task); |
---|
| 84 | + |
---|
| 85 | + if (!allowed) |
---|
| 86 | + return -EACCES; |
---|
| 87 | + |
---|
| 88 | + return 0; |
---|
| 89 | +} |
---|
| 90 | + |
---|
72 | 91 | static int seq_fdinfo_open(struct inode *inode, struct file *file) |
---|
73 | 92 | { |
---|
| 93 | + int ret = proc_fdinfo_access_allowed(inode); |
---|
| 94 | + |
---|
| 95 | + if (ret) |
---|
| 96 | + return ret; |
---|
| 97 | + |
---|
74 | 98 | return single_open(file, seq_show, inode); |
---|
75 | 99 | } |
---|
76 | 100 | |
---|
.. | .. |
---|
325 | 349 | struct proc_inode *ei; |
---|
326 | 350 | struct inode *inode; |
---|
327 | 351 | |
---|
328 | | - inode = proc_pid_make_inode(dentry->d_sb, task, S_IFREG | S_IRUSR); |
---|
| 352 | + inode = proc_pid_make_inode(dentry->d_sb, task, S_IFREG | S_IRUGO); |
---|
329 | 353 | if (!inode) |
---|
330 | 354 | return ERR_PTR(-ENOENT); |
---|
331 | 355 | |
---|
.. | .. |
---|
351 | 375 | proc_fdinfo_instantiate); |
---|
352 | 376 | } |
---|
353 | 377 | |
---|
| 378 | +static int proc_open_fdinfo(struct inode *inode, struct file *file) |
---|
| 379 | +{ |
---|
| 380 | + int ret = proc_fdinfo_access_allowed(inode); |
---|
| 381 | + |
---|
| 382 | + if (ret) |
---|
| 383 | + return ret; |
---|
| 384 | + |
---|
| 385 | + return 0; |
---|
| 386 | +} |
---|
| 387 | + |
---|
354 | 388 | const struct inode_operations proc_fdinfo_inode_operations = { |
---|
355 | 389 | .lookup = proc_lookupfdinfo, |
---|
356 | 390 | .setattr = proc_setattr, |
---|
357 | 391 | }; |
---|
358 | 392 | |
---|
359 | 393 | const struct file_operations proc_fdinfo_operations = { |
---|
| 394 | + .open = proc_open_fdinfo, |
---|
360 | 395 | .read = generic_read_dir, |
---|
361 | 396 | .iterate_shared = proc_readfdinfo, |
---|
362 | 397 | .llseek = generic_file_llseek, |
---|