1 #include <linux/mount.h> 2 #include <linux/file.h> 3 #include <linux/fs.h> 4 #include <linux/proc_ns.h> 5 #include <linux/magic.h> 6 #include <linux/ktime.h> 7 #include <linux/seq_file.h> 8 #include <linux/user_namespace.h> 9 #include <linux/nsfs.h> 10 11 static struct vfsmount *nsfs_mnt; 12 13 static long ns_ioctl(struct file *filp, unsigned int ioctl, 14 unsigned long arg); 15 static const struct file_operations ns_file_operations = { 16 .llseek = no_llseek, 17 .unlocked_ioctl = ns_ioctl, 18 }; 19 20 static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) 21 { 22 struct inode *inode = d_inode(dentry); 23 const struct proc_ns_operations *ns_ops = dentry->d_fsdata; 24 25 return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]", 26 ns_ops->name, inode->i_ino); 27 } 28 29 static void ns_prune_dentry(struct dentry *dentry) 30 { 31 struct inode *inode = d_inode(dentry); 32 if (inode) { 33 struct ns_common *ns = inode->i_private; 34 atomic_long_set(&ns->stashed, 0); 35 } 36 } 37 38 const struct dentry_operations ns_dentry_operations = 39 { 40 .d_prune = ns_prune_dentry, 41 .d_delete = always_delete_dentry, 42 .d_dname = ns_dname, 43 }; 44 45 static void nsfs_evict(struct inode *inode) 46 { 47 struct ns_common *ns = inode->i_private; 48 clear_inode(inode); 49 ns->ops->put(ns); 50 } 51 52 static void *__ns_get_path(struct path *path, struct ns_common *ns) 53 { 54 struct vfsmount *mnt = nsfs_mnt; 55 struct qstr qname = { .name = "", }; 56 struct dentry *dentry; 57 struct inode *inode; 58 unsigned long d; 59 60 rcu_read_lock(); 61 d = atomic_long_read(&ns->stashed); 62 if (!d) 63 goto slow; 64 dentry = (struct dentry *)d; 65 if (!lockref_get_not_dead(&dentry->d_lockref)) 66 goto slow; 67 rcu_read_unlock(); 68 ns->ops->put(ns); 69 got_it: 70 path->mnt = mntget(mnt); 71 path->dentry = dentry; 72 return NULL; 73 slow: 74 rcu_read_unlock(); 75 inode = new_inode_pseudo(mnt->mnt_sb); 76 if (!inode) { 77 ns->ops->put(ns); 78 return ERR_PTR(-ENOMEM); 79 } 80 inode->i_ino = ns->inum; 81 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); 82 inode->i_flags |= S_IMMUTABLE; 83 inode->i_mode = S_IFREG | S_IRUGO; 84 inode->i_fop = &ns_file_operations; 85 inode->i_private = ns; 86 87 dentry = d_alloc_pseudo(mnt->mnt_sb, &qname); 88 if (!dentry) { 89 iput(inode); 90 return ERR_PTR(-ENOMEM); 91 } 92 d_instantiate(dentry, inode); 93 dentry->d_fsdata = (void *)ns->ops; 94 d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry); 95 if (d) { 96 d_delete(dentry); /* make sure ->d_prune() does nothing */ 97 dput(dentry); 98 cpu_relax(); 99 return ERR_PTR(-EAGAIN); 100 } 101 goto got_it; 102 } 103 104 void *ns_get_path(struct path *path, struct task_struct *task, 105 const struct proc_ns_operations *ns_ops) 106 { 107 struct ns_common *ns; 108 void *ret; 109 110 again: 111 ns = ns_ops->get(task); 112 if (!ns) 113 return ERR_PTR(-ENOENT); 114 115 ret = __ns_get_path(path, ns); 116 if (IS_ERR(ret) && PTR_ERR(ret) == -EAGAIN) 117 goto again; 118 return ret; 119 } 120 121 static int open_related_ns(struct ns_common *ns, 122 struct ns_common *(*get_ns)(struct ns_common *ns)) 123 { 124 struct path path = {}; 125 struct file *f; 126 void *err; 127 int fd; 128 129 fd = get_unused_fd_flags(O_CLOEXEC); 130 if (fd < 0) 131 return fd; 132 133 while (1) { 134 struct ns_common *relative; 135 136 relative = get_ns(ns); 137 if (IS_ERR(relative)) { 138 put_unused_fd(fd); 139 return PTR_ERR(relative); 140 } 141 142 err = __ns_get_path(&path, relative); 143 if (IS_ERR(err) && PTR_ERR(err) == -EAGAIN) 144 continue; 145 break; 146 } 147 if (IS_ERR(err)) { 148 put_unused_fd(fd); 149 return PTR_ERR(err); 150 } 151 152 f = dentry_open(&path, O_RDONLY, current_cred()); 153 path_put(&path); 154 if (IS_ERR(f)) { 155 put_unused_fd(fd); 156 fd = PTR_ERR(f); 157 } else 158 fd_install(fd, f); 159 160 return fd; 161 } 162 163 static long ns_ioctl(struct file *filp, unsigned int ioctl, 164 unsigned long arg) 165 { 166 struct ns_common *ns = get_proc_ns(file_inode(filp)); 167 168 switch (ioctl) { 169 case NS_GET_USERNS: 170 return open_related_ns(ns, ns_get_owner); 171 case NS_GET_PARENT: 172 if (!ns->ops->get_parent) 173 return -EINVAL; 174 return open_related_ns(ns, ns->ops->get_parent); 175 default: 176 return -ENOTTY; 177 } 178 } 179 180 int ns_get_name(char *buf, size_t size, struct task_struct *task, 181 const struct proc_ns_operations *ns_ops) 182 { 183 struct ns_common *ns; 184 int res = -ENOENT; 185 ns = ns_ops->get(task); 186 if (ns) { 187 res = snprintf(buf, size, "%s:[%u]", ns_ops->name, ns->inum); 188 ns_ops->put(ns); 189 } 190 return res; 191 } 192 193 struct file *proc_ns_fget(int fd) 194 { 195 struct file *file; 196 197 file = fget(fd); 198 if (!file) 199 return ERR_PTR(-EBADF); 200 201 if (file->f_op != &ns_file_operations) 202 goto out_invalid; 203 204 return file; 205 206 out_invalid: 207 fput(file); 208 return ERR_PTR(-EINVAL); 209 } 210 211 static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry) 212 { 213 struct inode *inode = d_inode(dentry); 214 const struct proc_ns_operations *ns_ops = dentry->d_fsdata; 215 216 seq_printf(seq, "%s:[%lu]", ns_ops->name, inode->i_ino); 217 return 0; 218 } 219 220 static const struct super_operations nsfs_ops = { 221 .statfs = simple_statfs, 222 .evict_inode = nsfs_evict, 223 .show_path = nsfs_show_path, 224 }; 225 static struct dentry *nsfs_mount(struct file_system_type *fs_type, 226 int flags, const char *dev_name, void *data) 227 { 228 return mount_pseudo(fs_type, "nsfs:", &nsfs_ops, 229 &ns_dentry_operations, NSFS_MAGIC); 230 } 231 static struct file_system_type nsfs = { 232 .name = "nsfs", 233 .mount = nsfs_mount, 234 .kill_sb = kill_anon_super, 235 }; 236 237 void __init nsfs_init(void) 238 { 239 nsfs_mnt = kern_mount(&nsfs); 240 if (IS_ERR(nsfs_mnt)) 241 panic("can't set nsfs up\n"); 242 nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER; 243 } 244