From: Greg Kroah-Hartman Date: Sun, 20 May 2018 07:47:27 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.9.102~35 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a8f0ac0540ea740f2762770e4169d0fe8b7be16;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches 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 --- 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 index 00000000000..90c5872ef0d --- /dev/null +++ b/queue-4.4/proc-read-mm-s-arg-env-_-start-end-with-mmap-semaphore-taken.patch @@ -0,0 +1,111 @@ +From a3b609ef9f8b1dbfe97034ccad6cd3fe71fbe7ab Mon Sep 17 00:00:00 2001 +From: Mateusz Guzik +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 + +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 +Acked-by: Cyrill Gorcunov +Cc: Alexey Dobriyan +Cc: Jarod Wilson +Cc: Jan Stancek +Cc: Al Viro +Cc: Anshuman Khandual +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0848b555677 --- /dev/null +++ b/queue-4.4/procfs-fix-pthread-cross-thread-naming-if-pr_dumpable.patch @@ -0,0 +1,99 @@ +From 1b3044e39a89cb1d4d5313da477e8dfea2b5232d Mon Sep 17 00:00:00 2001 +From: Janis Danisevskis +Date: Fri, 20 May 2016 17:00:08 -0700 +Subject: procfs: fix pthread cross-thread naming if !PR_DUMPABLE + +From: Janis Danisevskis + +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//task//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 +Acked-by: Kees Cook +Cc: Al Viro +Cc: Cyrill Gorcunov +Cc: Alexey Dobriyan +Cc: Colin Ian King +Cc: David Rientjes +Cc: Minfei Huang +Cc: John Stultz +Cc: Calvin Owens +Cc: Jann Horn +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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//task//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//task//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 diff --git a/queue-4.4/series b/queue-4.4/series index ee3ed87a713..456f57c347c 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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