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