fs: take i_mutex during prepare_binprm for set[ug]id executables

This prevents a race between chown() and execve(), where chowning a
setuid-user binary to root would momentarily make the binary setuid
root.

This patch was mostly written by Linus Torvalds.

Signed-off-by: Jann Horn <jann@thejh.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
void set_dumpable(struct mm_struct *mm, int value)
{
	unsigned long old, new;

	if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
		return;

	do {
		old = ACCESS_ONCE(mm->flags);
		new = (old & ~MMF_DUMPABLE_MASK) | value;
	} while (cmpxchg(&mm->flags, old, new) != old);
}

void set_dumpable(struct mm_struct *mm, int value)
{
	unsigned long old, new;

	if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
		return;

	do {
		old = ACCESS_ONCE(mm->flags);
		new = (old & ~MMF_DUMPABLE_MASK) | value;
	} while (cmpxchg(&mm->flags, old, new) != old);
}
