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