Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[firefly-linux-kernel-4.4.55.git] / kernel / user.c
index 6408c04242914191405dfef6a21b73948ef5ae73..220e586127a0ca9cd65b3ccfd6b01c4620fef2e7 100644 (file)
@@ -187,6 +187,17 @@ void switch_uid(struct user_struct *new_user)
        atomic_dec(&old_user->processes);
        switch_uid_keyring(new_user);
        current->user = new_user;
+
+       /*
+        * We need to synchronize with __sigqueue_alloc()
+        * doing a get_uid(p->user).. If that saw the old
+        * user value, we need to wait until it has exited
+        * its critical region before we can free the old
+        * structure.
+        */
+       smp_mb();
+       spin_unlock_wait(&current->sighand->siglock);
+
        free_uid(old_user);
        suid_keys(current);
 }