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