1 #include <linux/proc_fs.h> 2 #include <linux/nsproxy.h> 3 #include <linux/sched.h> 4 #include <linux/ptrace.h> 5 #include <linux/fs_struct.h> 6 #include <linux/mount.h> 7 #include <linux/path.h> 8 #include <linux/namei.h> 9 #include <linux/file.h> 10 #include <linux/utsname.h> 11 #include <net/net_namespace.h> 12 #include <linux/mnt_namespace.h> 13 #include <linux/ipc_namespace.h> 14 #include <linux/pid_namespace.h> 15 #include "internal.h" 16 17 18 static const struct proc_ns_operations *ns_entries[] = { 19 #ifdef CONFIG_NET_NS 20 &netns_operations, 21 #endif 22 #ifdef CONFIG_UTS_NS 23 &utsns_operations, 24 #endif 25 #ifdef CONFIG_IPC_NS 26 &ipcns_operations, 27 #endif 28 }; 29 30 static const struct file_operations ns_file_operations = { 31 .llseek = no_llseek, 32 }; 33 34 static struct dentry *proc_ns_instantiate(struct inode *dir, 35 struct dentry *dentry, struct task_struct *task, const void *ptr) 36 { 37 const struct proc_ns_operations *ns_ops = ptr; 38 struct inode *inode; 39 struct proc_inode *ei; 40 struct dentry *error = ERR_PTR(-ENOENT); 41 42 inode = proc_pid_make_inode(dir->i_sb, task); 43 if (!inode) 44 goto out; 45 46 ei = PROC_I(inode); 47 inode->i_mode = S_IFREG|S_IRUSR; 48 inode->i_fop = &ns_file_operations; 49 ei->ns_ops = ns_ops; 50 ei->ns = ns_ops->get(task); 51 if (!ei->ns) 52 goto out_iput; 53 54 dentry->d_op = &pid_dentry_operations; 55 d_add(dentry, inode); 56 /* Close the race of the process dying before we return the dentry */ 57 if (pid_revalidate(dentry, NULL)) 58 error = NULL; 59 out: 60 return error; 61 out_iput: 62 iput(inode); 63 goto out; 64 } 65 66 static int proc_ns_fill_cache(struct file *filp, void *dirent, 67 filldir_t filldir, struct task_struct *task, 68 const struct proc_ns_operations *ops) 69 { 70 return proc_fill_cache(filp, dirent, filldir, 71 ops->name, strlen(ops->name), 72 proc_ns_instantiate, task, ops); 73 } 74 75 static int proc_ns_dir_readdir(struct file *filp, void *dirent, 76 filldir_t filldir) 77 { 78 int i; 79 struct dentry *dentry = filp->f_path.dentry; 80 struct inode *inode = dentry->d_inode; 81 struct task_struct *task = get_proc_task(inode); 82 const struct proc_ns_operations **entry, **last; 83 ino_t ino; 84 int ret; 85 86 ret = -ENOENT; 87 if (!task) 88 goto out_no_task; 89 90 ret = -EPERM; 91 if (!ptrace_may_access(task, PTRACE_MODE_READ)) 92 goto out; 93 94 ret = 0; 95 i = filp->f_pos; 96 switch (i) { 97 case 0: 98 ino = inode->i_ino; 99 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) 100 goto out; 101 i++; 102 filp->f_pos++; 103 /* fall through */ 104 case 1: 105 ino = parent_ino(dentry); 106 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) 107 goto out; 108 i++; 109 filp->f_pos++; 110 /* fall through */ 111 default: 112 i -= 2; 113 if (i >= ARRAY_SIZE(ns_entries)) { 114 ret = 1; 115 goto out; 116 } 117 entry = ns_entries + i; 118 last = &ns_entries[ARRAY_SIZE(ns_entries) - 1]; 119 while (entry <= last) { 120 if (proc_ns_fill_cache(filp, dirent, filldir, 121 task, *entry) < 0) 122 goto out; 123 filp->f_pos++; 124 entry++; 125 } 126 } 127 128 ret = 1; 129 out: 130 put_task_struct(task); 131 out_no_task: 132 return ret; 133 } 134 135 const struct file_operations proc_ns_dir_operations = { 136 .read = generic_read_dir, 137 .readdir = proc_ns_dir_readdir, 138 }; 139 140 static struct dentry *proc_ns_dir_lookup(struct inode *dir, 141 struct dentry *dentry, struct nameidata *nd) 142 { 143 struct dentry *error; 144 struct task_struct *task = get_proc_task(dir); 145 const struct proc_ns_operations **entry, **last; 146 unsigned int len = dentry->d_name.len; 147 148 error = ERR_PTR(-ENOENT); 149 150 if (!task) 151 goto out_no_task; 152 153 error = ERR_PTR(-EPERM); 154 if (!ptrace_may_access(task, PTRACE_MODE_READ)) 155 goto out; 156 157 last = &ns_entries[ARRAY_SIZE(ns_entries) - 1]; 158 for (entry = ns_entries; entry <= last; entry++) { 159 if (strlen((*entry)->name) != len) 160 continue; 161 if (!memcmp(dentry->d_name.name, (*entry)->name, len)) 162 break; 163 } 164 error = ERR_PTR(-ENOENT); 165 if (entry > last) 166 goto out; 167 168 error = proc_ns_instantiate(dir, dentry, task, *entry); 169 out: 170 put_task_struct(task); 171 out_no_task: 172 return error; 173 } 174 175 const struct inode_operations proc_ns_dir_inode_operations = { 176 .lookup = proc_ns_dir_lookup, 177 .getattr = pid_getattr, 178 .setattr = proc_setattr, 179 }; 180 181 struct file *proc_ns_fget(int fd) 182 { 183 struct file *file; 184 185 file = fget(fd); 186 if (!file) 187 return ERR_PTR(-EBADF); 188 189 if (file->f_op != &ns_file_operations) 190 goto out_invalid; 191 192 return file; 193 194 out_invalid: 195 fput(file); 196 return ERR_PTR(-EINVAL); 197 } 198 199