LCOV - code coverage report
Current view: top level - fs/proc - fd.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 159 175 90.9 %
Date: 2021-04-22 12:43:58 Functions: 14 15 93.3 %

          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/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         139 : static int seq_show(struct seq_file *m, void *v)
      21             : {
      22         139 :         struct files_struct *files = NULL;
      23         139 :         int f_flags = 0, ret = -ENOENT;
      24         139 :         struct file *file = NULL;
      25         139 :         struct task_struct *task;
      26             : 
      27         139 :         task = get_proc_task(m->private);
      28         139 :         if (!task)
      29             :                 return -ENOENT;
      30             : 
      31         139 :         task_lock(task);
      32         139 :         files = task->files;
      33         139 :         if (files) {
      34         139 :                 unsigned int fd = proc_fd(m->private);
      35             : 
      36         139 :                 spin_lock(&files->file_lock);
      37         139 :                 file = files_lookup_fd_locked(files, fd);
      38         139 :                 if (file) {
      39         139 :                         struct fdtable *fdt = files_fdtable(files);
      40             : 
      41         139 :                         f_flags = file->f_flags;
      42         139 :                         if (close_on_exec(fd, fdt))
      43         139 :                                 f_flags |= O_CLOEXEC;
      44             : 
      45         139 :                         get_file(file);
      46         139 :                         ret = 0;
      47             :                 }
      48         139 :                 spin_unlock(&files->file_lock);
      49             :         }
      50         139 :         task_unlock(task);
      51         139 :         put_task_struct(task);
      52             : 
      53         139 :         if (ret)
      54             :                 return ret;
      55             : 
      56         139 :         seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n",
      57         139 :                    (long long)file->f_pos, f_flags,
      58         139 :                    real_mount(file->f_path.mnt)->mnt_id);
      59             : 
      60             :         /* show_fd_locks() never deferences files so a stale value is safe */
      61         139 :         show_fd_locks(m, file, files);
      62         139 :         if (seq_has_overflowed(m))
      63           0 :                 goto out;
      64             : 
      65         139 :         if (file->f_op->show_fdinfo)
      66           0 :                 file->f_op->show_fdinfo(m, file);
      67             : 
      68         139 : out:
      69         139 :         fput(file);
      70         139 :         return 0;
      71             : }
      72             : 
      73         139 : static int seq_fdinfo_open(struct inode *inode, struct file *file)
      74             : {
      75         139 :         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         244 : static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode)
      86             : {
      87         244 :         struct file *file;
      88             : 
      89         244 :         rcu_read_lock();
      90         244 :         file = task_lookup_fd_rcu(task, fd);
      91         244 :         if (file)
      92         244 :                 *mode = file->f_mode;
      93         244 :         rcu_read_unlock();
      94         244 :         return !!file;
      95             : }
      96             : 
      97        2850 : static void tid_fd_update_inode(struct task_struct *task, struct inode *inode,
      98             :                                 fmode_t f_mode)
      99             : {
     100        2850 :         task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);
     101             : 
     102        2850 :         if (S_ISLNK(inode->i_mode)) {
     103        2711 :                 unsigned i_mode = S_IFLNK;
     104        2711 :                 if (f_mode & FMODE_READ)
     105        2331 :                         i_mode |= S_IRUSR | S_IXUSR;
     106        2711 :                 if (f_mode & FMODE_WRITE)
     107        1962 :                         i_mode |= S_IWUSR | S_IXUSR;
     108        2711 :                 inode->i_mode = i_mode;
     109             :         }
     110        2850 :         security_task_to_inode(task, inode);
     111        2850 : }
     112             : 
     113         188 : static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
     114             : {
     115         188 :         struct task_struct *task;
     116         188 :         struct inode *inode;
     117         188 :         unsigned int fd;
     118             : 
     119         188 :         if (flags & LOOKUP_RCU)
     120             :                 return -ECHILD;
     121             : 
     122         188 :         inode = d_inode(dentry);
     123         188 :         task = get_proc_task(inode);
     124         188 :         fd = proc_fd(inode);
     125             : 
     126         188 :         if (task) {
     127         188 :                 fmode_t f_mode;
     128         188 :                 if (tid_fd_mode(task, fd, &f_mode)) {
     129         188 :                         tid_fd_update_inode(task, inode, f_mode);
     130         188 :                         put_task_struct(task);
     131         188 :                         return 1;
     132             :                 }
     133           0 :                 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         105 : static int proc_fd_link(struct dentry *dentry, struct path *path)
     144             : {
     145         105 :         struct task_struct *task;
     146         105 :         int ret = -ENOENT;
     147             : 
     148         105 :         task = get_proc_task(d_inode(dentry));
     149         105 :         if (task) {
     150         105 :                 unsigned int fd = proc_fd(d_inode(dentry));
     151         105 :                 struct file *fd_file;
     152             : 
     153         105 :                 fd_file = fget_task(task, fd);
     154         105 :                 if (fd_file) {
     155         105 :                         *path = fd_file->f_path;
     156         105 :                         path_get(&fd_file->f_path);
     157         105 :                         ret = 0;
     158         105 :                         fput(fd_file);
     159             :                 }
     160         105 :                 put_task_struct(task);
     161             :         }
     162             : 
     163         105 :         return ret;
     164             : }
     165             : 
     166             : struct fd_data {
     167             :         fmode_t mode;
     168             :         unsigned fd;
     169             : };
     170             : 
     171        2648 : static struct dentry *proc_fd_instantiate(struct dentry *dentry,
     172             :         struct task_struct *task, const void *ptr)
     173             : {
     174        2648 :         const struct fd_data *data = ptr;
     175        2648 :         struct proc_inode *ei;
     176        2648 :         struct inode *inode;
     177             : 
     178        2648 :         inode = proc_pid_make_inode(dentry->d_sb, task, S_IFLNK);
     179        2648 :         if (!inode)
     180        2648 :                 return ERR_PTR(-ENOENT);
     181             : 
     182        2648 :         ei = PROC_I(inode);
     183        2648 :         ei->fd = data->fd;
     184             : 
     185        2648 :         inode->i_op = &proc_pid_link_inode_operations;
     186        2648 :         inode->i_size = 64;
     187             : 
     188        2648 :         ei->op.proc_get_link = proc_fd_link;
     189        2648 :         tid_fd_update_inode(task, inode, data->mode);
     190             : 
     191        2648 :         d_set_d_op(dentry, &tid_fd_dentry_operations);
     192        2648 :         return d_splice_alias(inode, dentry);
     193             : }
     194             : 
     195          56 : static struct dentry *proc_lookupfd_common(struct inode *dir,
     196             :                                            struct dentry *dentry,
     197             :                                            instantiate_t instantiate)
     198             : {
     199          56 :         struct task_struct *task = get_proc_task(dir);
     200          56 :         struct fd_data data = {.fd = name_to_int(&dentry->d_name)};
     201          56 :         struct dentry *result = ERR_PTR(-ENOENT);
     202             : 
     203          56 :         if (!task)
     204           0 :                 goto out_no_task;
     205          56 :         if (data.fd == ~0U)
     206           0 :                 goto out;
     207          56 :         if (!tid_fd_mode(task, data.fd, &data.mode))
     208           0 :                 goto out;
     209             : 
     210          56 :         result = instantiate(dentry, task, &data);
     211          56 : out:
     212          56 :         put_task_struct(task);
     213          56 : out_no_task:
     214          56 :         return result;
     215             : }
     216             : 
     217         320 : static int proc_readfd_common(struct file *file, struct dir_context *ctx,
     218             :                               instantiate_t instantiate)
     219             : {
     220         320 :         struct task_struct *p = get_proc_task(file_inode(file));
     221         320 :         unsigned int fd;
     222             : 
     223         320 :         if (!p)
     224             :                 return -ENOENT;
     225             : 
     226         320 :         if (!dir_emit_dots(file, ctx))
     227           0 :                 goto out;
     228             : 
     229         320 :         rcu_read_lock();
     230        3157 :         for (fd = ctx->pos - 2;; fd++) {
     231        3157 :                 struct file *f;
     232        3157 :                 struct fd_data data;
     233        3157 :                 char name[10 + 1];
     234        3157 :                 unsigned int len;
     235             : 
     236        3157 :                 f = task_lookup_next_fd_rcu(p, &fd);
     237        3157 :                 ctx->pos = fd + 2LL;
     238        3157 :                 if (!f)
     239             :                         break;
     240        2837 :                 data.mode = f->f_mode;
     241        2837 :                 rcu_read_unlock();
     242        2837 :                 data.fd = fd;
     243             : 
     244        2837 :                 len = snprintf(name, sizeof(name), "%u", fd);
     245        2837 :                 if (!proc_fill_cache(file, ctx,
     246             :                                      name, len, instantiate, p,
     247             :                                      &data))
     248           0 :                         goto out;
     249        2837 :                 cond_resched();
     250        2837 :                 rcu_read_lock();
     251             :         }
     252         320 :         rcu_read_unlock();
     253         320 : out:
     254         320 :         put_task_struct(p);
     255         320 :         return 0;
     256             : }
     257             : 
     258         320 : static int proc_readfd(struct file *file, struct dir_context *ctx)
     259             : {
     260         320 :         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          42 : static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
     270             :                                     unsigned int flags)
     271             : {
     272          42 :         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         268 : int proc_fd_permission(struct user_namespace *mnt_userns,
     280             :                        struct inode *inode, int mask)
     281             : {
     282         268 :         struct task_struct *p;
     283         268 :         int rv;
     284             : 
     285         268 :         rv = generic_permission(&init_user_ns, inode, mask);
     286         268 :         if (rv == 0)
     287             :                 return rv;
     288             : 
     289           0 :         rcu_read_lock();
     290           0 :         p = pid_task(proc_pid(inode), PIDTYPE_PID);
     291           0 :         if (p && same_thread_group(p, current))
     292           0 :                 rv = 0;
     293           0 :         rcu_read_unlock();
     294             : 
     295           0 :         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          14 : static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry,
     305             :         struct task_struct *task, const void *ptr)
     306             : {
     307          14 :         const struct fd_data *data = ptr;
     308          14 :         struct proc_inode *ei;
     309          14 :         struct inode *inode;
     310             : 
     311          14 :         inode = proc_pid_make_inode(dentry->d_sb, task, S_IFREG | S_IRUSR);
     312          14 :         if (!inode)
     313          14 :                 return ERR_PTR(-ENOENT);
     314             : 
     315          14 :         ei = PROC_I(inode);
     316          14 :         ei->fd = data->fd;
     317             : 
     318          14 :         inode->i_fop = &proc_fdinfo_file_operations;
     319          14 :         tid_fd_update_inode(task, inode, 0);
     320             : 
     321          14 :         d_set_d_op(dentry, &tid_fd_dentry_operations);
     322          14 :         return d_splice_alias(inode, dentry);
     323             : }
     324             : 
     325             : static struct dentry *
     326          14 : proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
     327             : {
     328          14 :         return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
     329             : }
     330             : 
     331           0 : static int proc_readfdinfo(struct file *file, struct dir_context *ctx)
     332             : {
     333           0 :         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             : };

Generated by: LCOV version 1.14