0001
0002 #include <linux/mount.h>
0003 #include <linux/pseudo_fs.h>
0004 #include <linux/file.h>
0005 #include <linux/fs.h>
0006 #include <linux/proc_fs.h>
0007 #include <linux/proc_ns.h>
0008 #include <linux/magic.h>
0009 #include <linux/ktime.h>
0010 #include <linux/seq_file.h>
0011 #include <linux/user_namespace.h>
0012 #include <linux/nsfs.h>
0013 #include <linux/uaccess.h>
0014
0015 #include "internal.h"
0016
0017 static struct vfsmount *nsfs_mnt;
0018
0019 static long ns_ioctl(struct file *filp, unsigned int ioctl,
0020 unsigned long arg);
0021 static const struct file_operations ns_file_operations = {
0022 .llseek = no_llseek,
0023 .unlocked_ioctl = ns_ioctl,
0024 };
0025
0026 static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
0027 {
0028 struct inode *inode = d_inode(dentry);
0029 const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
0030
0031 return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
0032 ns_ops->name, inode->i_ino);
0033 }
0034
0035 static void ns_prune_dentry(struct dentry *dentry)
0036 {
0037 struct inode *inode = d_inode(dentry);
0038 if (inode) {
0039 struct ns_common *ns = inode->i_private;
0040 atomic_long_set(&ns->stashed, 0);
0041 }
0042 }
0043
0044 const struct dentry_operations ns_dentry_operations =
0045 {
0046 .d_prune = ns_prune_dentry,
0047 .d_delete = always_delete_dentry,
0048 .d_dname = ns_dname,
0049 };
0050
0051 static void nsfs_evict(struct inode *inode)
0052 {
0053 struct ns_common *ns = inode->i_private;
0054 clear_inode(inode);
0055 ns->ops->put(ns);
0056 }
0057
0058 static int __ns_get_path(struct path *path, struct ns_common *ns)
0059 {
0060 struct vfsmount *mnt = nsfs_mnt;
0061 struct dentry *dentry;
0062 struct inode *inode;
0063 unsigned long d;
0064
0065 rcu_read_lock();
0066 d = atomic_long_read(&ns->stashed);
0067 if (!d)
0068 goto slow;
0069 dentry = (struct dentry *)d;
0070 if (!lockref_get_not_dead(&dentry->d_lockref))
0071 goto slow;
0072 rcu_read_unlock();
0073 ns->ops->put(ns);
0074 got_it:
0075 path->mnt = mntget(mnt);
0076 path->dentry = dentry;
0077 return 0;
0078 slow:
0079 rcu_read_unlock();
0080 inode = new_inode_pseudo(mnt->mnt_sb);
0081 if (!inode) {
0082 ns->ops->put(ns);
0083 return -ENOMEM;
0084 }
0085 inode->i_ino = ns->inum;
0086 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
0087 inode->i_flags |= S_IMMUTABLE;
0088 inode->i_mode = S_IFREG | S_IRUGO;
0089 inode->i_fop = &ns_file_operations;
0090 inode->i_private = ns;
0091
0092 dentry = d_alloc_anon(mnt->mnt_sb);
0093 if (!dentry) {
0094 iput(inode);
0095 return -ENOMEM;
0096 }
0097 d_instantiate(dentry, inode);
0098 dentry->d_fsdata = (void *)ns->ops;
0099 d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry);
0100 if (d) {
0101 d_delete(dentry);
0102 dput(dentry);
0103 cpu_relax();
0104 return -EAGAIN;
0105 }
0106 goto got_it;
0107 }
0108
0109 int ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
0110 void *private_data)
0111 {
0112 int ret;
0113
0114 do {
0115 struct ns_common *ns = ns_get_cb(private_data);
0116 if (!ns)
0117 return -ENOENT;
0118 ret = __ns_get_path(path, ns);
0119 } while (ret == -EAGAIN);
0120
0121 return ret;
0122 }
0123
0124 struct ns_get_path_task_args {
0125 const struct proc_ns_operations *ns_ops;
0126 struct task_struct *task;
0127 };
0128
0129 static struct ns_common *ns_get_path_task(void *private_data)
0130 {
0131 struct ns_get_path_task_args *args = private_data;
0132
0133 return args->ns_ops->get(args->task);
0134 }
0135
0136 int ns_get_path(struct path *path, struct task_struct *task,
0137 const struct proc_ns_operations *ns_ops)
0138 {
0139 struct ns_get_path_task_args args = {
0140 .ns_ops = ns_ops,
0141 .task = task,
0142 };
0143
0144 return ns_get_path_cb(path, ns_get_path_task, &args);
0145 }
0146
0147 int open_related_ns(struct ns_common *ns,
0148 struct ns_common *(*get_ns)(struct ns_common *ns))
0149 {
0150 struct path path = {};
0151 struct file *f;
0152 int err;
0153 int fd;
0154
0155 fd = get_unused_fd_flags(O_CLOEXEC);
0156 if (fd < 0)
0157 return fd;
0158
0159 do {
0160 struct ns_common *relative;
0161
0162 relative = get_ns(ns);
0163 if (IS_ERR(relative)) {
0164 put_unused_fd(fd);
0165 return PTR_ERR(relative);
0166 }
0167
0168 err = __ns_get_path(&path, relative);
0169 } while (err == -EAGAIN);
0170
0171 if (err) {
0172 put_unused_fd(fd);
0173 return err;
0174 }
0175
0176 f = dentry_open(&path, O_RDONLY, current_cred());
0177 path_put(&path);
0178 if (IS_ERR(f)) {
0179 put_unused_fd(fd);
0180 fd = PTR_ERR(f);
0181 } else
0182 fd_install(fd, f);
0183
0184 return fd;
0185 }
0186 EXPORT_SYMBOL_GPL(open_related_ns);
0187
0188 static long ns_ioctl(struct file *filp, unsigned int ioctl,
0189 unsigned long arg)
0190 {
0191 struct user_namespace *user_ns;
0192 struct ns_common *ns = get_proc_ns(file_inode(filp));
0193 uid_t __user *argp;
0194 uid_t uid;
0195
0196 switch (ioctl) {
0197 case NS_GET_USERNS:
0198 return open_related_ns(ns, ns_get_owner);
0199 case NS_GET_PARENT:
0200 if (!ns->ops->get_parent)
0201 return -EINVAL;
0202 return open_related_ns(ns, ns->ops->get_parent);
0203 case NS_GET_NSTYPE:
0204 return ns->ops->type;
0205 case NS_GET_OWNER_UID:
0206 if (ns->ops->type != CLONE_NEWUSER)
0207 return -EINVAL;
0208 user_ns = container_of(ns, struct user_namespace, ns);
0209 argp = (uid_t __user *) arg;
0210 uid = from_kuid_munged(current_user_ns(), user_ns->owner);
0211 return put_user(uid, argp);
0212 default:
0213 return -ENOTTY;
0214 }
0215 }
0216
0217 int ns_get_name(char *buf, size_t size, struct task_struct *task,
0218 const struct proc_ns_operations *ns_ops)
0219 {
0220 struct ns_common *ns;
0221 int res = -ENOENT;
0222 const char *name;
0223 ns = ns_ops->get(task);
0224 if (ns) {
0225 name = ns_ops->real_ns_name ? : ns_ops->name;
0226 res = snprintf(buf, size, "%s:[%u]", name, ns->inum);
0227 ns_ops->put(ns);
0228 }
0229 return res;
0230 }
0231
0232 bool proc_ns_file(const struct file *file)
0233 {
0234 return file->f_op == &ns_file_operations;
0235 }
0236
0237 struct file *proc_ns_fget(int fd)
0238 {
0239 struct file *file;
0240
0241 file = fget(fd);
0242 if (!file)
0243 return ERR_PTR(-EBADF);
0244
0245 if (file->f_op != &ns_file_operations)
0246 goto out_invalid;
0247
0248 return file;
0249
0250 out_invalid:
0251 fput(file);
0252 return ERR_PTR(-EINVAL);
0253 }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino)
0264 {
0265 return (ns->inum == ino) && (nsfs_mnt->mnt_sb->s_dev == dev);
0266 }
0267
0268
0269 static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry)
0270 {
0271 struct inode *inode = d_inode(dentry);
0272 const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
0273
0274 seq_printf(seq, "%s:[%lu]", ns_ops->name, inode->i_ino);
0275 return 0;
0276 }
0277
0278 static const struct super_operations nsfs_ops = {
0279 .statfs = simple_statfs,
0280 .evict_inode = nsfs_evict,
0281 .show_path = nsfs_show_path,
0282 };
0283
0284 static int nsfs_init_fs_context(struct fs_context *fc)
0285 {
0286 struct pseudo_fs_context *ctx = init_pseudo(fc, NSFS_MAGIC);
0287 if (!ctx)
0288 return -ENOMEM;
0289 ctx->ops = &nsfs_ops;
0290 ctx->dops = &ns_dentry_operations;
0291 return 0;
0292 }
0293
0294 static struct file_system_type nsfs = {
0295 .name = "nsfs",
0296 .init_fs_context = nsfs_init_fs_context,
0297 .kill_sb = kill_anon_super,
0298 };
0299
0300 void __init nsfs_init(void)
0301 {
0302 nsfs_mnt = kern_mount(&nsfs);
0303 if (IS_ERR(nsfs_mnt))
0304 panic("can't set nsfs up\n");
0305 nsfs_mnt->mnt_sb->s_flags &= ~SB_NOUSER;
0306 }