Branch data Line data Source code
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 : 390 : void set_fs_root(struct fs_struct *fs, const struct path *path) 16 : : { 17 : 390 : struct path old_root; 18 : : 19 : 390 : path_get(path); 20 : 390 : spin_lock(&fs->lock); 21 : 390 : write_seqcount_begin(&fs->seq); 22 : 390 : old_root = fs->root; 23 : 390 : fs->root = *path; 24 : 390 : write_seqcount_end(&fs->seq); 25 : 390 : spin_unlock(&fs->lock); 26 [ + + ]: 390 : if (old_root.dentry) 27 : 312 : path_put(&old_root); 28 : 390 : } 29 : : 30 : : /* 31 : : * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. 32 : : * It can block. 33 : : */ 34 : 277134 : void set_fs_pwd(struct fs_struct *fs, const struct path *path) 35 : : { 36 : 277134 : struct path old_pwd; 37 : : 38 : 277134 : path_get(path); 39 : 277134 : spin_lock(&fs->lock); 40 : 277134 : write_seqcount_begin(&fs->seq); 41 : 277134 : old_pwd = fs->pwd; 42 : 277134 : fs->pwd = *path; 43 : 277134 : write_seqcount_end(&fs->seq); 44 : 277134 : spin_unlock(&fs->lock); 45 : : 46 [ + + ]: 277134 : if (old_pwd.dentry) 47 : 277056 : path_put(&old_pwd); 48 : 277134 : } 49 : : 50 : 0 : static inline int replace_path(struct path *p, const struct path *old, const struct path *new) 51 : : { 52 [ # # # # ]: 0 : if (likely(p->dentry != old->dentry || p->mnt != old->mnt)) 53 : : return 0; 54 : 0 : *p = *new; 55 : 0 : return 1; 56 : : } 57 : : 58 : 0 : void chroot_fs_refs(const struct path *old_root, const struct path *new_root) 59 : : { 60 : 0 : struct task_struct *g, *p; 61 : 0 : struct fs_struct *fs; 62 : 0 : int count = 0; 63 : : 64 : 0 : read_lock(&tasklist_lock); 65 [ # # ]: 0 : do_each_thread(g, p) { 66 : 0 : task_lock(p); 67 : 0 : fs = p->fs; 68 [ # # ]: 0 : if (fs) { 69 : 0 : int hits = 0; 70 : 0 : spin_lock(&fs->lock); 71 : 0 : write_seqcount_begin(&fs->seq); 72 [ # # ]: 0 : hits += replace_path(&fs->root, old_root, new_root); 73 [ # # ]: 0 : hits += replace_path(&fs->pwd, old_root, new_root); 74 : 0 : write_seqcount_end(&fs->seq); 75 [ # # ]: 0 : while (hits--) { 76 : 0 : count++; 77 : 0 : path_get(new_root); 78 : : } 79 : 0 : spin_unlock(&fs->lock); 80 : : } 81 : 0 : task_unlock(p); 82 [ # # ]: 0 : } while_each_thread(g, p); 83 : 0 : read_unlock(&tasklist_lock); 84 [ # # ]: 0 : while (count--) 85 : 0 : path_put(old_root); 86 : 0 : } 87 : : 88 : 75419 : void free_fs_struct(struct fs_struct *fs) 89 : : { 90 : 75419 : path_put(&fs->root); 91 : 75419 : path_put(&fs->pwd); 92 : 75419 : kmem_cache_free(fs_cachep, fs); 93 : 75419 : } 94 : : 95 : 77369 : void exit_fs(struct task_struct *tsk) 96 : : { 97 : 77369 : struct fs_struct *fs = tsk->fs; 98 : : 99 [ + - ]: 77369 : if (fs) { 100 : 77369 : int kill; 101 : 77369 : task_lock(tsk); 102 : 77369 : spin_lock(&fs->lock); 103 : 77369 : tsk->fs = NULL; 104 : 77369 : kill = !--fs->users; 105 : 77369 : spin_unlock(&fs->lock); 106 : 77369 : task_unlock(tsk); 107 [ + + ]: 77369 : if (kill) 108 : 75419 : free_fs_struct(fs); 109 : : } 110 : 77369 : } 111 : : 112 : 77208 : struct fs_struct *copy_fs_struct(struct fs_struct *old) 113 : : { 114 : 77208 : struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); 115 : : /* We don't need to lock fs - think why ;-) */ 116 [ + - ]: 77208 : if (fs) { 117 : 77208 : fs->users = 1; 118 : 77208 : fs->in_exec = 0; 119 : 77208 : spin_lock_init(&fs->lock); 120 : 77208 : seqcount_init(&fs->seq); 121 : 77208 : fs->umask = old->umask; 122 : : 123 : 77208 : spin_lock(&old->lock); 124 : 77208 : fs->root = old->root; 125 : 77208 : path_get(&fs->root); 126 : 77208 : fs->pwd = old->pwd; 127 : 77208 : path_get(&fs->pwd); 128 : 77208 : spin_unlock(&old->lock); 129 : : } 130 : 77208 : return fs; 131 : : } 132 : : 133 : 0 : int unshare_fs_struct(void) 134 : : { 135 : 0 : struct fs_struct *fs = current->fs; 136 : 0 : struct fs_struct *new_fs = copy_fs_struct(fs); 137 : 0 : int kill; 138 : : 139 [ # # ]: 0 : if (!new_fs) 140 : : return -ENOMEM; 141 : : 142 : 0 : task_lock(current); 143 : 0 : spin_lock(&fs->lock); 144 : 0 : kill = !--fs->users; 145 : 0 : current->fs = new_fs; 146 : 0 : spin_unlock(&fs->lock); 147 : 0 : task_unlock(current); 148 : : 149 [ # # ]: 0 : if (kill) 150 : 0 : free_fs_struct(fs); 151 : : 152 : : return 0; 153 : : } 154 : : EXPORT_SYMBOL_GPL(unshare_fs_struct); 155 : : 156 : 93593 : int current_umask(void) 157 : : { 158 : 93593 : 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 : : };