ALSA: mtpav: Don't call card private_free at probe error path
[linux-2.6-microblaze.git] / fs / exec.c
index 537d92c..79f2c94 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -65,6 +65,7 @@
 #include <linux/vmalloc.h>
 #include <linux/io_uring.h>
 #include <linux/syscall_user_dispatch.h>
+#include <linux/coredump.h>
 
 #include <linux/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1045,7 +1046,7 @@ static int de_thread(struct task_struct *tsk)
         * Kill all other threads in the thread group.
         */
        spin_lock_irq(lock);
-       if (signal_group_exit(sig)) {
+       if ((sig->flags & SIGNAL_GROUP_EXIT) || sig->group_exec_task) {
                /*
                 * Another group action in progress, just
                 * return so that the signal is processed.
@@ -1054,7 +1055,7 @@ static int de_thread(struct task_struct *tsk)
                return -EAGAIN;
        }
 
-       sig->group_exit_task = tsk;
+       sig->group_exec_task = tsk;
        sig->notify_count = zap_other_threads(tsk);
        if (!thread_group_leader(tsk))
                sig->notify_count--;
@@ -1082,7 +1083,7 @@ static int de_thread(struct task_struct *tsk)
                        write_lock_irq(&tasklist_lock);
                        /*
                         * Do this under tasklist_lock to ensure that
-                        * exit_notify() can't miss ->group_exit_task
+                        * exit_notify() can't miss ->group_exec_task
                         */
                        sig->notify_count = -1;
                        if (likely(leader->exit_state))
@@ -1149,7 +1150,7 @@ static int de_thread(struct task_struct *tsk)
                release_task(leader);
        }
 
-       sig->group_exit_task = NULL;
+       sig->group_exec_task = NULL;
        sig->notify_count = 0;
 
 no_thread_group:
@@ -1162,7 +1163,7 @@ no_thread_group:
 killed:
        /* protects against exit_notify() and __exit_signal() */
        read_lock(&tasklist_lock);
-       sig->group_exit_task = NULL;
+       sig->group_exec_task = NULL;
        sig->notify_count = 0;
        read_unlock(&tasklist_lock);
        return -EAGAIN;
@@ -1207,7 +1208,8 @@ static int unshare_sighand(struct task_struct *me)
 char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk)
 {
        task_lock(tsk);
-       strncpy(buf, tsk->comm, buf_size);
+       /* Always NUL terminated and zero-padded */
+       strscpy_pad(buf, tsk->comm, buf_size);
        task_unlock(tsk);
        return buf;
 }
@@ -1222,7 +1224,7 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
 {
        task_lock(tsk);
        trace_task_rename(tsk, buf);
-       strlcpy(tsk->comm, buf, sizeof(tsk->comm));
+       strscpy_pad(tsk->comm, buf, sizeof(tsk->comm));
        task_unlock(tsk);
        perf_event_comm(tsk, exec);
 }
@@ -1307,6 +1309,8 @@ int begin_new_exec(struct linux_binprm * bprm)
         */
        force_uaccess_begin();
 
+       if (me->flags & PF_KTHREAD)
+               free_kthread_struct(me);
        me->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD |
                                        PF_NOFREEZE | PF_NO_SETAFFINITY);
        flush_thread();
@@ -2096,3 +2100,37 @@ COMPAT_SYSCALL_DEFINE5(execveat, int, fd,
                                  argv, envp, flags);
 }
 #endif
+
+#ifdef CONFIG_SYSCTL
+
+static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
+               void *buffer, size_t *lenp, loff_t *ppos)
+{
+       int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+
+       if (!error)
+               validate_coredump_safety();
+       return error;
+}
+
+static struct ctl_table fs_exec_sysctls[] = {
+       {
+               .procname       = "suid_dumpable",
+               .data           = &suid_dumpable,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax_coredump,
+               .extra1         = SYSCTL_ZERO,
+               .extra2         = SYSCTL_TWO,
+       },
+       { }
+};
+
+static int __init init_fs_exec_sysctls(void)
+{
+       register_sysctl_init("fs", fs_exec_sysctls);
+       return 0;
+}
+
+fs_initcall(init_fs_exec_sysctls);
+#endif /* CONFIG_SYSCTL */