diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 6a13c46cd87d..ed4bc339c9dc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -315,6 +315,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
315 | goto free_ti; | 315 | goto free_ti; |
316 | 316 | ||
317 | tsk->stack = ti; | 317 | tsk->stack = ti; |
318 | #ifdef CONFIG_SECCOMP | ||
319 | /* | ||
320 | * We must handle setting up seccomp filters once we're under | ||
321 | * the sighand lock in case orig has changed between now and | ||
322 | * then. Until then, filter must be NULL to avoid messing up | ||
323 | * the usage counts on the error path calling free_task. | ||
324 | */ | ||
325 | tsk->seccomp.filter = NULL; | ||
326 | #endif | ||
318 | 327 | ||
319 | setup_thread_stack(tsk, orig); | 328 | setup_thread_stack(tsk, orig); |
320 | clear_user_return_notifier(tsk); | 329 | clear_user_return_notifier(tsk); |
@@ -1081,6 +1090,39 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
1081 | return 0; | 1090 | return 0; |
1082 | } | 1091 | } |
1083 | 1092 | ||
1093 | static void copy_seccomp(struct task_struct *p) | ||
1094 | { | ||
1095 | #ifdef CONFIG_SECCOMP | ||
1096 | /* | ||
1097 | * Must be called with sighand->lock held, which is common to | ||
1098 | * all threads in the group. Holding cred_guard_mutex is not | ||
1099 | * needed because this new task is not yet running and cannot | ||
1100 | * be racing exec. | ||
1101 | */ | ||
1102 | BUG_ON(!spin_is_locked(¤t->sighand->siglock)); | ||
1103 | |||
1104 | /* Ref-count the new filter user, and assign it. */ | ||
1105 | get_seccomp_filter(current); | ||
1106 | p->seccomp = current->seccomp; | ||
1107 | |||
1108 | /* | ||
1109 | * Explicitly enable no_new_privs here in case it got set | ||
1110 | * between the task_struct being duplicated and holding the | ||
1111 | * sighand lock. The seccomp state and nnp must be in sync. | ||
1112 | */ | ||
1113 | if (task_no_new_privs(current)) | ||
1114 | task_set_no_new_privs(p); | ||
1115 | |||
1116 | /* | ||
1117 | * If the parent gained a seccomp mode after copying thread | ||
1118 | * flags and between before we held the sighand lock, we have | ||
1119 | * to manually enable the seccomp thread flag here. | ||
1120 | */ | ||
1121 | if (p->seccomp.mode != SECCOMP_MODE_DISABLED) | ||
1122 | set_tsk_thread_flag(p, TIF_SECCOMP); | ||
1123 | #endif | ||
1124 | } | ||
1125 | |||
1084 | SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) | 1126 | SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) |
1085 | { | 1127 | { |
1086 | current->clear_child_tid = tidptr; | 1128 | current->clear_child_tid = tidptr; |
@@ -1196,7 +1238,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1196 | goto fork_out; | 1238 | goto fork_out; |
1197 | 1239 | ||
1198 | ftrace_graph_init_task(p); | 1240 | ftrace_graph_init_task(p); |
1199 | get_seccomp_filter(p); | ||
1200 | 1241 | ||
1201 | rt_mutex_init_task(p); | 1242 | rt_mutex_init_task(p); |
1202 | 1243 | ||
@@ -1437,6 +1478,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1437 | spin_lock(¤t->sighand->siglock); | 1478 | spin_lock(¤t->sighand->siglock); |
1438 | 1479 | ||
1439 | /* | 1480 | /* |
1481 | * Copy seccomp details explicitly here, in case they were changed | ||
1482 | * before holding sighand lock. | ||
1483 | */ | ||
1484 | copy_seccomp(p); | ||
1485 | |||
1486 | /* | ||
1440 | * Process group and session signals need to be delivered to just the | 1487 | * Process group and session signals need to be delivered to just the |
1441 | * parent before the fork or both the parent and the child after the | 1488 | * parent before the fork or both the parent and the child after the |
1442 | * fork. Restart if a signal comes in before we add the new process to | 1489 | * fork. Restart if a signal comes in before we add the new process to |