x86: asm: instrument usercopy in get_user() and put_user()
Use hooks from instrumented.h to notify bug detection tools about usercopy events in variations of get_user() and put_user(). Link: https://lkml.kernel.org/r/20220915150417.722975-5-glider@google.com Signed-off-by: Alexander Potapenko <glider@google.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Andrey Konovalov <andreyknvl@gmail.com> Cc: Andrey Konovalov <andreyknvl@google.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Christoph Hellwig <hch@lst.de> Cc: Christoph Lameter <cl@linux.com> Cc: David Rientjes <rientjes@google.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Eric Biggers <ebiggers@google.com> Cc: Eric Biggers <ebiggers@kernel.org> Cc: Eric Dumazet <edumazet@google.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Ilya Leoshkevich <iii@linux.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Kees Cook <keescook@chromium.org> Cc: Marco Elver <elver@google.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Petr Mladek <pmladek@suse.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vegard Nossum <vegard.nossum@oracle.com> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
33b75c1d88
commit
888f84a6da
|
@ -5,6 +5,7 @@
|
|||
* User space memory access functions
|
||||
*/
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/instrumented.h>
|
||||
#include <linux/kasan-checks.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/asm.h>
|
||||
|
@ -103,6 +104,7 @@ extern int __get_user_bad(void);
|
|||
: "=a" (__ret_gu), "=r" (__val_gu), \
|
||||
ASM_CALL_CONSTRAINT \
|
||||
: "0" (ptr), "i" (sizeof(*(ptr)))); \
|
||||
instrument_get_user(__val_gu); \
|
||||
(x) = (__force __typeof__(*(ptr))) __val_gu; \
|
||||
__builtin_expect(__ret_gu, 0); \
|
||||
})
|
||||
|
@ -192,9 +194,11 @@ extern void __put_user_nocheck_8(void);
|
|||
int __ret_pu; \
|
||||
void __user *__ptr_pu; \
|
||||
register __typeof__(*(ptr)) __val_pu asm("%"_ASM_AX); \
|
||||
__chk_user_ptr(ptr); \
|
||||
__ptr_pu = (ptr); \
|
||||
__val_pu = (x); \
|
||||
__typeof__(*(ptr)) __x = (x); /* eval x once */ \
|
||||
__typeof__(ptr) __ptr = (ptr); /* eval ptr once */ \
|
||||
__chk_user_ptr(__ptr); \
|
||||
__ptr_pu = __ptr; \
|
||||
__val_pu = __x; \
|
||||
asm volatile("call __" #fn "_%P[size]" \
|
||||
: "=c" (__ret_pu), \
|
||||
ASM_CALL_CONSTRAINT \
|
||||
|
@ -202,6 +206,7 @@ extern void __put_user_nocheck_8(void);
|
|||
"r" (__val_pu), \
|
||||
[size] "i" (sizeof(*(ptr))) \
|
||||
:"ebx"); \
|
||||
instrument_put_user(__x, __ptr, sizeof(*(ptr))); \
|
||||
__builtin_expect(__ret_pu, 0); \
|
||||
})
|
||||
|
||||
|
@ -248,23 +253,25 @@ extern void __put_user_nocheck_8(void);
|
|||
|
||||
#define __put_user_size(x, ptr, size, label) \
|
||||
do { \
|
||||
__typeof__(*(ptr)) __x = (x); /* eval x once */ \
|
||||
__chk_user_ptr(ptr); \
|
||||
switch (size) { \
|
||||
case 1: \
|
||||
__put_user_goto(x, ptr, "b", "iq", label); \
|
||||
__put_user_goto(__x, ptr, "b", "iq", label); \
|
||||
break; \
|
||||
case 2: \
|
||||
__put_user_goto(x, ptr, "w", "ir", label); \
|
||||
__put_user_goto(__x, ptr, "w", "ir", label); \
|
||||
break; \
|
||||
case 4: \
|
||||
__put_user_goto(x, ptr, "l", "ir", label); \
|
||||
__put_user_goto(__x, ptr, "l", "ir", label); \
|
||||
break; \
|
||||
case 8: \
|
||||
__put_user_goto_u64(x, ptr, label); \
|
||||
__put_user_goto_u64(__x, ptr, label); \
|
||||
break; \
|
||||
default: \
|
||||
__put_user_bad(); \
|
||||
} \
|
||||
instrument_put_user(__x, ptr, size); \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
|
@ -305,6 +312,7 @@ do { \
|
|||
default: \
|
||||
(x) = __get_user_bad(); \
|
||||
} \
|
||||
instrument_get_user(x); \
|
||||
} while (0)
|
||||
|
||||
#define __get_user_asm(x, addr, itype, ltype, label) \
|
||||
|
|
|
@ -153,4 +153,32 @@ instrument_copy_from_user_after(const void *to, const void __user *from,
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* instrument_get_user() - add instrumentation to get_user()-like macros
|
||||
*
|
||||
* get_user() and friends are fragile, so it may depend on the implementation
|
||||
* whether the instrumentation happens before or after the data is copied from
|
||||
* the userspace.
|
||||
*
|
||||
* @to destination variable, may not be address-taken
|
||||
*/
|
||||
#define instrument_get_user(to) \
|
||||
({ \
|
||||
})
|
||||
|
||||
/**
|
||||
* instrument_put_user() - add instrumentation to put_user()-like macros
|
||||
*
|
||||
* put_user() and friends are fragile, so it may depend on the implementation
|
||||
* whether the instrumentation happens before or after the data is copied from
|
||||
* the userspace.
|
||||
*
|
||||
* @from source address
|
||||
* @ptr userspace pointer to copy to
|
||||
* @size number of bytes to copy
|
||||
*/
|
||||
#define instrument_put_user(from, ptr, size) \
|
||||
({ \
|
||||
})
|
||||
|
||||
#endif /* _LINUX_INSTRUMENTED_H */
|
||||
|
|
Loading…
Reference in New Issue