On 06/23, Kees Cook wrote:
+static pid_t seccomp_can_sync_threads(void)
+{
+ struct task_struct *thread, *caller;
+
+ BUG_ON(write_can_lock(&tasklist_lock));
+ BUG_ON(!spin_is_locked(¤t->sighand->siglock));
+
+ if (current->seccomp.mode != SECCOMP_MODE_FILTER)
+ return -EACCES;
+
+ /* Validate all threads being eligible for synchronization. */
+ thread = caller = current;
+ for_each_thread(caller, thread) {
You only need to initialize "caller" for for_each_thread(). Same for
seccomp_sync_threads().
quoted hunk ↗ jump to hunk
@@ -586,6 +701,17 @@ static long seccomp_set_mode_filter(unsigned int flags,
if (IS_ERR(prepared))
return PTR_ERR(prepared);
+ /*
+ * If we're doing thread sync, we must hold tasklist_lock
+ * to make sure seccomp filter changes are stable on threads
+ * entering or leaving the task list. And we must take it
+ * before the sighand lock to avoid deadlocking.
+ */
+ if (flags & SECCOMP_FILTER_FLAG_TSYNC)
+ write_lock_irqsave(&tasklist_lock, taskflags);
+ else
+ __acquire(&tasklist_lock); /* keep sparse happy */
+
Why? ->siglock should be enough, it seems.
It obviously does not protect the global process list, but *sync_threads()
only care about current's thread group list, no?
Oleg.