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/ptrace.h> 10 #include <linux/bitmap.h> 11 #include <linux/security.h> 12 #include <linux/file.h> 13 #include <linux/seq_file.h> 14 #include <linux/fs.h> 15 #include <linux/filelock.h> 16 17 #include <linux/proc_fs.h> 18 19 #include "../mount.h" 20 #include "internal.h" 21 #include "fd.h" 22 23 static int seq_show(struct seq_file *m, void *v) 24 { 25 struct files_struct *files = NULL; 26 int f_flags = 0, ret = -ENOENT; 27 struct file *file = NULL; 28 struct task_struct *task; 29 30 task = get_proc_task(m->private); 31 if (!task) 32 return -ENOENT; 33 34 task_lock(task); 35 files = task->files; 36 if (files) { 37 unsigned int fd = proc_fd(m->private); 38 39 spin_lock(&files->file_lock); 40 file = files_lookup_fd_locked(files, fd); 41 if (file) { 42 struct fdtable *fdt = files_fdtable(files); 43 44 f_flags = file->f_flags; 45 if (close_on_exec(fd, fdt)) 46 f_flags |= O_CLOEXEC; 47 48 get_file(file); 49 ret = 0; 50 } 51 spin_unlock(&files->file_lock); 52 } 53 task_unlock(task); 54 put_task_struct(task); 55 56 if (ret) 57 return ret; 58 59 seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\nino:\t%lu\n", 60 (long long)file->f_pos, f_flags, 61 real_mount(file->f_path.mnt)->mnt_id, 62 file_inode(file)->i_ino); 63 64 /* show_fd_locks() never deferences files so a stale value is safe */ 65 show_fd_locks(m, file, files); 66 if (seq_has_overflowed(m)) 67 goto out; 68 69 if (file->f_op->show_fdinfo) 70 file->f_op->show_fdinfo(m, file); 71 72 out: 73 fput(file); 74 return 0; 75 } 76 77 static int proc_fdinfo_access_allowed(struct inode *inode) 78 { 79 bool allowed = false; 80 struct task_struct *task = get_proc_task(inode); 81 82 if (!task) 83 return -ESRCH; 84 85 allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); 86 put_task_struct(task); 87 88 if (!allowed) 89 return -EACCES; 90 91 return 0; 92 } 93 94 static int seq_fdinfo_open(struct inode *inode, struct file *file) 95 { 96 int ret = proc_fdinfo_access_allowed(inode); 97 98 if (ret) 99 return ret; 100 101 return single_open(file, seq_show, inode); 102 } 103 104 static const struct file_operations proc_fdinfo_file_operations = { 105 .open = seq_fdinfo_open, 106 .read = seq_read, 107 .llseek = seq_lseek, 108 .release = single_release, 109 }; 110 111 static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode) 112 { 113 struct file *file; 114 115 rcu_read_lock(); 116 file = task_lookup_fdget_rcu(task, fd); 117 rcu_read_unlock(); 118 if (file) { 119 *mode = file->f_mode; 120 fput(file); 121 } 122 return !!file; 123 } 124 125 static void tid_fd_update_inode(struct task_struct *task, struct inode *inode, 126 fmode_t f_mode) 127 { 128 task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid); 129 130 if (S_ISLNK(inode->i_mode)) { 131 unsigned i_mode = S_IFLNK; 132 if (f_mode & FMODE_READ) 133 i_mode |= S_IRUSR | S_IXUSR; 134 if (f_mode & FMODE_WRITE) 135 i_mode |= S_IWUSR | S_IXUSR; 136 inode->i_mode = i_mode; 137 } 138 security_task_to_inode(task, inode); 139 } 140 141 static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) 142 { 143 struct task_struct *task; 144 struct inode *inode; 145 unsigned int fd; 146 147 if (flags & LOOKUP_RCU) 148 return -ECHILD; 149 150 inode = d_inode(dentry); 151 task = get_proc_task(inode); 152 fd = proc_fd(inode); 153 154 if (task) { 155 fmode_t f_mode; 156 if (tid_fd_mode(task, fd, &f_mode)) { 157 tid_fd_update_inode(task, inode, f_mode); 158 put_task_struct(task); 159 return 1; 160 } 161 put_task_struct(task); 162 } 163 return 0; 164 } 165 166 static const struct dentry_operations tid_fd_dentry_operations = { 167 .d_revalidate = tid_fd_revalidate, 168 .d_delete = pid_delete_dentry, 169 }; 170 171 static int proc_fd_link(struct dentry *dentry, struct path *path) 172 { 173 struct task_struct *task; 174 int ret = -ENOENT; 175 176 task = get_proc_task(d_inode(dentry)); 177 if (task) { 178 unsigned int fd = proc_fd(d_inode(dentry)); 179 struct file *fd_file; 180 181 fd_file = fget_task(task, fd); 182 if (fd_file) { 183 *path = fd_file->f_path; 184 path_get(&fd_file->f_path); 185 ret = 0; 186 fput(fd_file); 187 } 188 put_task_struct(task); 189 } 190 191 return ret; 192 } 193 194 struct fd_data { 195 fmode_t mode; 196 unsigned fd; 197 }; 198 199 static struct dentry *proc_fd_instantiate(struct dentry *dentry, 200 struct task_struct *task, const void *ptr) 201 { 202 const struct fd_data *data = ptr; 203 struct proc_inode *ei; 204 struct inode *inode; 205 206 inode = proc_pid_make_inode(dentry->d_sb, task, S_IFLNK); 207 if (!inode) 208 return ERR_PTR(-ENOENT); 209 210 ei = PROC_I(inode); 211 ei->fd = data->fd; 212 213 inode->i_op = &proc_pid_link_inode_operations; 214 inode->i_size = 64; 215 216 ei->op.proc_get_link = proc_fd_link; 217 tid_fd_update_inode(task, inode, data->mode); 218 219 d_set_d_op(dentry, &tid_fd_dentry_operations); 220 return d_splice_alias(inode, dentry); 221 } 222 223 static struct dentry *proc_lookupfd_common(struct inode *dir, 224 struct dentry *dentry, 225 instantiate_t instantiate) 226 { 227 struct task_struct *task = get_proc_task(dir); 228 struct fd_data data = {.fd = name_to_int(&dentry->d_name)}; 229 struct dentry *result = ERR_PTR(-ENOENT); 230 231 if (!task) 232 goto out_no_task; 233 if (data.fd == ~0U) 234 goto out; 235 if (!tid_fd_mode(task, data.fd, &data.mode)) 236 goto out; 237 238 result = instantiate(dentry, task, &data); 239 out: 240 put_task_struct(task); 241 out_no_task: 242 return result; 243 } 244 245 static int proc_readfd_common(struct file *file, struct dir_context *ctx, 246 instantiate_t instantiate) 247 { 248 struct task_struct *p = get_proc_task(file_inode(file)); 249 unsigned int fd; 250 251 if (!p) 252 return -ENOENT; 253 254 if (!dir_emit_dots(file, ctx)) 255 goto out; 256 257 rcu_read_lock(); 258 for (fd = ctx->pos - 2;; fd++) { 259 struct file *f; 260 struct fd_data data; 261 char name[10 + 1]; 262 unsigned int len; 263 264 f = task_lookup_next_fdget_rcu(p, &fd); 265 ctx->pos = fd + 2LL; 266 if (!f) 267 break; 268 data.mode = f->f_mode; 269 rcu_read_unlock(); 270 fput(f); 271 data.fd = fd; 272 273 len = snprintf(name, sizeof(name), "%u", fd); 274 if (!proc_fill_cache(file, ctx, 275 name, len, instantiate, p, 276 &data)) 277 goto out; 278 cond_resched(); 279 rcu_read_lock(); 280 } 281 rcu_read_unlock(); 282 out: 283 put_task_struct(p); 284 return 0; 285 } 286 287 static int proc_readfd_count(struct inode *inode, loff_t *count) 288 { 289 struct task_struct *p = get_proc_task(inode); 290 struct fdtable *fdt; 291 292 if (!p) 293 return -ENOENT; 294 295 task_lock(p); 296 if (p->files) { 297 rcu_read_lock(); 298 299 fdt = files_fdtable(p->files); 300 *count = bitmap_weight(fdt->open_fds, fdt->max_fds); 301 302 rcu_read_unlock(); 303 } 304 task_unlock(p); 305 306 put_task_struct(p); 307 308 return 0; 309 } 310 311 static int proc_readfd(struct file *file, struct dir_context *ctx) 312 { 313 return proc_readfd_common(file, ctx, proc_fd_instantiate); 314 } 315 316 const struct file_operations proc_fd_operations = { 317 .read = generic_read_dir, 318 .iterate_shared = proc_readfd, 319 .llseek = generic_file_llseek, 320 }; 321 322 static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, 323 unsigned int flags) 324 { 325 return proc_lookupfd_common(dir, dentry, proc_fd_instantiate); 326 } 327 328 /* 329 * /proc/pid/fd needs a special permission handler so that a process can still 330 * access /proc/self/fd after it has executed a setuid(). 331 */ 332 int proc_fd_permission(struct mnt_idmap *idmap, 333 struct inode *inode, int mask) 334 { 335 struct task_struct *p; 336 int rv; 337 338 rv = generic_permission(&nop_mnt_idmap, inode, mask); 339 if (rv == 0) 340 return rv; 341 342 rcu_read_lock(); 343 p = pid_task(proc_pid(inode), PIDTYPE_PID); 344 if (p && same_thread_group(p, current)) 345 rv = 0; 346 rcu_read_unlock(); 347 348 return rv; 349 } 350 351 static int proc_fd_getattr(struct mnt_idmap *idmap, 352 const struct path *path, struct kstat *stat, 353 u32 request_mask, unsigned int query_flags) 354 { 355 struct inode *inode = d_inode(path->dentry); 356 int rv = 0; 357 358 generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat); 359 360 /* If it's a directory, put the number of open fds there */ 361 if (S_ISDIR(inode->i_mode)) { 362 rv = proc_readfd_count(inode, &stat->size); 363 if (rv < 0) 364 return rv; 365 } 366 367 return rv; 368 } 369 370 const struct inode_operations proc_fd_inode_operations = { 371 .lookup = proc_lookupfd, 372 .permission = proc_fd_permission, 373 .getattr = proc_fd_getattr, 374 .setattr = proc_setattr, 375 }; 376 377 static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry, 378 struct task_struct *task, const void *ptr) 379 { 380 const struct fd_data *data = ptr; 381 struct proc_inode *ei; 382 struct inode *inode; 383 384 inode = proc_pid_make_inode(dentry->d_sb, task, S_IFREG | S_IRUGO); 385 if (!inode) 386 return ERR_PTR(-ENOENT); 387 388 ei = PROC_I(inode); 389 ei->fd = data->fd; 390 391 inode->i_fop = &proc_fdinfo_file_operations; 392 tid_fd_update_inode(task, inode, 0); 393 394 d_set_d_op(dentry, &tid_fd_dentry_operations); 395 return d_splice_alias(inode, dentry); 396 } 397 398 static struct dentry * 399 proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags) 400 { 401 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate); 402 } 403 404 static int proc_readfdinfo(struct file *file, struct dir_context *ctx) 405 { 406 return proc_readfd_common(file, ctx, 407 proc_fdinfo_instantiate); 408 } 409 410 static int proc_open_fdinfo(struct inode *inode, struct file *file) 411 { 412 int ret = proc_fdinfo_access_allowed(inode); 413 414 if (ret) 415 return ret; 416 417 return 0; 418 } 419 420 const struct inode_operations proc_fdinfo_inode_operations = { 421 .lookup = proc_lookupfdinfo, 422 .setattr = proc_setattr, 423 }; 424 425 const struct file_operations proc_fdinfo_operations = { 426 .open = proc_open_fdinfo, 427 .read = generic_read_dir, 428 .iterate_shared = proc_readfdinfo, 429 .llseek = generic_file_llseek, 430 }; 431