LCOV - code coverage report
Current view: top level - fs/proc - fd.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 147 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 16 0.0 %

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

Generated by: LCOV version 1.14