|
@@ -315,6 +315,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
|
|
|
goto free_ti;
|
|
|
|
|
|
tsk->stack = ti;
|
|
|
+#ifdef CONFIG_SECCOMP
|
|
|
+ /*
|
|
|
+ * We must handle setting up seccomp filters once we're under
|
|
|
+ * the sighand lock in case orig has changed between now and
|
|
|
+ * then. Until then, filter must be NULL to avoid messing up
|
|
|
+ * the usage counts on the error path calling free_task.
|
|
|
+ */
|
|
|
+ tsk->seccomp.filter = NULL;
|
|
|
+#endif
|
|
|
|
|
|
setup_thread_stack(tsk, orig);
|
|
|
clear_user_return_notifier(tsk);
|
|
@@ -1081,6 +1090,39 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void copy_seccomp(struct task_struct *p)
|
|
|
+{
|
|
|
+#ifdef CONFIG_SECCOMP
|
|
|
+ /*
|
|
|
+ * Must be called with sighand->lock held, which is common to
|
|
|
+ * all threads in the group. Holding cred_guard_mutex is not
|
|
|
+ * needed because this new task is not yet running and cannot
|
|
|
+ * be racing exec.
|
|
|
+ */
|
|
|
+ BUG_ON(!spin_is_locked(¤t->sighand->siglock));
|
|
|
+
|
|
|
+ /* Ref-count the new filter user, and assign it. */
|
|
|
+ get_seccomp_filter(current);
|
|
|
+ p->seccomp = current->seccomp;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Explicitly enable no_new_privs here in case it got set
|
|
|
+ * between the task_struct being duplicated and holding the
|
|
|
+ * sighand lock. The seccomp state and nnp must be in sync.
|
|
|
+ */
|
|
|
+ if (task_no_new_privs(current))
|
|
|
+ task_set_no_new_privs(p);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If the parent gained a seccomp mode after copying thread
|
|
|
+ * flags and between before we held the sighand lock, we have
|
|
|
+ * to manually enable the seccomp thread flag here.
|
|
|
+ */
|
|
|
+ if (p->seccomp.mode != SECCOMP_MODE_DISABLED)
|
|
|
+ set_tsk_thread_flag(p, TIF_SECCOMP);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
|
|
|
{
|
|
|
current->clear_child_tid = tidptr;
|
|
@@ -1196,7 +1238,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|
|
goto fork_out;
|
|
|
|
|
|
ftrace_graph_init_task(p);
|
|
|
- get_seccomp_filter(p);
|
|
|
|
|
|
rt_mutex_init_task(p);
|
|
|
|
|
@@ -1436,6 +1477,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|
|
|
|
|
spin_lock(¤t->sighand->siglock);
|
|
|
|
|
|
+ /*
|
|
|
+ * Copy seccomp details explicitly here, in case they were changed
|
|
|
+ * before holding sighand lock.
|
|
|
+ */
|
|
|
+ copy_seccomp(p);
|
|
|
+
|
|
|
/*
|
|
|
* Process group and session signals need to be delivered to just the
|
|
|
* parent before the fork or both the parent and the child after the
|