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.

Signed-off-by: Richard W.M. Jones <rjo...@redhat.com>
---
 Documentation/filesystems/proc.txt |  1 +
 fs/proc/array.c                    | 20 +++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/Documentation/filesystems/proc.txt 
b/Documentation/filesystems/proc.txt
index 7f5607a..e8d0075 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)
  TracerPid                   PID of process tracing this process (0 if not)
  Uid                         Real, effective, saved set, and  file system UIDs
  Gid                         Real, effective, saved set, and  file system GIDs
+ Umask                       file mode creation mask
  FDSize                      number of file descriptor slots currently 
allocated
  Groups                      supplementary group list
  NStgid                      descendant namespace thread group ID hierarchy
diff --git a/fs/proc/array.c b/fs/proc/array.c
index b6c00ce..03e8d3f 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -83,6 +83,7 @@
 #include <linux/tracehook.h>
 #include <linux/string_helpers.h>
 #include <linux/user_namespace.h>
+#include <linux/fs_struct.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -139,12 +140,25 @@ static inline const char *get_task_state(struct 
task_struct *tsk)
        return task_state_array[fls(state)];
 }
 
+static inline int get_task_umask(struct task_struct *tsk)
+{
+       struct fs_struct *fs;
+       int umask = -ENOENT;
+
+       task_lock(tsk);
+       fs = tsk->fs;
+       if (fs)
+               umask = fs->umask;
+       task_unlock(tsk);
+       return umask;
+}
+
 static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
                                struct pid *pid, struct task_struct *p)
 {
        struct user_namespace *user_ns = seq_user_ns(m);
        struct group_info *group_info;
-       int g;
+       int g, umask;
        struct task_struct *tracer;
        const struct cred *cred;
        pid_t ppid, tpid = 0, tgid, ngid;
@@ -162,6 +176,10 @@ static inline void task_state(struct seq_file *m, struct 
pid_namespace *ns,
        ngid = task_numa_group_id(p);
        cred = get_task_cred(p);
 
+       umask = get_task_umask(p);
+       if (umask >= 0)
+               seq_printf(m, "Umask:\t0%o\n", umask);
+
        task_lock(p);
        if (p->files)
                max_fds = files_fdtable(p->files)->max_fds;
-- 
2.7.4

Reply via email to