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 task_lock(task); 32 files = task->files; 33 if (files) { 34 unsigned int fd = proc_fd(m->private); 35 36 spin_lock(&files->file_lock); 37 file = files_lookup_fd_locked(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 } 50 task_unlock(task); 51 put_task_struct(task); 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() never deferences files so a stale value is safe */ 61 show_fd_locks(m, file, files); 62 if (seq_has_overflowed(m)) 63 goto out; 64 65 if (file->f_op->show_fdinfo) 66 file->f_op->show_fdinfo(m, file); 67 68 out: 69 fput(file); 70 return 0; 71 } 72 73 static int seq_fdinfo_open(struct inode *inode, struct file *file) 74 { 75 return single_open(file, seq_show, inode); 76 } 77 78 static const struct file_operations proc_fdinfo_file_operations = { 79 .open = seq_fdinfo_open, 80 .read = seq_read, 81 .llseek = seq_lseek, 82 .release = single_release, 83 }; 84 85 static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode) 86 { 87 struct file *file; 88 89 rcu_read_lock(); 90 file = task_lookup_fd_rcu(task, fd); 91 if (file) 92 *mode = file->f_mode; 93 rcu_read_unlock(); 94 return !!file; 95 } 96 97 static void tid_fd_update_inode(struct task_struct *task, struct inode *inode, 98 fmode_t f_mode) 99 { 100 task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid); 101 102 if (S_ISLNK(inode->i_mode)) { 103 unsigned i_mode = S_IFLNK; 104 if (f_mode & FMODE_READ) 105 i_mode |= S_IRUSR | S_IXUSR; 106 if (f_mode & FMODE_WRITE) 107 i_mode |= S_IWUSR | S_IXUSR; 108 inode->i_mode = i_mode; 109 } 110 security_task_to_inode(task, inode); 111 } 112 113 static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) 114 { 115 struct task_struct *task; 116 struct inode *inode; 117 unsigned int fd; 118 119 if (flags & LOOKUP_RCU) 120 return -ECHILD; 121 122 inode = d_inode(dentry); 123 task = get_proc_task(inode); 124 fd = proc_fd(inode); 125 126 if (task) { 127 fmode_t f_mode; 128 if (tid_fd_mode(task, fd, &f_mode)) { 129 tid_fd_update_inode(task, inode, f_mode); 130 put_task_struct(task); 131 return 1; 132 } 133 put_task_struct(task); 134 } 135 return 0; 136 } 137 138 static const struct dentry_operations tid_fd_dentry_operations = { 139 .d_revalidate = tid_fd_revalidate, 140 .d_delete = pid_delete_dentry, 141 }; 142 143 static int proc_fd_link(struct dentry *dentry, struct path *path) 144 { 145 struct task_struct *task; 146 int ret = -ENOENT; 147 148 task = get_proc_task(d_inode(dentry)); 149 if (task) { 150 unsigned int fd = proc_fd(d_inode(dentry)); 151 struct file *fd_file; 152 153 fd_file = fget_task(task, fd); 154 if (fd_file) { 155 *path = fd_file->f_path; 156 path_get(&fd_file->f_path); 157 ret = 0; 158 fput(fd_file); 159 } 160 put_task_struct(task); 161 } 162 163 return ret; 164 } 165 166 struct fd_data { 167 fmode_t mode; 168 unsigned fd; 169 }; 170 171 static struct dentry *proc_fd_instantiate(struct dentry *dentry, 172 struct task_struct *task, const void *ptr) 173 { 174 const struct fd_data *data = ptr; 175 struct proc_inode *ei; 176 struct inode *inode; 177 178 inode = proc_pid_make_inode(dentry->d_sb, task, S_IFLNK); 179 if (!inode) 180 return ERR_PTR(-ENOENT); 181 182 ei = PROC_I(inode); 183 ei->fd = data->fd; 184 185 inode->i_op = &proc_pid_link_inode_operations; 186 inode->i_size = 64; 187 188 ei->op.proc_get_link = proc_fd_link; 189 tid_fd_update_inode(task, inode, data->mode); 190 191 d_set_d_op(dentry, &tid_fd_dentry_operations); 192 return d_splice_alias(inode, dentry); 193 } 194 195 static struct dentry *proc_lookupfd_common(struct inode *dir, 196 struct dentry *dentry, 197 instantiate_t instantiate) 198 { 199 struct task_struct *task = get_proc_task(dir); 200 struct fd_data data = {.fd = name_to_int(&dentry->d_name)}; 201 struct dentry *result = ERR_PTR(-ENOENT); 202 203 if (!task) 204 goto out_no_task; 205 if (data.fd == ~0U) 206 goto out; 207 if (!tid_fd_mode(task, data.fd, &data.mode)) 208 goto out; 209 210 result = instantiate(dentry, task, &data); 211 out: 212 put_task_struct(task); 213 out_no_task: 214 return result; 215 } 216 217 static int proc_readfd_common(struct file *file, struct dir_context *ctx, 218 instantiate_t instantiate) 219 { 220 struct task_struct *p = get_proc_task(file_inode(file)); 221 unsigned int fd; 222 223 if (!p) 224 return -ENOENT; 225 226 if (!dir_emit_dots(file, ctx)) 227 goto out; 228 229 rcu_read_lock(); 230 for (fd = ctx->pos - 2;; fd++) { 231 struct file *f; 232 struct fd_data data; 233 char name[10 + 1]; 234 unsigned int len; 235 236 f = task_lookup_next_fd_rcu(p, &fd); 237 ctx->pos = fd + 2LL; 238 if (!f) 239 break; 240 data.mode = f->f_mode; 241 rcu_read_unlock(); 242 data.fd = fd; 243 244 len = snprintf(name, sizeof(name), "%u", fd); 245 if (!proc_fill_cache(file, ctx, 246 name, len, instantiate, p, 247 &data)) 248 goto out; 249 cond_resched(); 250 rcu_read_lock(); 251 } 252 rcu_read_unlock(); 253 out: 254 put_task_struct(p); 255 return 0; 256 } 257 258 static int proc_readfd(struct file *file, struct dir_context *ctx) 259 { 260 return proc_readfd_common(file, ctx, proc_fd_instantiate); 261 } 262 263 const struct file_operations proc_fd_operations = { 264 .read = generic_read_dir, 265 .iterate_shared = proc_readfd, 266 .llseek = generic_file_llseek, 267 }; 268 269 static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, 270 unsigned int flags) 271 { 272 return proc_lookupfd_common(dir, dentry, proc_fd_instantiate); 273 } 274 275 /* 276 * /proc/pid/fd needs a special permission handler so that a process can still 277 * access /proc/self/fd after it has executed a setuid(). 278 */ 279 int proc_fd_permission(struct user_namespace *mnt_userns, 280 struct inode *inode, int mask) 281 { 282 struct task_struct *p; 283 int rv; 284 285 rv = generic_permission(&init_user_ns, inode, mask); 286 if (rv == 0) 287 return rv; 288 289 rcu_read_lock(); 290 p = pid_task(proc_pid(inode), PIDTYPE_PID); 291 if (p && same_thread_group(p, current)) 292 rv = 0; 293 rcu_read_unlock(); 294 295 return rv; 296 } 297 298 const struct inode_operations proc_fd_inode_operations = { 299 .lookup = proc_lookupfd, 300 .permission = proc_fd_permission, 301 .setattr = proc_setattr, 302 }; 303 304 static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry, 305 struct task_struct *task, const void *ptr) 306 { 307 const struct fd_data *data = ptr; 308 struct proc_inode *ei; 309 struct inode *inode; 310 311 inode = proc_pid_make_inode(dentry->d_sb, task, S_IFREG | S_IRUSR); 312 if (!inode) 313 return ERR_PTR(-ENOENT); 314 315 ei = PROC_I(inode); 316 ei->fd = data->fd; 317 318 inode->i_fop = &proc_fdinfo_file_operations; 319 tid_fd_update_inode(task, inode, 0); 320 321 d_set_d_op(dentry, &tid_fd_dentry_operations); 322 return d_splice_alias(inode, dentry); 323 } 324 325 static struct dentry * 326 proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags) 327 { 328 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); 329 } 330 331 static int proc_readfdinfo(struct file *file, struct dir_context *ctx) 332 { 333 return proc_readfd_common(file, ctx, 334 proc_fdinfo_instantiate); 335 } 336 337 const struct inode_operations proc_fdinfo_inode_operations = { 338 .lookup = proc_lookupfdinfo, 339 .setattr = proc_setattr, 340 }; 341 342 const struct file_operations proc_fdinfo_operations = { 343 .read = generic_read_dir, 344 .iterate_shared = proc_readfdinfo, 345 .llseek = generic_file_llseek, 346 }; 347