Commit 24a71ce5 authored by Alexey Gladkov's avatar Alexey Gladkov Committed by Eric W. Biederman
Browse files

proc: instantiate only pids that we can ptrace on 'hidepid=4' mount option



If "hidepid=4" mount option is set then do not instantiate pids that
we can not ptrace. "hidepid=4" means that procfs should only contain
pids that the caller can ptrace.

Signed-off-by: default avatarDjalal Harouni <tixxdz@gmail.com>
Signed-off-by: default avatarAlexey Gladkov <gladkov.alexey@gmail.com>
Reviewed-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent fa10fed3
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -701,6 +701,14 @@ static bool has_pid_permissions(struct proc_fs_info *fs_info,
				 struct task_struct *task,
				 int hide_pid_min)
{
	/*
	 * If 'hidpid' mount option is set force a ptrace check,
	 * we indicate that we are using a filesystem syscall
	 * by passing PTRACE_MODE_READ_FSCREDS
	 */
	if (fs_info->hide_pid == HIDEPID_NOT_PTRACEABLE)
		return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);

	if (fs_info->hide_pid < hide_pid_min)
		return true;
	if (in_group_p(fs_info->pid_gid))
@@ -3319,7 +3327,14 @@ struct dentry *proc_pid_lookup(struct dentry *dentry, unsigned int flags)
	if (!task)
		goto out;

	/* Limit procfs to only ptraceable tasks */
	if (fs_info->hide_pid == HIDEPID_NOT_PTRACEABLE) {
		if (!has_pid_permissions(fs_info, task, HIDEPID_NO_ACCESS))
			goto out_put_task;
	}

	result = proc_pid_instantiate(dentry, task, NULL);
out_put_task:
	put_task_struct(task);
out:
	return result;
+10 −3
Original line number Diff line number Diff line
@@ -47,6 +47,14 @@ static const struct fs_parameter_spec proc_fs_parameters[] = {
	{}
};

static inline int valid_hidepid(unsigned int value)
{
	return (value == HIDEPID_OFF ||
		value == HIDEPID_NO_ACCESS ||
		value == HIDEPID_INVISIBLE ||
		value == HIDEPID_NOT_PTRACEABLE);
}

static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
	struct proc_fs_context *ctx = fc->fs_private;
@@ -63,10 +71,9 @@ static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
		break;

	case Opt_hidepid:
		if (!valid_hidepid(result.uint_32))
			return invalf(fc, "proc: unknown value of hidepid.\n");
		ctx->hidepid = result.uint_32;
		if (ctx->hidepid < HIDEPID_OFF ||
		    ctx->hidepid > HIDEPID_INVISIBLE)
			return invalfc(fc, "hidepid value must be between 0 and 2.\n");
		break;

	default:
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ enum {
	HIDEPID_OFF	  = 0,
	HIDEPID_NO_ACCESS = 1,
	HIDEPID_INVISIBLE = 2,
	HIDEPID_NOT_PTRACEABLE = 4, /* Limit pids to only ptraceable pids */
};

struct proc_fs_info {