1120945Snectar// SPDX-License-Identifier: GPL-2.0-only 2233294Sstas#include <linux/export.h> 3233294Sstas#include <linux/sched/signal.h> 4233294Sstas#include <linux/sched/task.h> 5120945Snectar#include <linux/fs.h> 6233294Sstas#include <linux/path.h> 7233294Sstas#include <linux/slab.h> 8233294Sstas#include <linux/fs_struct.h> 9120945Snectar#include "internal.h" 10233294Sstas 11233294Sstas/* 12120945Snectar * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. 13233294Sstas * It can block. 14233294Sstas */ 15233294Sstasvoid set_fs_root(struct fs_struct *fs, const struct path *path) 16120945Snectar{ 17233294Sstas struct path old_root; 18233294Sstas 19233294Sstas path_get(path); 20120945Snectar spin_lock(&fs->lock); 21233294Sstas write_seqcount_begin(&fs->seq); 22233294Sstas old_root = fs->root; 23233294Sstas fs->root = *path; 24233294Sstas write_seqcount_end(&fs->seq); 25233294Sstas spin_unlock(&fs->lock); 26233294Sstas if (old_root.dentry) 27233294Sstas path_put(&old_root); 28233294Sstas} 29233294Sstas 30233294Sstas/* 31233294Sstas * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. 32120945Snectar * It can block. 33120945Snectar */ 34233294Sstasvoid set_fs_pwd(struct fs_struct *fs, const struct path *path) 35120945Snectar{ 36120945Snectar struct path old_pwd; 37120945Snectar 38120945Snectar path_get(path); 39178825Sdfr spin_lock(&fs->lock); 40178825Sdfr write_seqcount_begin(&fs->seq); 41233294Sstas old_pwd = fs->pwd; 42120945Snectar fs->pwd = *path; 43120945Snectar write_seqcount_end(&fs->seq); 44120945Snectar spin_unlock(&fs->lock); 45120945Snectar 46120945Snectar if (old_pwd.dentry) 47120945Snectar path_put(&old_pwd); 48178825Sdfr} 49178825Sdfr 50178825Sdfrstatic inline int replace_path(struct path *p, const struct path *old, const struct path *new) 51178825Sdfr{ 52178825Sdfr if (likely(p->dentry != old->dentry || p->mnt != old->mnt)) 53178825Sdfr return 0; 54178825Sdfr *p = *new; 55178825Sdfr return 1; 56178825Sdfr} 57178825Sdfr 58178825Sdfrvoid chroot_fs_refs(const struct path *old_root, const struct path *new_root) 59178825Sdfr{ 60178825Sdfr struct task_struct *g, *p; 61178825Sdfr struct fs_struct *fs; 62178825Sdfr int count = 0; 63178825Sdfr 64178825Sdfr read_lock(&tasklist_lock); 65178825Sdfr for_each_process_thread(g, p) { 66178825Sdfr task_lock(p); 67178825Sdfr fs = p->fs; 68120945Snectar if (fs) { 69120945Snectar int hits = 0; 70120945Snectar spin_lock(&fs->lock); 71120945Snectar write_seqcount_begin(&fs->seq); 72120945Snectar hits += replace_path(&fs->root, old_root, new_root); 73120945Snectar hits += replace_path(&fs->pwd, old_root, new_root); 74120945Snectar write_seqcount_end(&fs->seq); 75120945Snectar while (hits--) { 76120945Snectar count++; 77120945Snectar path_get(new_root); 78178825Sdfr } 79120945Snectar spin_unlock(&fs->lock); 80120945Snectar } 81120945Snectar task_unlock(p); 82120945Snectar } 83120945Snectar read_unlock(&tasklist_lock); 84120945Snectar while (count--) 85178825Sdfr path_put(old_root); 86120945Snectar} 87120945Snectar 88120945Snectarvoid free_fs_struct(struct fs_struct *fs) 89120945Snectar{ 90120945Snectar path_put(&fs->root); 91120945Snectar path_put(&fs->pwd); 92120945Snectar kmem_cache_free(fs_cachep, fs); 93120945Snectar} 94120945Snectar 95120945Snectarvoid exit_fs(struct task_struct *tsk) 96120945Snectar{ 97120945Snectar struct fs_struct *fs = tsk->fs; 98120945Snectar 99120945Snectar if (fs) { 100120945Snectar int kill; 101120945Snectar task_lock(tsk); 102120945Snectar spin_lock(&fs->lock); 103120945Snectar tsk->fs = NULL; 104120945Snectar kill = !--fs->users; 105178825Sdfr spin_unlock(&fs->lock); 106120945Snectar task_unlock(tsk); 107178825Sdfr if (kill) 108233294Sstas free_fs_struct(fs); 109233294Sstas } 110233294Sstas} 111178825Sdfr 112178825Sdfrstruct fs_struct *copy_fs_struct(struct fs_struct *old) 113233294Sstas{ 114120945Snectar struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); 115178825Sdfr /* We don't need to lock fs - think why ;-) */ 116178825Sdfr if (fs) { 117178825Sdfr fs->users = 1; 118178825Sdfr fs->in_exec = 0; 119178825Sdfr spin_lock_init(&fs->lock); 120178825Sdfr seqcount_spinlock_init(&fs->seq, &fs->lock); 121178825Sdfr fs->umask = old->umask; 122178825Sdfr 123178825Sdfr spin_lock(&old->lock); 124178825Sdfr fs->root = old->root; 125178825Sdfr path_get(&fs->root); 126178825Sdfr fs->pwd = old->pwd; 127233294Sstas path_get(&fs->pwd); 128233294Sstas spin_unlock(&old->lock); 129178825Sdfr } 130233294Sstas return fs; 131233294Sstas} 132233294Sstas 133233294Sstasint unshare_fs_struct(void) 134233294Sstas{ 135233294Sstas struct fs_struct *fs = current->fs; 136233294Sstas struct fs_struct *new_fs = copy_fs_struct(fs); 137233294Sstas int kill; 138233294Sstas 139233294Sstas if (!new_fs) 140120945Snectar return -ENOMEM; 141120945Snectar 142120945Snectar task_lock(current); 143120945Snectar 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} 154EXPORT_SYMBOL_GPL(unshare_fs_struct); 155 156int current_umask(void) 157{ 158 return current->fs->umask; 159} 160EXPORT_SYMBOL(current_umask); 161 162/* to be mentioned only in INIT_TASK */ 163struct fs_struct init_fs = { 164 .users = 1, 165 .lock = __SPIN_LOCK_UNLOCKED(init_fs.lock), 166 .seq = SEQCNT_SPINLOCK_ZERO(init_fs.seq, &init_fs.lock), 167 .umask = 0022, 168}; 169