Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Fix 'flush_old_exec()/setup_new_exec()' split

Commit 221af7f87b9 ("Split 'flush_old_exec' into two functions") split
the function at the point of no return - ie right where there were no
more error cases to check. That made sense from a technical standpoint,
but when we then also combined it with the actual personality setting
going in between flush_old_exec() and setup_new_exec(), it needs to be a
bit more careful.

In particular, we need to make sure that we really flush the old
personality bits in the 'flush' stage, rather than later in the 'setup'
stage, since otherwise we might be flushing the _new_ personality state
that we're just setting up.

So this moves the flags and personality flushing (and 'flush_thread()',
which is the arch-specific function that generally resets lazy FP state
etc) of the old process into flush_old_exec(), so that it doesn't affect
any state that execve() is setting up for the new process environment.

This was reported by Michal Simek as breaking his Microblaze qemu
environment.

Reported-and-tested-by: Michal Simek <michal.simek@petalogix.com>
Cc: Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+5 -5
+5 -5
fs/exec.c
··· 961 961 goto out; 962 962 963 963 bprm->mm = NULL; /* We're using it now */ 964 + 965 + current->flags &= ~PF_RANDOMIZE; 966 + flush_thread(); 967 + current->personality &= ~bprm->per_clear; 968 + 964 969 return 0; 965 970 966 971 out: ··· 1002 997 tcomm[i] = '\0'; 1003 998 set_task_comm(current, tcomm); 1004 999 1005 - current->flags &= ~PF_RANDOMIZE; 1006 - flush_thread(); 1007 - 1008 1000 /* Set the new mm task size. We have to do that late because it may 1009 1001 * depend on TIF_32BIT which is only updated in flush_thread() on 1010 1002 * some architectures like powerpc ··· 1016 1014 bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) { 1017 1015 set_dumpable(current->mm, suid_dumpable); 1018 1016 } 1019 - 1020 - current->personality &= ~bprm->per_clear; 1021 1017 1022 1018 /* 1023 1019 * Flush performance counters when crossing a