Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) };