mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
s390/uaccess: Prevent kprobes on cmpxchg_user_key() functions
Code regions within cmpxchg_user_key() functions may be executed with a non-default access key, which may lead to a protection exception if the corresponding page has the fetch-protection bit enabled. There is code in place which initializes the storage keys of such pages when needed. However there is also the possibility of out-of-line execution of such code in case a kprobe is set within such a region. To avoid this problem prevent that any kprobe can be set within the cmpxchg_user_key() functions. Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
parent
b13c190c6d
commit
d2b73ce90a
|
|
@ -8,6 +8,7 @@
|
|||
* Gerald Schaefer (gerald.schaefer@de.ibm.com)
|
||||
*/
|
||||
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/mm.h>
|
||||
|
|
@ -149,8 +150,8 @@ EXPORT_SYMBOL(_copy_to_user_key);
|
|||
|
||||
#define CMPXCHG_USER_KEY_MAX_LOOPS 128
|
||||
|
||||
int __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
|
||||
unsigned char old, unsigned char new, unsigned long key)
|
||||
int __kprobes __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
|
||||
unsigned char old, unsigned char new, unsigned long key)
|
||||
{
|
||||
unsigned int prev, shift, mask, _old, _new;
|
||||
unsigned long count;
|
||||
|
|
@ -208,8 +209,8 @@ int __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
|
|||
}
|
||||
EXPORT_SYMBOL(__cmpxchg_user_key1);
|
||||
|
||||
int __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
|
||||
unsigned short old, unsigned short new, unsigned long key)
|
||||
int __kprobes __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
|
||||
unsigned short old, unsigned short new, unsigned long key)
|
||||
{
|
||||
unsigned int prev, shift, mask, _old, _new;
|
||||
unsigned long count;
|
||||
|
|
@ -267,8 +268,8 @@ int __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
|
|||
}
|
||||
EXPORT_SYMBOL(__cmpxchg_user_key2);
|
||||
|
||||
int __cmpxchg_user_key4(unsigned long address, unsigned int *uval,
|
||||
unsigned int old, unsigned int new, unsigned long key)
|
||||
int __kprobes __cmpxchg_user_key4(unsigned long address, unsigned int *uval,
|
||||
unsigned int old, unsigned int new, unsigned long key)
|
||||
{
|
||||
unsigned int prev = old;
|
||||
bool sacf_flag;
|
||||
|
|
@ -299,8 +300,8 @@ int __cmpxchg_user_key4(unsigned long address, unsigned int *uval,
|
|||
}
|
||||
EXPORT_SYMBOL(__cmpxchg_user_key4);
|
||||
|
||||
int __cmpxchg_user_key8(unsigned long address, unsigned long *uval,
|
||||
unsigned long old, unsigned long new, unsigned long key)
|
||||
int __kprobes __cmpxchg_user_key8(unsigned long address, unsigned long *uval,
|
||||
unsigned long old, unsigned long new, unsigned long key)
|
||||
{
|
||||
unsigned long prev = old;
|
||||
bool sacf_flag;
|
||||
|
|
@ -331,8 +332,8 @@ int __cmpxchg_user_key8(unsigned long address, unsigned long *uval,
|
|||
}
|
||||
EXPORT_SYMBOL(__cmpxchg_user_key8);
|
||||
|
||||
int __cmpxchg_user_key16(unsigned long address, __uint128_t *uval,
|
||||
__uint128_t old, __uint128_t new, unsigned long key)
|
||||
int __kprobes __cmpxchg_user_key16(unsigned long address, __uint128_t *uval,
|
||||
__uint128_t old, __uint128_t new, unsigned long key)
|
||||
{
|
||||
__uint128_t prev = old;
|
||||
bool sacf_flag;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user