Skip to content

Commit 24a71ce

Browse files
legionusebiederm
authored andcommitted
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: Djalal Harouni <[email protected]> Signed-off-by: Alexey Gladkov <[email protected]> Reviewed-by: Alexey Dobriyan <[email protected]> Reviewed-by: Kees Cook <[email protected]> Signed-off-by: Eric W. Biederman <[email protected]>
1 parent fa10fed commit 24a71ce

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

fs/proc/base.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,14 @@ static bool has_pid_permissions(struct proc_fs_info *fs_info,
701701
struct task_struct *task,
702702
int hide_pid_min)
703703
{
704+
/*
705+
* If 'hidpid' mount option is set force a ptrace check,
706+
* we indicate that we are using a filesystem syscall
707+
* by passing PTRACE_MODE_READ_FSCREDS
708+
*/
709+
if (fs_info->hide_pid == HIDEPID_NOT_PTRACEABLE)
710+
return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
711+
704712
if (fs_info->hide_pid < hide_pid_min)
705713
return true;
706714
if (in_group_p(fs_info->pid_gid))
@@ -3319,7 +3327,14 @@ struct dentry *proc_pid_lookup(struct dentry *dentry, unsigned int flags)
33193327
if (!task)
33203328
goto out;
33213329

3330+
/* Limit procfs to only ptraceable tasks */
3331+
if (fs_info->hide_pid == HIDEPID_NOT_PTRACEABLE) {
3332+
if (!has_pid_permissions(fs_info, task, HIDEPID_NO_ACCESS))
3333+
goto out_put_task;
3334+
}
3335+
33223336
result = proc_pid_instantiate(dentry, task, NULL);
3337+
out_put_task:
33233338
put_task_struct(task);
33243339
out:
33253340
return result;

fs/proc/root.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ static const struct fs_parameter_spec proc_fs_parameters[] = {
4747
{}
4848
};
4949

50+
static inline int valid_hidepid(unsigned int value)
51+
{
52+
return (value == HIDEPID_OFF ||
53+
value == HIDEPID_NO_ACCESS ||
54+
value == HIDEPID_INVISIBLE ||
55+
value == HIDEPID_NOT_PTRACEABLE);
56+
}
57+
5058
static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
5159
{
5260
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)
6371
break;
6472

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

7279
default:

include/linux/proc_fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum {
4747
HIDEPID_OFF = 0,
4848
HIDEPID_NO_ACCESS = 1,
4949
HIDEPID_INVISIBLE = 2,
50+
HIDEPID_NOT_PTRACEABLE = 4, /* Limit pids to only ptraceable pids */
5051
};
5152

5253
struct proc_fs_info {

0 commit comments

Comments
 (0)