Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/export.h>
0003 #include <linux/sched/signal.h>
0004 #include <linux/sched/task.h>
0005 #include <linux/fs.h>
0006 #include <linux/path.h>
0007 #include <linux/slab.h>
0008 #include <linux/fs_struct.h>
0009 #include "internal.h"
0010 
0011 /*
0012  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
0013  * It can block.
0014  */
0015 void set_fs_root(struct fs_struct *fs, const struct path *path)
0016 {
0017     struct path old_root;
0018 
0019     path_get(path);
0020     spin_lock(&fs->lock);
0021     write_seqcount_begin(&fs->seq);
0022     old_root = fs->root;
0023     fs->root = *path;
0024     write_seqcount_end(&fs->seq);
0025     spin_unlock(&fs->lock);
0026     if (old_root.dentry)
0027         path_put(&old_root);
0028 }
0029 
0030 /*
0031  * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
0032  * It can block.
0033  */
0034 void set_fs_pwd(struct fs_struct *fs, const struct path *path)
0035 {
0036     struct path old_pwd;
0037 
0038     path_get(path);
0039     spin_lock(&fs->lock);
0040     write_seqcount_begin(&fs->seq);
0041     old_pwd = fs->pwd;
0042     fs->pwd = *path;
0043     write_seqcount_end(&fs->seq);
0044     spin_unlock(&fs->lock);
0045 
0046     if (old_pwd.dentry)
0047         path_put(&old_pwd);
0048 }
0049 
0050 static inline int replace_path(struct path *p, const struct path *old, const struct path *new)
0051 {
0052     if (likely(p->dentry != old->dentry || p->mnt != old->mnt))
0053         return 0;
0054     *p = *new;
0055     return 1;
0056 }
0057 
0058 void chroot_fs_refs(const struct path *old_root, const struct path *new_root)
0059 {
0060     struct task_struct *g, *p;
0061     struct fs_struct *fs;
0062     int count = 0;
0063 
0064     read_lock(&tasklist_lock);
0065     do_each_thread(g, p) {
0066         task_lock(p);
0067         fs = p->fs;
0068         if (fs) {
0069             int hits = 0;
0070             spin_lock(&fs->lock);
0071             write_seqcount_begin(&fs->seq);
0072             hits += replace_path(&fs->root, old_root, new_root);
0073             hits += replace_path(&fs->pwd, old_root, new_root);
0074             write_seqcount_end(&fs->seq);
0075             while (hits--) {
0076                 count++;
0077                 path_get(new_root);
0078             }
0079             spin_unlock(&fs->lock);
0080         }
0081         task_unlock(p);
0082     } while_each_thread(g, p);
0083     read_unlock(&tasklist_lock);
0084     while (count--)
0085         path_put(old_root);
0086 }
0087 
0088 void free_fs_struct(struct fs_struct *fs)
0089 {
0090     path_put(&fs->root);
0091     path_put(&fs->pwd);
0092     kmem_cache_free(fs_cachep, fs);
0093 }
0094 
0095 void exit_fs(struct task_struct *tsk)
0096 {
0097     struct fs_struct *fs = tsk->fs;
0098 
0099     if (fs) {
0100         int kill;
0101         task_lock(tsk);
0102         spin_lock(&fs->lock);
0103         tsk->fs = NULL;
0104         kill = !--fs->users;
0105         spin_unlock(&fs->lock);
0106         task_unlock(tsk);
0107         if (kill)
0108             free_fs_struct(fs);
0109     }
0110 }
0111 
0112 struct fs_struct *copy_fs_struct(struct fs_struct *old)
0113 {
0114     struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
0115     /* We don't need to lock fs - think why ;-) */
0116     if (fs) {
0117         fs->users = 1;
0118         fs->in_exec = 0;
0119         spin_lock_init(&fs->lock);
0120         seqcount_spinlock_init(&fs->seq, &fs->lock);
0121         fs->umask = old->umask;
0122 
0123         spin_lock(&old->lock);
0124         fs->root = old->root;
0125         path_get(&fs->root);
0126         fs->pwd = old->pwd;
0127         path_get(&fs->pwd);
0128         spin_unlock(&old->lock);
0129     }
0130     return fs;
0131 }
0132 
0133 int unshare_fs_struct(void)
0134 {
0135     struct fs_struct *fs = current->fs;
0136     struct fs_struct *new_fs = copy_fs_struct(fs);
0137     int kill;
0138 
0139     if (!new_fs)
0140         return -ENOMEM;
0141 
0142     task_lock(current);
0143     spin_lock(&fs->lock);
0144     kill = !--fs->users;
0145     current->fs = new_fs;
0146     spin_unlock(&fs->lock);
0147     task_unlock(current);
0148 
0149     if (kill)
0150         free_fs_struct(fs);
0151 
0152     return 0;
0153 }
0154 EXPORT_SYMBOL_GPL(unshare_fs_struct);
0155 
0156 int current_umask(void)
0157 {
0158     return current->fs->umask;
0159 }
0160 EXPORT_SYMBOL(current_umask);
0161 
0162 /* to be mentioned only in INIT_TASK */
0163 struct fs_struct init_fs = {
0164     .users      = 1,
0165     .lock       = __SPIN_LOCK_UNLOCKED(init_fs.lock),
0166     .seq        = SEQCNT_SPINLOCK_ZERO(init_fs.seq, &init_fs.lock),
0167     .umask      = 0022,
0168 };