Commit d8eebb11 authored by Heiko Carstens's avatar Heiko Carstens Committed by Alexander Gordeev
Browse files

s390/futex: Avoid KMSAN instrumention for user pointers



Similar to commit eb6efdfe ("s390/uaccess: add KMSAN support to
put_user() and get_user()") disable KMSAN instrumention for futex inline
assemblies, which contain dereferenced user pointers. With KMSAN
instrumentation this would lead to accesses of shadows for user pointers,
which should not happen.

Handle the futex operations like they copy a value (old) from user
space to kernel space.

Acked-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent c4891f45
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
#ifndef _ASM_S390_FUTEX_H
#define _ASM_S390_FUTEX_H

#include <linux/instrumented.h>
#include <linux/uaccess.h>
#include <linux/futex.h>
#include <asm/asm-extable.h>
@@ -9,11 +10,12 @@
#include <asm/errno.h>

#define FUTEX_OP_FUNC(name, insn)						\
static inline int								\
static uaccess_kmsan_or_inline int						\
__futex_atomic_##name(int oparg, int *old, u32 __user *uaddr)			\
{										\
	int rc, new;								\
										\
	instrument_copy_from_user_before(old, uaddr, sizeof(*old));		\
	asm_inline volatile(							\
		"	sacf	256\n"						\
		"0:	l	%[old],%[uaddr]\n"				\
@@ -30,6 +32,8 @@ __futex_atomic_##name(int oparg, int *old, u32 __user *uaddr) \
		  [new] "=&d" (new), [uaddr] "+Q" (*uaddr)			\
		: [oparg] "d" (oparg)						\
		: "cc");							\
	if (!rc)								\
		instrument_copy_from_user_after(old, uaddr, sizeof(*old), 0);	\
	return rc;								\
}

@@ -68,11 +72,12 @@ int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
	return rc;
}

static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
						u32 oldval, u32 newval)
static uaccess_kmsan_or_inline
int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval)
{
	int rc;

	instrument_copy_from_user_before(uval, uaddr, sizeof(*uval));
	asm_inline volatile(
		"	sacf	256\n"
		"0:	cs	%[old],%[new],%[uaddr]\n"
@@ -84,6 +89,7 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
		: [new] "d" (newval)
		: "cc", "memory");
	*uval = oldval;
	instrument_copy_from_user_after(uval, uaddr, sizeof(*uval), 0);
	return rc;
}