Skip to content

Commit

Permalink
proc: add option to mount only a pids subset
Browse files Browse the repository at this point in the history
This allows to hide all files and directories in the procfs that are not
related to tasks.

Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
  • Loading branch information
legionus committed Sep 18, 2017
1 parent d006bbc commit 993a2a5
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
20 changes: 20 additions & 0 deletions fs/proc/generic.c
Expand Up @@ -233,6 +233,11 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags)
{
struct proc_fs_info *fs_info = proc_sb(dir->i_sb);

if (proc_fs_pidonly(fs_info))
return ERR_PTR(-ENOENT);

return proc_lookup_de(PDE(dir), dir, dentry);
}

Expand Down Expand Up @@ -289,10 +294,24 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *file,
int proc_readdir(struct file *file, struct dir_context *ctx)
{
struct inode *inode = file_inode(file);
struct proc_fs_info *fs_info = proc_sb(inode->i_sb);

if (proc_fs_pidonly(fs_info))
return 1;

return proc_readdir_de(PDE(inode), file, ctx);
}

static int proc_dir_open(struct inode *inode, struct file *file)
{
struct proc_fs_info *fs_info = proc_sb(inode->i_sb);

if (proc_fs_pidonly(fs_info))
return -ENOENT;

return 0;
}

/*
* These are the generic /proc directory operations. They
* use the in-memory "struct proc_dir_entry" tree to parse
Expand All @@ -302,6 +321,7 @@ static const struct file_operations proc_dir_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
.iterate_shared = proc_readdir,
.open = proc_dir_open,
};

/*
Expand Down
4 changes: 4 additions & 0 deletions fs/proc/inode.c
Expand Up @@ -324,12 +324,16 @@ proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr,

static int proc_reg_open(struct inode *inode, struct file *file)
{
struct proc_fs_info *fs_info = proc_sb(inode->i_sb);
struct proc_dir_entry *pde = PDE(inode);
int rv = 0;
int (*open)(struct inode *, struct file *);
int (*release)(struct inode *, struct file *);
struct pde_opener *pdeo;

if (proc_fs_pidonly(fs_info))
return -ENOENT;

/*
* Ensure that
* 1) PDE's ->release hook will be called no matter what
Expand Down
12 changes: 10 additions & 2 deletions fs/proc/root.c
Expand Up @@ -27,17 +27,18 @@
#include "internal.h"

enum {
Opt_gid, Opt_hidepid, Opt_limit_pids, Opt_err,
Opt_gid, Opt_hidepid, Opt_limit_pids, Opt_pidonly, Opt_err,
};

static const match_table_t tokens = {
{Opt_hidepid, "hidepid=%u"},
{Opt_gid, "gid=%u"},
{Opt_limit_pids, "limit_pids=%u"},
{Opt_pidonly, "pidonly"},
{Opt_err, NULL},
};

/* We only parse 'limit_pids' option here */
/* We only parse 'limit_pids' and 'pidonly' option here */
int proc_parse_early_options(char *options, struct proc_fs_info *fs_info)
{
char *p, *opts, *orig;
Expand Down Expand Up @@ -73,6 +74,11 @@ int proc_parse_early_options(char *options, struct proc_fs_info *fs_info)
proc_fs_set_newinstance(fs_info, true);
pr_info("proc: mounting a new procfs instance ");
break;
case Opt_pidonly:
proc_fs_set_pidonly(fs_info, PROC_PIDONLY_ON);
proc_fs_set_newinstance(fs_info, true);
pr_info("proc: mounting a new procfs instance ");
break;
case Opt_gid:
case Opt_hidepid:
break;
Expand Down Expand Up @@ -125,6 +131,7 @@ int proc_parse_options(char *options, struct proc_fs_info *fs_info)
}
proc_fs_set_hide_pid(fs_info, option);
break;
case Opt_pidonly:
case Opt_limit_pids:
break;
default:
Expand Down Expand Up @@ -197,6 +204,7 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
/* Set it as early as possible */
proc_fs_set_newinstance(fs_info, false);
proc_fs_set_limit_pids(fs_info, PROC_LIMIT_PIDS_OFF);
proc_fs_set_pidonly(fs_info, PROC_PIDONLY_OFF);

if (flags & MS_KERNMOUNT) {
ns = data;
Expand Down
21 changes: 21 additions & 0 deletions include/linux/proc_fs.h
Expand Up @@ -17,6 +17,11 @@ enum { /* definitions for proc mount option limit_pids */
PROC_LIMIT_PIDS_PTRACE = 1, /* Limit pids to only ptracable pids */
};

enum {
PROC_PIDONLY_OFF = 0,
PROC_PIDONLY_ON = 1,
};

struct proc_fs_info {
struct super_block *sb;
struct pid_namespace *pid_ns;
Expand All @@ -25,6 +30,7 @@ struct proc_fs_info {
struct dentry *proc_thread_self; /* For /proc/thread-self/ */
bool newinstance; /* Private flag for new separated instances */
int limit_pids:1;
int pidonly:1;
};

#ifdef CONFIG_PROC_FS
Expand Down Expand Up @@ -59,6 +65,16 @@ static inline int proc_fs_set_limit_pids(struct proc_fs_info *fs_info, int value
return 0;
}

static inline int proc_fs_set_pidonly(struct proc_fs_info *fs_info, int value)
{
if (value != PROC_PIDONLY_ON && value != PROC_PIDONLY_OFF)
return -EINVAL;

fs_info->pidonly = value;

return 0;
}

static inline int proc_fs_hide_pid(struct proc_fs_info *fs_info)
{
return fs_info->pid_ns->hide_pid;
Expand All @@ -79,6 +95,11 @@ static inline int proc_fs_limit_pids(struct proc_fs_info *fs_info)
return fs_info->limit_pids;
}

static inline int proc_fs_pidonly(struct proc_fs_info *fs_info)
{
return fs_info->pidonly;
}

extern void proc_root_init(void);
extern void proc_flush_task(struct task_struct *);

Expand Down

0 comments on commit 993a2a5

Please sign in to comment.