aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2016-05-20 20:00:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commit3e42979e65dace1f9268dd5440e5ab096b8dee59 (patch)
tree152057727f5ac2448a4575cbda5937527a1ab5ba
parent623e47fc64f8de480b322b7ed68855f97137e2a5 (diff)
procfs: expose umask in /proc/<PID>/status
It's not possible to read the process umask without also modifying it, which is what umask(2) does. A library cannot read umask safely, especially if the main program might be multithreaded. Add a new status line ("Umask") in /proc/<PID>/status. It contains the file mode creation mask (umask) in octal. It is only shown for tasks which have task->fs. This patch is adapted from one originally written by Pierre Carrier. The use case is that we have endless trouble with people setting weird umask() values (usually on the grounds of "security"), and then everything breaking. I'm on the hook to fix these. We'd like to add debugging to our program so we can dump out the umask in debug reports. Previous versions of the patch used a syscall so you could only read your own umask. That's all I need. However there was quite a lot of push-back from those, so this new version exports it in /proc. See: https://lkml.org/lkml/2016/4/13/704 [umask2] https://lkml.org/lkml/2016/4/13/487 [getumask] Signed-off-by: Richard W.M. Jones <rjones@redhat.com> Acked-by: Konstantin Khlebnikov <koct9i@gmail.com> Acked-by: Jerome Marchand <jmarchan@redhat.com> Acked-by: Kees Cook <keescook@chromium.org> Cc: "Theodore Ts'o" <tytso@mit.edu> Cc: Michal Hocko <mhocko@kernel.org> Cc: Pierre Carrier <pierre@spotify.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/filesystems/proc.txt1
-rw-r--r--fs/proc/array.c20
2 files changed, 20 insertions, 1 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 7f5607a089b4..e8d00759bfa5 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -225,6 +225,7 @@ Table 1-2: Contents of the status files (as of 4.1)
225 TracerPid PID of process tracing this process (0 if not) 225 TracerPid PID of process tracing this process (0 if not)
226 Uid Real, effective, saved set, and file system UIDs 226 Uid Real, effective, saved set, and file system UIDs
227 Gid Real, effective, saved set, and file system GIDs 227 Gid Real, effective, saved set, and file system GIDs
228 Umask file mode creation mask
228 FDSize number of file descriptor slots currently allocated 229 FDSize number of file descriptor slots currently allocated
229 Groups supplementary group list 230 Groups supplementary group list
230 NStgid descendant namespace thread group ID hierarchy 231 NStgid descendant namespace thread group ID hierarchy
diff --git a/fs/proc/array.c b/fs/proc/array.c
index b6c00ce0e29e..88c7de12197b 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -83,6 +83,7 @@
83#include <linux/tracehook.h> 83#include <linux/tracehook.h>
84#include <linux/string_helpers.h> 84#include <linux/string_helpers.h>
85#include <linux/user_namespace.h> 85#include <linux/user_namespace.h>
86#include <linux/fs_struct.h>
86 87
87#include <asm/pgtable.h> 88#include <asm/pgtable.h>
88#include <asm/processor.h> 89#include <asm/processor.h>
@@ -139,12 +140,25 @@ static inline const char *get_task_state(struct task_struct *tsk)
139 return task_state_array[fls(state)]; 140 return task_state_array[fls(state)];
140} 141}
141 142
143static inline int get_task_umask(struct task_struct *tsk)
144{
145 struct fs_struct *fs;
146 int umask = -ENOENT;
147
148 task_lock(tsk);
149 fs = tsk->fs;
150 if (fs)
151 umask = fs->umask;
152 task_unlock(tsk);
153 return umask;
154}
155
142static inline void task_state(struct seq_file *m, struct pid_namespace *ns, 156static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
143 struct pid *pid, struct task_struct *p) 157 struct pid *pid, struct task_struct *p)
144{ 158{
145 struct user_namespace *user_ns = seq_user_ns(m); 159 struct user_namespace *user_ns = seq_user_ns(m);
146 struct group_info *group_info; 160 struct group_info *group_info;
147 int g; 161 int g, umask;
148 struct task_struct *tracer; 162 struct task_struct *tracer;
149 const struct cred *cred; 163 const struct cred *cred;
150 pid_t ppid, tpid = 0, tgid, ngid; 164 pid_t ppid, tpid = 0, tgid, ngid;
@@ -162,6 +176,10 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
162 ngid = task_numa_group_id(p); 176 ngid = task_numa_group_id(p);
163 cred = get_task_cred(p); 177 cred = get_task_cred(p);
164 178
179 umask = get_task_umask(p);
180 if (umask >= 0)
181 seq_printf(m, "Umask:\t%#04o\n", umask);
182
165 task_lock(p); 183 task_lock(p);
166 if (p->files) 184 if (p->files)
167 max_fds = files_fdtable(p->files)->max_fds; 185 max_fds = files_fdtable(p->files)->max_fds;