--- /dev/null
+From a3b609ef9f8b1dbfe97034ccad6cd3fe71fbe7ab Mon Sep 17 00:00:00 2001
+From: Mateusz Guzik <mguzik@redhat.com>
+Date: Wed, 20 Jan 2016 15:01:05 -0800
+Subject: proc read mm's {arg,env}_{start,end} with mmap semaphore taken.
+
+From: Mateusz Guzik <mguzik@redhat.com>
+
+commit a3b609ef9f8b1dbfe97034ccad6cd3fe71fbe7ab upstream.
+
+Only functions doing more than one read are modified. Consumeres
+happened to deal with possibly changing data, but it does not seem like
+a good thing to rely on.
+
+Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
+Acked-by: Cyrill Gorcunov <gorcunov@openvz.org>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Jarod Wilson <jarod@redhat.com>
+Cc: Jan Stancek <jstancek@redhat.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Anshuman Khandual <anshuman.linux@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/proc/base.c | 13 ++++++++++---
+ mm/util.c | 16 ++++++++++++----
+ 2 files changed, 22 insertions(+), 7 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -953,6 +953,7 @@ static ssize_t environ_read(struct file
+ unsigned long src = *ppos;
+ int ret = 0;
+ struct mm_struct *mm = file->private_data;
++ unsigned long env_start, env_end;
+
+ /* Ensure the process spawned far enough to have an environment. */
+ if (!mm || !mm->env_end)
+@@ -965,19 +966,25 @@ static ssize_t environ_read(struct file
+ ret = 0;
+ if (!atomic_inc_not_zero(&mm->mm_users))
+ goto free;
++
++ down_read(&mm->mmap_sem);
++ env_start = mm->env_start;
++ env_end = mm->env_end;
++ up_read(&mm->mmap_sem);
++
+ while (count > 0) {
+ size_t this_len, max_len;
+ int retval;
+
+- if (src >= (mm->env_end - mm->env_start))
++ if (src >= (env_end - env_start))
+ break;
+
+- this_len = mm->env_end - (mm->env_start + src);
++ this_len = env_end - (env_start + src);
+
+ max_len = min_t(size_t, PAGE_SIZE, count);
+ this_len = min(max_len, this_len);
+
+- retval = access_remote_vm(mm, (mm->env_start + src),
++ retval = access_remote_vm(mm, (env_start + src),
+ page, this_len, 0);
+
+ if (retval <= 0) {
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -428,17 +428,25 @@ int get_cmdline(struct task_struct *task
+ int res = 0;
+ unsigned int len;
+ struct mm_struct *mm = get_task_mm(task);
++ unsigned long arg_start, arg_end, env_start, env_end;
+ if (!mm)
+ goto out;
+ if (!mm->arg_end)
+ goto out_mm; /* Shh! No looking before we're done */
+
+- len = mm->arg_end - mm->arg_start;
++ down_read(&mm->mmap_sem);
++ arg_start = mm->arg_start;
++ arg_end = mm->arg_end;
++ env_start = mm->env_start;
++ env_end = mm->env_end;
++ up_read(&mm->mmap_sem);
++
++ len = arg_end - arg_start;
+
+ if (len > buflen)
+ len = buflen;
+
+- res = access_process_vm(task, mm->arg_start, buffer, len, 0);
++ res = access_process_vm(task, arg_start, buffer, len, 0);
+
+ /*
+ * If the nul at the end of args has been overwritten, then
+@@ -449,10 +457,10 @@ int get_cmdline(struct task_struct *task
+ if (len < res) {
+ res = len;
+ } else {
+- len = mm->env_end - mm->env_start;
++ len = env_end - env_start;
+ if (len > buflen - res)
+ len = buflen - res;
+- res += access_process_vm(task, mm->env_start,
++ res += access_process_vm(task, env_start,
+ buffer+res, len, 0);
+ res = strnlen(buffer, res);
+ }
--- /dev/null
+From 1b3044e39a89cb1d4d5313da477e8dfea2b5232d Mon Sep 17 00:00:00 2001
+From: Janis Danisevskis <jdanis@google.com>
+Date: Fri, 20 May 2016 17:00:08 -0700
+Subject: procfs: fix pthread cross-thread naming if !PR_DUMPABLE
+
+From: Janis Danisevskis <jdanis@google.com>
+
+commit 1b3044e39a89cb1d4d5313da477e8dfea2b5232d upstream.
+
+The PR_DUMPABLE flag causes the pid related paths of the proc file
+system to be owned by ROOT.
+
+The implementation of pthread_set/getname_np however needs access to
+/proc/<pid>/task/<tid>/comm. If PR_DUMPABLE is false this
+implementation is locked out.
+
+This patch installs a special permission function for the file "comm"
+that grants read and write access to all threads of the same group
+regardless of the ownership of the inode. For all other threads the
+function falls back to the generic inode permission check.
+
+[akpm@linux-foundation.org: fix spello in comment]
+Signed-off-by: Janis Danisevskis <jdanis@google.com>
+Acked-by: Kees Cook <keescook@chromium.org>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Cyrill Gorcunov <gorcunov@openvz.org>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Minfei Huang <mnfhuang@gmail.com>
+Cc: John Stultz <john.stultz@linaro.org>
+Cc: Calvin Owens <calvinowens@fb.com>
+Cc: Jann Horn <jann@thejh.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/proc/base.c | 42 +++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 41 insertions(+), 1 deletion(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -3083,6 +3083,44 @@ int proc_pid_readdir(struct file *file,
+ }
+
+ /*
++ * proc_tid_comm_permission is a special permission function exclusively
++ * used for the node /proc/<pid>/task/<tid>/comm.
++ * It bypasses generic permission checks in the case where a task of the same
++ * task group attempts to access the node.
++ * The rationale behind this is that glibc and bionic access this node for
++ * cross thread naming (pthread_set/getname_np(!self)). However, if
++ * PR_SET_DUMPABLE gets set to 0 this node among others becomes uid=0 gid=0,
++ * which locks out the cross thread naming implementation.
++ * This function makes sure that the node is always accessible for members of
++ * same thread group.
++ */
++static int proc_tid_comm_permission(struct inode *inode, int mask)
++{
++ bool is_same_tgroup;
++ struct task_struct *task;
++
++ task = get_proc_task(inode);
++ if (!task)
++ return -ESRCH;
++ is_same_tgroup = same_thread_group(current, task);
++ put_task_struct(task);
++
++ if (likely(is_same_tgroup && !(mask & MAY_EXEC))) {
++ /* This file (/proc/<pid>/task/<tid>/comm) can always be
++ * read or written by the members of the corresponding
++ * thread group.
++ */
++ return 0;
++ }
++
++ return generic_permission(inode, mask);
++}
++
++static const struct inode_operations proc_tid_comm_inode_operations = {
++ .permission = proc_tid_comm_permission,
++};
++
++/*
+ * Tasks
+ */
+ static const struct pid_entry tid_base_stuff[] = {
+@@ -3100,7 +3138,9 @@ static const struct pid_entry tid_base_s
+ #ifdef CONFIG_SCHED_DEBUG
+ REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
+ #endif
+- REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
++ NOD("comm", S_IFREG|S_IRUGO|S_IWUSR,
++ &proc_tid_comm_inode_operations,
++ &proc_pid_set_comm_operations, {}),
+ #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+ ONE("syscall", S_IRUSR, proc_pid_syscall),
+ #endif
signals-avoid-unnecessary-taking-of-sighand-siglock.patch
cpufreq-intel_pstate-enable-hwp-by-default.patch
tracing-x86-xen-remove-zero-data-size-trace-events-trace_xen_mmu_flush_tlb-_all.patch
+proc-read-mm-s-arg-env-_-start-end-with-mmap-semaphore-taken.patch
+procfs-fix-pthread-cross-thread-naming-if-pr_dumpable.patch