new helper: uaccess_kernel()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h
index 77c55ce..b2f62b9 100644
--- a/arch/alpha/include/asm/uaccess.h
+++ b/arch/alpha/include/asm/uaccess.h
@@ -425,7 +425,7 @@
#undef __module_call
#define user_addr_max() \
- (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
+ (uaccess_kernel() ? ~0UL : TASK_SIZE)
extern long strncpy_from_user(char *dest, const char __user *src, long count);
extern __must_check long strlen_user(const char __user *str);
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h
index d837a53..ffd14e6 100644
--- a/arch/arc/include/asm/uaccess.h
+++ b/arch/arc/include/asm/uaccess.h
@@ -27,7 +27,7 @@
#include <linux/string.h> /* for generic string functions */
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __kernel_ok (uaccess_kernel())
/*
* Algorithmically, for __user_ok() we want do:
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 9677a7c..b635273 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -266,7 +266,7 @@
#define access_ok(type, addr, size) (__range_ok(addr, size) == 0)
#define user_addr_max() \
- (segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs())
+ (uaccess_kernel() ? ~0UL : get_fs())
/*
* The "__xxx" versions of the user access functions do not verify the
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 6bd1089..9b4ed17 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -90,7 +90,7 @@
unsigned long ua_flags;
int atomic;
- if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+ if (uaccess_kernel()) {
memcpy((void *)to, from, n);
return 0;
}
@@ -162,7 +162,7 @@
{
unsigned long ua_flags;
- if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+ if (uaccess_kernel()) {
memset((void *)addr, 0, n);
return 0;
}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 89d5162..8981485 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -370,7 +370,7 @@
/* Check that things do not wrap around */
if (addr > ULONG_MAX - size)
return 0;
- if (segment_eq(get_fs(), KERNEL_DS))
+ if (uaccess_kernel())
return 1;
#ifdef CONFIG_MTD_UCLINUX
if (1)
diff --git a/arch/c6x/kernel/sys_c6x.c b/arch/c6x/kernel/sys_c6x.c
index 3e9bdfb..a742ae25 100644
--- a/arch/c6x/kernel/sys_c6x.c
+++ b/arch/c6x/kernel/sys_c6x.c
@@ -23,7 +23,7 @@
if (!addr || addr > (0xffffffffUL - (size - 1)))
goto _bad_access;
- if (segment_eq(get_fs(), KERNEL_DS))
+ if (uaccess_kernel())
return 1;
if (memory_start <= addr && (addr + size - 1) < memory_end)
diff --git a/arch/cris/include/asm/uaccess.h b/arch/cris/include/asm/uaccess.h
index c2462ef..5f5b8f5 100644
--- a/arch/cris/include/asm/uaccess.h
+++ b/arch/cris/include/asm/uaccess.h
@@ -43,7 +43,7 @@
#define segment_eq(a, b) ((a).seg == (b).seg)
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __kernel_ok (uaccess_kernel())
#define __user_ok(addr, size) \
(((size) <= TASK_SIZE) && ((addr) <= TASK_SIZE-(size)))
#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h
index fb72b71..14054a4 100644
--- a/arch/m68k/include/asm/uaccess_mm.h
+++ b/arch/m68k/include/asm/uaccess_mm.h
@@ -375,7 +375,7 @@
#define copy_to_user(to, from, n) __copy_to_user(to, from, n)
#define user_addr_max() \
- (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
+ (uaccess_kernel() ? ~0UL : TASK_SIZE)
extern long strncpy_from_user(char *dst, const char __user *src, long count);
extern __must_check long strlen_user(const char __user *str);
diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h
index 7fc5277..83de755 100644
--- a/arch/metag/include/asm/uaccess.h
+++ b/arch/metag/include/asm/uaccess.h
@@ -24,7 +24,7 @@
#define segment_eq(a, b) ((a).seg == (b).seg)
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __kernel_ok (uaccess_kernel())
/*
* Explicitly allow NULL pointers here. Parts of the kernel such
* as readv/writev use access_ok to validate pointers, but want
diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
index c8b574f..77cad23 100644
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -50,7 +50,7 @@
__wsum sum, int *err_ptr)
{
might_fault();
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
return __csum_partial_copy_kernel((__force void *)src, dst,
len, sum, err_ptr);
else
@@ -82,7 +82,7 @@
{
might_fault();
if (access_ok(VERIFY_WRITE, dst, len)) {
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
return __csum_partial_copy_kernel(src,
(__force void *)dst,
len, sum, err_ptr);
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index 55fd94e..7f12d7e 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -20,7 +20,7 @@
#include <asm/cpu-features.h>
#include <asm/cpu-type.h>
#include <asm/mipsmtregs.h>
-#include <linux/uaccess.h> /* for segment_eq() */
+#include <linux/uaccess.h> /* for uaccess_kernel() */
extern void (*r4k_blast_dcache)(void);
extern void (*r4k_blast_icache)(void);
@@ -714,7 +714,7 @@
\
__##pfx##flush_prologue \
\
- if (segment_eq(get_fs(), USER_DS)) { \
+ if (!uaccess_kernel()) { \
while (1) { \
protected_cachee_op(hitop, addr); \
if (addr == aend) \
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index dd25b31..70ca8ee 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -88,7 +88,7 @@
if (!IS_ENABLED(CONFIG_EVA))
return false;
- return segment_eq(get_fs(), get_ds());
+ return uaccess_kernel();
}
/*
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 7ed9835..f806ee5 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -1026,7 +1026,7 @@
goto sigbus;
if (IS_ENABLED(CONFIG_EVA)) {
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
LoadHW(addr, value, res);
else
LoadHWE(addr, value, res);
@@ -1045,7 +1045,7 @@
goto sigbus;
if (IS_ENABLED(CONFIG_EVA)) {
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
LoadW(addr, value, res);
else
LoadWE(addr, value, res);
@@ -1064,7 +1064,7 @@
goto sigbus;
if (IS_ENABLED(CONFIG_EVA)) {
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
LoadHWU(addr, value, res);
else
LoadHWUE(addr, value, res);
@@ -1132,7 +1132,7 @@
value = regs->regs[insn.i_format.rt];
if (IS_ENABLED(CONFIG_EVA)) {
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
StoreHW(addr, value, res);
else
StoreHWE(addr, value, res);
@@ -1152,7 +1152,7 @@
value = regs->regs[insn.i_format.rt];
if (IS_ENABLED(CONFIG_EVA)) {
- if (segment_eq(get_fs(), get_ds()))
+ if (uaccess_kernel())
StoreW(addr, value, res);
else
StoreWE(addr, value, res);
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index 0b0f604..227af1a 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -292,7 +292,7 @@
}
#define user_addr_max() \
- (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
+ (uaccess_kernel() ? ~0UL : TASK_SIZE)
extern long strncpy_from_user(char *dest, const char __user *src, long count);
diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h
index ac8bd58..0ba1430 100644
--- a/arch/parisc/include/asm/futex.h
+++ b/arch/parisc/include/asm/futex.h
@@ -109,7 +109,7 @@
/* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is
* our gateway page, and causes no end of trouble...
*/
- if (segment_eq(KERNEL_DS, get_fs()) && !uaddr)
+ if (uaccess_kernel() && !uaddr)
return -EFAULT;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index f82ff10..66f5160 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -76,7 +76,7 @@
goto label; \
} while (0)
-#define get_user_space() (segment_eq(get_fs(), KERNEL_DS) ? 0 : mfsp(3))
+#define get_user_space() (uaccess_kernel() ? 0 : mfsp(3))
#define get_kernel_space() (0)
#define MERGE(w0, sh_1, w1, sh_2) ({ \
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 9e9a5e8..7228ed8 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -37,7 +37,7 @@
static inline void set_fs(mm_segment_t fs)
{
current->thread.mm_segment = fs;
- if (segment_eq(fs, KERNEL_DS)) {
+ if (uaccess_kernel()) {
set_cpu_flag(CIF_ASCE_SECONDARY);
__ctl_load(S390_lowcore.kernel_asce, 7, 7);
} else {
diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
index bd56c28..9e068bf 100644
--- a/arch/sparc/include/asm/uaccess.h
+++ b/arch/sparc/include/asm/uaccess.h
@@ -7,7 +7,7 @@
#endif
#define user_addr_max() \
- (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
+ (uaccess_kernel() ? ~0UL : TASK_SIZE)
long strncpy_from_user(char *dest, const char __user *src, long count);
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 952d512..a59a1e8 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -36,7 +36,7 @@
* large size and address near to PAGE_OFFSET - a fault will break his intentions.
*/
#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __kernel_ok (uaccess_kernel())
#define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size)))
#define access_ok(type, addr, size) \
({ (void)(type); __access_ok((unsigned long)(addr), size); })
diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h
index 076bdcb..e992bb5 100644
--- a/arch/um/include/asm/uaccess.h
+++ b/arch/um/include/asm/uaccess.h
@@ -45,7 +45,7 @@
return __addr_range_nowrap(addr, size) &&
(__under_task_size(addr, size) ||
__access_ok_vsyscall(addr, size) ||
- segment_eq(get_fs(), KERNEL_DS));
+ uaccess_kernel());
}
#endif
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 85ac8ad..22c9f79 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -141,7 +141,7 @@
long __copy_from_user(void *to, const void __user *from, unsigned long n)
{
- if (segment_eq(get_fs(), KERNEL_DS)) {
+ if (uaccess_kernel()) {
memcpy(to, (__force void*)from, n);
return 0;
}
@@ -161,7 +161,7 @@
long __copy_to_user(void __user *to, const void *from, unsigned long n)
{
- if (segment_eq(get_fs(), KERNEL_DS)) {
+ if (uaccess_kernel()) {
memcpy((__force void *) to, from, n);
return 0;
}
@@ -189,7 +189,7 @@
long n;
char *ptr = dst;
- if (segment_eq(get_fs(), KERNEL_DS)) {
+ if (uaccess_kernel()) {
strncpy(dst, (__force void *) src, count);
return strnlen(dst, count);
}
@@ -210,7 +210,7 @@
unsigned long __clear_user(void __user *mem, unsigned long len)
{
- if (segment_eq(get_fs(), KERNEL_DS)) {
+ if (uaccess_kernel()) {
memset((__force void*)mem, 0, len);
return 0;
}
@@ -235,7 +235,7 @@
{
int count = 0, n;
- if (segment_eq(get_fs(), KERNEL_DS))
+ if (uaccess_kernel())
return strnlen((__force char*)str, len) + 1;
n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
diff --git a/arch/unicore32/include/asm/uaccess.h b/arch/unicore32/include/asm/uaccess.h
index f60fab7..1196c88 100644
--- a/arch/unicore32/include/asm/uaccess.h
+++ b/arch/unicore32/include/asm/uaccess.h
@@ -20,7 +20,7 @@
#define __strnlen_user __strnlen_user
#define __clear_user __clear_user
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __kernel_ok (uaccess_kernel())
#define __user_ok(addr, size) (((size) <= TASK_SIZE) \
&& ((addr) <= TASK_SIZE - (size)))
#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index d22c1dc..ddaf78a 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -178,7 +178,7 @@
buf, interrupts_enabled(regs) ? "n" : "ff",
fast_interrupts_enabled(regs) ? "n" : "ff",
processor_modes[processor_mode(regs)],
- segment_eq(get_fs(), get_ds()) ? "kernel" : "user");
+ uaccess_kernel() ? "kernel" : "user");
{
unsigned int ctrl;
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index bd8861c..2651269 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -37,7 +37,7 @@
#define segment_eq(a, b) ((a).seg == (b).seg)
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __kernel_ok (uaccess_kernel())
#define __user_ok(addr, size) \
(((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
#define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size)))
diff --git a/block/bsg.c b/block/bsg.c
index 74835db..69ccb78 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -650,7 +650,7 @@
dprintk("%s: write %zd bytes\n", bd->name, count);
- if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
+ if (unlikely(uaccess_kernel()))
return -EINVAL;
bsg_set_block(bd, file);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 29b8650..5d9136a 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -581,7 +581,7 @@
sg_io_hdr_t *hp;
unsigned char cmnd[SG_MAX_CDB_SIZE];
- if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
+ if (unlikely(uaccess_kernel()))
return -EINVAL;
if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index b786ca2..9c3ae87 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -7,6 +7,8 @@
#define VERIFY_READ 0
#define VERIFY_WRITE 1
+#define uaccess_kernel() segment_eq(get_fs(), KERNEL_DS)
+
#include <asm/uaccess.h>
static __always_inline void pagefault_disabled_inc(void)
diff --git a/include/rdma/ib.h b/include/rdma/ib.h
index 9b4c22a3..66dbed0 100644
--- a/include/rdma/ib.h
+++ b/include/rdma/ib.h
@@ -100,7 +100,7 @@
*/
static inline bool ib_safe_file_access(struct file *filp)
{
- return filp->f_cred == current_cred() && segment_eq(get_fs(), USER_DS);
+ return filp->f_cred == current_cred() && !uaccess_kernel();
}
#endif /* _RDMA_IB_H */
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index cee9802..f806dbd 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -96,7 +96,7 @@
if (unlikely(in_interrupt() ||
current->flags & (PF_KTHREAD | PF_EXITING)))
return -EPERM;
- if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
+ if (unlikely(uaccess_kernel()))
return -EPERM;
if (!access_ok(VERIFY_WRITE, unsafe_ptr, size))
return -EPERM;
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index e68604a..97db876 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -413,7 +413,7 @@
size_t count)
{
/* It will get better. Eventually... */
- if (segment_eq(get_fs(), KERNEL_DS)) {
+ if (uaccess_kernel()) {
direction |= ITER_KVEC;
i->type = direction;
i->kvec = (struct kvec *)iov;
diff --git a/mm/memory.c b/mm/memory.c
index a97a4ce..e8f4e10 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4136,7 +4136,7 @@
* get paged out, therefore we'll never actually fault, and the
* below annotations will generate false positives.
*/
- if (segment_eq(get_fs(), KERNEL_DS))
+ if (uaccess_kernel())
return;
if (pagefault_disabled())
return;
diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c
index 9752771..6c02ac4 100644
--- a/security/tomoyo/network.c
+++ b/security/tomoyo/network.c
@@ -608,7 +608,7 @@
static bool tomoyo_kernel_service(void)
{
/* Nothing to do if I am a kernel service. */
- return segment_eq(get_fs(), KERNEL_DS);
+ return uaccess_kernel();
}
/**