Back to home page

LXR

 
 

    


0001 #include <linux/mount.h>
0002 #include <linux/file.h>
0003 #include <linux/fs.h>
0004 #include <linux/proc_ns.h>
0005 #include <linux/magic.h>
0006 #include <linux/ktime.h>
0007 #include <linux/seq_file.h>
0008 #include <linux/user_namespace.h>
0009 #include <linux/nsfs.h>
0010 
0011 static struct vfsmount *nsfs_mnt;
0012 
0013 static long ns_ioctl(struct file *filp, unsigned int ioctl,
0014             unsigned long arg);
0015 static const struct file_operations ns_file_operations = {
0016     .llseek     = no_llseek,
0017     .unlocked_ioctl = ns_ioctl,
0018 };
0019 
0020 static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
0021 {
0022     struct inode *inode = d_inode(dentry);
0023     const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
0024 
0025     return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
0026         ns_ops->name, inode->i_ino);
0027 }
0028 
0029 static void ns_prune_dentry(struct dentry *dentry)
0030 {
0031     struct inode *inode = d_inode(dentry);
0032     if (inode) {
0033         struct ns_common *ns = inode->i_private;
0034         atomic_long_set(&ns->stashed, 0);
0035     }
0036 }
0037 
0038 const struct dentry_operations ns_dentry_operations =
0039 {
0040     .d_prune    = ns_prune_dentry,
0041     .d_delete   = always_delete_dentry,
0042     .d_dname    = ns_dname,
0043 };
0044 
0045 static void nsfs_evict(struct inode *inode)
0046 {
0047     struct ns_common *ns = inode->i_private;
0048     clear_inode(inode);
0049     ns->ops->put(ns);
0050 }
0051 
0052 static void *__ns_get_path(struct path *path, struct ns_common *ns)
0053 {
0054     struct vfsmount *mnt = nsfs_mnt;
0055     struct qstr qname = { .name = "", };
0056     struct dentry *dentry;
0057     struct inode *inode;
0058     unsigned long d;
0059 
0060     rcu_read_lock();
0061     d = atomic_long_read(&ns->stashed);
0062     if (!d)
0063         goto slow;
0064     dentry = (struct dentry *)d;
0065     if (!lockref_get_not_dead(&dentry->d_lockref))
0066         goto slow;
0067     rcu_read_unlock();
0068     ns->ops->put(ns);
0069 got_it:
0070     path->mnt = mntget(mnt);
0071     path->dentry = dentry;
0072     return NULL;
0073 slow:
0074     rcu_read_unlock();
0075     inode = new_inode_pseudo(mnt->mnt_sb);
0076     if (!inode) {
0077         ns->ops->put(ns);
0078         return ERR_PTR(-ENOMEM);
0079     }
0080     inode->i_ino = ns->inum;
0081     inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
0082     inode->i_flags |= S_IMMUTABLE;
0083     inode->i_mode = S_IFREG | S_IRUGO;
0084     inode->i_fop = &ns_file_operations;
0085     inode->i_private = ns;
0086 
0087     dentry = d_alloc_pseudo(mnt->mnt_sb, &qname);
0088     if (!dentry) {
0089         iput(inode);
0090         return ERR_PTR(-ENOMEM);
0091     }
0092     d_instantiate(dentry, inode);
0093     dentry->d_fsdata = (void *)ns->ops;
0094     d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry);
0095     if (d) {
0096         d_delete(dentry);   /* make sure ->d_prune() does nothing */
0097         dput(dentry);
0098         cpu_relax();
0099         return ERR_PTR(-EAGAIN);
0100     }
0101     goto got_it;
0102 }
0103 
0104 void *ns_get_path(struct path *path, struct task_struct *task,
0105             const struct proc_ns_operations *ns_ops)
0106 {
0107     struct ns_common *ns;
0108     void *ret;
0109 
0110 again:
0111     ns = ns_ops->get(task);
0112     if (!ns)
0113         return ERR_PTR(-ENOENT);
0114 
0115     ret = __ns_get_path(path, ns);
0116     if (IS_ERR(ret) && PTR_ERR(ret) == -EAGAIN)
0117         goto again;
0118     return ret;
0119 }
0120 
0121 int open_related_ns(struct ns_common *ns,
0122            struct ns_common *(*get_ns)(struct ns_common *ns))
0123 {
0124     struct path path = {};
0125     struct file *f;
0126     void *err;
0127     int fd;
0128 
0129     fd = get_unused_fd_flags(O_CLOEXEC);
0130     if (fd < 0)
0131         return fd;
0132 
0133     while (1) {
0134         struct ns_common *relative;
0135 
0136         relative = get_ns(ns);
0137         if (IS_ERR(relative)) {
0138             put_unused_fd(fd);
0139             return PTR_ERR(relative);
0140         }
0141 
0142         err = __ns_get_path(&path, relative);
0143         if (IS_ERR(err) && PTR_ERR(err) == -EAGAIN)
0144             continue;
0145         break;
0146     }
0147     if (IS_ERR(err)) {
0148         put_unused_fd(fd);
0149         return PTR_ERR(err);
0150     }
0151 
0152     f = dentry_open(&path, O_RDONLY, current_cred());
0153     path_put(&path);
0154     if (IS_ERR(f)) {
0155         put_unused_fd(fd);
0156         fd = PTR_ERR(f);
0157     } else
0158         fd_install(fd, f);
0159 
0160     return fd;
0161 }
0162 
0163 static long ns_ioctl(struct file *filp, unsigned int ioctl,
0164             unsigned long arg)
0165 {
0166     struct ns_common *ns = get_proc_ns(file_inode(filp));
0167 
0168     switch (ioctl) {
0169     case NS_GET_USERNS:
0170         return open_related_ns(ns, ns_get_owner);
0171     case NS_GET_PARENT:
0172         if (!ns->ops->get_parent)
0173             return -EINVAL;
0174         return open_related_ns(ns, ns->ops->get_parent);
0175     default:
0176         return -ENOTTY;
0177     }
0178 }
0179 
0180 int ns_get_name(char *buf, size_t size, struct task_struct *task,
0181             const struct proc_ns_operations *ns_ops)
0182 {
0183     struct ns_common *ns;
0184     int res = -ENOENT;
0185     ns = ns_ops->get(task);
0186     if (ns) {
0187         res = snprintf(buf, size, "%s:[%u]", ns_ops->name, ns->inum);
0188         ns_ops->put(ns);
0189     }
0190     return res;
0191 }
0192 
0193 struct file *proc_ns_fget(int fd)
0194 {
0195     struct file *file;
0196 
0197     file = fget(fd);
0198     if (!file)
0199         return ERR_PTR(-EBADF);
0200 
0201     if (file->f_op != &ns_file_operations)
0202         goto out_invalid;
0203 
0204     return file;
0205 
0206 out_invalid:
0207     fput(file);
0208     return ERR_PTR(-EINVAL);
0209 }
0210 
0211 static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry)
0212 {
0213     struct inode *inode = d_inode(dentry);
0214     const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
0215 
0216     seq_printf(seq, "%s:[%lu]", ns_ops->name, inode->i_ino);
0217     return 0;
0218 }
0219 
0220 static const struct super_operations nsfs_ops = {
0221     .statfs = simple_statfs,
0222     .evict_inode = nsfs_evict,
0223     .show_path = nsfs_show_path,
0224 };
0225 static struct dentry *nsfs_mount(struct file_system_type *fs_type,
0226             int flags, const char *dev_name, void *data)
0227 {
0228     return mount_pseudo(fs_type, "nsfs:", &nsfs_ops,
0229             &ns_dentry_operations, NSFS_MAGIC);
0230 }
0231 static struct file_system_type nsfs = {
0232     .name = "nsfs",
0233     .mount = nsfs_mount,
0234     .kill_sb = kill_anon_super,
0235 };
0236 
0237 void __init nsfs_init(void)
0238 {
0239     nsfs_mnt = kern_mount(&nsfs);
0240     if (IS_ERR(nsfs_mnt))
0241         panic("can't set nsfs up\n");
0242     nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
0243 }