root/fs/fs_struct.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_fs_root
  2. set_fs_pwd
  3. replace_path
  4. chroot_fs_refs
  5. free_fs_struct
  6. exit_fs
  7. copy_fs_struct
  8. unshare_fs_struct
  9. current_umask

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 #include <linux/export.h>
   3 #include <linux/sched/signal.h>
   4 #include <linux/sched/task.h>
   5 #include <linux/fs.h>
   6 #include <linux/path.h>
   7 #include <linux/slab.h>
   8 #include <linux/fs_struct.h>
   9 #include "internal.h"
  10 
  11 /*
  12  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
  13  * It can block.
  14  */
  15 void set_fs_root(struct fs_struct *fs, const struct path *path)
  16 {
  17         struct path old_root;
  18 
  19         path_get(path);
  20         spin_lock(&fs->lock);
  21         write_seqcount_begin(&fs->seq);
  22         old_root = fs->root;
  23         fs->root = *path;
  24         write_seqcount_end(&fs->seq);
  25         spin_unlock(&fs->lock);
  26         if (old_root.dentry)
  27                 path_put(&old_root);
  28 }
  29 
  30 /*
  31  * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
  32  * It can block.
  33  */
  34 void set_fs_pwd(struct fs_struct *fs, const struct path *path)
  35 {
  36         struct path old_pwd;
  37 
  38         path_get(path);
  39         spin_lock(&fs->lock);
  40         write_seqcount_begin(&fs->seq);
  41         old_pwd = fs->pwd;
  42         fs->pwd = *path;
  43         write_seqcount_end(&fs->seq);
  44         spin_unlock(&fs->lock);
  45 
  46         if (old_pwd.dentry)
  47                 path_put(&old_pwd);
  48 }
  49 
  50 static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
  51 {
  52         if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
  53                 return 0;
  54         *p = *new;
  55         return 1;
  56 }
  57 
  58 void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
  59 {
  60         struct task_struct *g, *p;
  61         struct fs_struct *fs;
  62         int count = 0;
  63 
  64         read_lock(&tasklist_lock);
  65         do_each_thread(g, p) {
  66                 task_lock(p);
  67                 fs = p->fs;
  68                 if (fs) {
  69                         int hits = 0;
  70                         spin_lock(&fs->lock);
  71                         write_seqcount_begin(&fs->seq);
  72                         hits += replace_path(&fs->root, old_root, new_root);
  73                         hits += replace_path(&fs->pwd, old_root, new_root);
  74                         write_seqcount_end(&fs->seq);
  75                         while (hits--) {
  76                                 count++;
  77                                 path_get(new_root);
  78                         }
  79                         spin_unlock(&fs->lock);
  80                 }
  81                 task_unlock(p);
  82         } while_each_thread(g, p);
  83         read_unlock(&tasklist_lock);
  84         while (count--)
  85                 path_put(old_root);
  86 }
  87 
  88 void free_fs_struct(struct fs_struct *fs)
  89 {
  90         path_put(&fs->root);
  91         path_put(&fs->pwd);
  92         kmem_cache_free(fs_cachep, fs);
  93 }
  94 
  95 void exit_fs(struct task_struct *tsk)
  96 {
  97         struct fs_struct *fs = tsk->fs;
  98 
  99         if (fs) {
 100                 int kill;
 101                 task_lock(tsk);
 102                 spin_lock(&fs->lock);
 103                 tsk->fs = NULL;
 104                 kill = !--fs->users;
 105                 spin_unlock(&fs->lock);
 106                 task_unlock(tsk);
 107                 if (kill)
 108                         free_fs_struct(fs);
 109         }
 110 }
 111 
 112 struct fs_struct *copy_fs_struct(struct fs_struct *old)
 113 {
 114         struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
 115         /* We don't need to lock fs - think why ;-) */
 116         if (fs) {
 117                 fs->users = 1;
 118                 fs->in_exec = 0;
 119                 spin_lock_init(&fs->lock);
 120                 seqcount_init(&fs->seq);
 121                 fs->umask = old->umask;
 122 
 123                 spin_lock(&old->lock);
 124                 fs->root = old->root;
 125                 path_get(&fs->root);
 126                 fs->pwd = old->pwd;
 127                 path_get(&fs->pwd);
 128                 spin_unlock(&old->lock);
 129         }
 130         return fs;
 131 }
 132 
 133 int unshare_fs_struct(void)
 134 {
 135         struct fs_struct *fs = current->fs;
 136         struct fs_struct *new_fs = copy_fs_struct(fs);
 137         int kill;
 138 
 139         if (!new_fs)
 140                 return -ENOMEM;
 141 
 142         task_lock(current);
 143         spin_lock(&fs->lock);
 144         kill = !--fs->users;
 145         current->fs = new_fs;
 146         spin_unlock(&fs->lock);
 147         task_unlock(current);
 148 
 149         if (kill)
 150                 free_fs_struct(fs);
 151 
 152         return 0;
 153 }
 154 EXPORT_SYMBOL_GPL(unshare_fs_struct);
 155 
 156 int current_umask(void)
 157 {
 158         return current->fs->umask;
 159 }
 160 EXPORT_SYMBOL(current_umask);
 161 
 162 /* to be mentioned only in INIT_TASK */
 163 struct fs_struct init_fs = {
 164         .users          = 1,
 165         .lock           = __SPIN_LOCK_UNLOCKED(init_fs.lock),
 166         .seq            = SEQCNT_ZERO(init_fs.seq),
 167         .umask          = 0022,
 168 };

/* [<][>][^][v][top][bottom][index][help] */