]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 May 2018 07:47:27 +0000 (09:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 May 2018 07:47:27 +0000 (09:47 +0200)
added patches:
proc-read-mm-s-arg-env-_-start-end-with-mmap-semaphore-taken.patch
procfs-fix-pthread-cross-thread-naming-if-pr_dumpable.patch

queue-4.4/proc-read-mm-s-arg-env-_-start-end-with-mmap-semaphore-taken.patch [new file with mode: 0644]
queue-4.4/procfs-fix-pthread-cross-thread-naming-if-pr_dumpable.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/proc-read-mm-s-arg-env-_-start-end-with-mmap-semaphore-taken.patch b/queue-4.4/proc-read-mm-s-arg-env-_-start-end-with-mmap-semaphore-taken.patch
new file mode 100644 (file)
index 0000000..90c5872
--- /dev/null
@@ -0,0 +1,111 @@
+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);
+               }
diff --git a/queue-4.4/procfs-fix-pthread-cross-thread-naming-if-pr_dumpable.patch b/queue-4.4/procfs-fix-pthread-cross-thread-naming-if-pr_dumpable.patch
new file mode 100644 (file)
index 0000000..0848b55
--- /dev/null
@@ -0,0 +1,99 @@
+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
index ee3ed87a713e3698fcdeabdf09c68a380c01b63c..456f57c347cb4c823f75514db406a6dbf63791b8 100644 (file)
@@ -51,3 +51,5 @@ mm-filemap-avoid-unnecessary-calls-to-lock_page-when-waiting-for-io-to-complete-
 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