linux/fs/proc/namespaces.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/proc_fs.h>
   3#include <linux/nsproxy.h>
   4#include <linux/ptrace.h>
   5#include <linux/namei.h>
   6#include <linux/file.h>
   7#include <linux/utsname.h>
   8#include <net/net_namespace.h>
   9#include <linux/ipc_namespace.h>
  10#include <linux/pid_namespace.h>
  11#include <linux/user_namespace.h>
  12#include "internal.h"
  13
  14
  15static const struct proc_ns_operations *ns_entries[] = {
  16#ifdef CONFIG_NET_NS
  17        &netns_operations,
  18#endif
  19#ifdef CONFIG_UTS_NS
  20        &utsns_operations,
  21#endif
  22#ifdef CONFIG_IPC_NS
  23        &ipcns_operations,
  24#endif
  25#ifdef CONFIG_PID_NS
  26        &pidns_operations,
  27        &pidns_for_children_operations,
  28#endif
  29#ifdef CONFIG_USER_NS
  30        &userns_operations,
  31#endif
  32        &mntns_operations,
  33#ifdef CONFIG_CGROUPS
  34        &cgroupns_operations,
  35#endif
  36#ifdef CONFIG_TIME_NS
  37        &timens_operations,
  38        &timens_for_children_operations,
  39#endif
  40};
  41
  42static const char *proc_ns_get_link(struct dentry *dentry,
  43                                    struct inode *inode,
  44                                    struct delayed_call *done)
  45{
  46        const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
  47        struct task_struct *task;
  48        struct path ns_path;
  49        int error = -EACCES;
  50
  51        if (!dentry)
  52                return ERR_PTR(-ECHILD);
  53
  54        task = get_proc_task(inode);
  55        if (!task)
  56                return ERR_PTR(-EACCES);
  57
  58        if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
  59                goto out;
  60
  61        error = ns_get_path(&ns_path, task, ns_ops);
  62        if (error)
  63                goto out;
  64
  65        error = nd_jump_link(&ns_path);
  66out:
  67        put_task_struct(task);
  68        return ERR_PTR(error);
  69}
  70
  71static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int buflen)
  72{
  73        struct inode *inode = d_inode(dentry);
  74        const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
  75        struct task_struct *task;
  76        char name[50];
  77        int res = -EACCES;
  78
  79        task = get_proc_task(inode);
  80        if (!task)
  81                return res;
  82
  83        if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
  84                res = ns_get_name(name, sizeof(name), task, ns_ops);
  85                if (res >= 0)
  86                        res = readlink_copy(buffer, buflen, name);
  87        }
  88        put_task_struct(task);
  89        return res;
  90}
  91
  92static const struct inode_operations proc_ns_link_inode_operations = {
  93        .readlink       = proc_ns_readlink,
  94        .get_link       = proc_ns_get_link,
  95        .setattr        = proc_setattr,
  96};
  97
  98static struct dentry *proc_ns_instantiate(struct dentry *dentry,
  99        struct task_struct *task, const void *ptr)
 100{
 101        const struct proc_ns_operations *ns_ops = ptr;
 102        struct inode *inode;
 103        struct proc_inode *ei;
 104
 105        inode = proc_pid_make_inode(dentry->d_sb, task, S_IFLNK | S_IRWXUGO);
 106        if (!inode)
 107                return ERR_PTR(-ENOENT);
 108
 109        ei = PROC_I(inode);
 110        inode->i_op = &proc_ns_link_inode_operations;
 111        ei->ns_ops = ns_ops;
 112        pid_update_inode(task, inode);
 113
 114        d_set_d_op(dentry, &pid_dentry_operations);
 115        return d_splice_alias(inode, dentry);
 116}
 117
 118static int proc_ns_dir_readdir(struct file *file, struct dir_context *ctx)
 119{
 120        struct task_struct *task = get_proc_task(file_inode(file));
 121        const struct proc_ns_operations **entry, **last;
 122
 123        if (!task)
 124                return -ENOENT;
 125
 126        if (!dir_emit_dots(file, ctx))
 127                goto out;
 128        if (ctx->pos >= 2 + ARRAY_SIZE(ns_entries))
 129                goto out;
 130        entry = ns_entries + (ctx->pos - 2);
 131        last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
 132        while (entry <= last) {
 133                const struct proc_ns_operations *ops = *entry;
 134                if (!proc_fill_cache(file, ctx, ops->name, strlen(ops->name),
 135                                     proc_ns_instantiate, task, ops))
 136                        break;
 137                ctx->pos++;
 138                entry++;
 139        }
 140out:
 141        put_task_struct(task);
 142        return 0;
 143}
 144
 145const struct file_operations proc_ns_dir_operations = {
 146        .read           = generic_read_dir,
 147        .iterate_shared = proc_ns_dir_readdir,
 148        .llseek         = generic_file_llseek,
 149};
 150
 151static struct dentry *proc_ns_dir_lookup(struct inode *dir,
 152                                struct dentry *dentry, unsigned int flags)
 153{
 154        struct task_struct *task = get_proc_task(dir);
 155        const struct proc_ns_operations **entry, **last;
 156        unsigned int len = dentry->d_name.len;
 157        struct dentry *res = ERR_PTR(-ENOENT);
 158
 159        if (!task)
 160                goto out_no_task;
 161
 162        last = &ns_entries[ARRAY_SIZE(ns_entries)];
 163        for (entry = ns_entries; entry < last; entry++) {
 164                if (strlen((*entry)->name) != len)
 165                        continue;
 166                if (!memcmp(dentry->d_name.name, (*entry)->name, len))
 167                        break;
 168        }
 169        if (entry == last)
 170                goto out;
 171
 172        res = proc_ns_instantiate(dentry, task, *entry);
 173out:
 174        put_task_struct(task);
 175out_no_task:
 176        return res;
 177}
 178
 179const struct inode_operations proc_ns_dir_inode_operations = {
 180        .lookup         = proc_ns_dir_lookup,
 181        .getattr        = pid_getattr,
 182        .setattr        = proc_setattr,
 183};
 184