2005-06-24 13:01:26 +08:00
|
|
|
/*
|
|
|
|
* include/asm-xtensa/uaccess.h
|
|
|
|
*
|
|
|
|
* User space memory access functions
|
|
|
|
*
|
|
|
|
* These routines provide basic accessing functions to the user memory
|
2010-08-07 03:11:15 +08:00
|
|
|
* space for the kernel. This header file provides functions such as:
|
2005-06-24 13:01:26 +08:00
|
|
|
*
|
|
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2001 - 2005 Tensilica Inc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _XTENSA_UACCESS_H
|
|
|
|
#define _XTENSA_UACCESS_H
|
|
|
|
|
2011-07-26 08:11:54 +08:00
|
|
|
#include <linux/prefetch.h>
|
2011-06-20 22:08:07 +08:00
|
|
|
#include <asm/types.h>
|
2016-12-26 03:34:44 +08:00
|
|
|
#include <asm/extable.h>
|
uaccess: generalize access_ok()
There are many different ways that access_ok() is defined across
architectures, but in the end, they all just compare against the
user_addr_max() value or they accept anything.
Provide one definition that works for most architectures, checking
against TASK_SIZE_MAX for user processes or skipping the check inside
of uaccess_kernel() sections.
For architectures without CONFIG_SET_FS(), this should be the fastest
check, as it comes down to a single comparison of a pointer against a
compile-time constant, while the architecture specific versions tend to
do something more complex for historic reasons or get something wrong.
Type checking for __user annotations is handled inconsistently across
architectures, but this is easily simplified as well by using an inline
function that takes a 'const void __user *' argument. A handful of
callers need an extra __user annotation for this.
Some architectures had trick to use 33-bit or 65-bit arithmetic on the
addresses to calculate the overflow, however this simpler version uses
fewer registers, which means it can produce better object code in the
end despite needing a second (statically predicted) branch.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Mark Rutland <mark.rutland@arm.com> [arm64, asm-generic]
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Stafford Horne <shorne@gmail.com>
Acked-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2022-02-16 00:55:04 +08:00
|
|
|
#include <asm-generic/access_ok.h>
|
2017-12-18 06:43:15 +08:00
|
|
|
|
2005-06-24 13:01:26 +08:00
|
|
|
/*
|
|
|
|
* These are the main single-value transfer routines. They
|
|
|
|
* automatically use the right size if we just have the right pointer
|
|
|
|
* type.
|
|
|
|
*
|
|
|
|
* This gets kind of ugly. We want to return _two_ values in
|
|
|
|
* "get_user()" and yet we don't want to do any pointers, because that
|
|
|
|
* is too much of a performance impact. Thus we have a few rather ugly
|
|
|
|
* macros here, and hide all the uglyness from the user.
|
|
|
|
*
|
|
|
|
* Careful to not
|
|
|
|
* (a) re-use the arguments for side effects (sizeof is ok)
|
|
|
|
* (b) require any knowledge of processes at this stage
|
|
|
|
*/
|
2015-01-06 21:11:13 +08:00
|
|
|
#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
|
|
|
|
#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
|
2005-06-24 13:01:26 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The "__xxx" versions of the user access functions are versions that
|
|
|
|
* do not verify the address space, that must have been done previously
|
|
|
|
* with a separate "access_ok()" call (this is used when we do multiple
|
|
|
|
* accesses to the same area of user memory).
|
|
|
|
*/
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
|
|
|
|
#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
|
2005-06-24 13:01:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
extern long __put_user_bad(void);
|
|
|
|
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __put_user_nocheck(x, ptr, size) \
|
2005-06-24 13:01:26 +08:00
|
|
|
({ \
|
|
|
|
long __pu_err; \
|
2015-01-06 21:11:13 +08:00
|
|
|
__put_user_size((x), (ptr), (size), __pu_err); \
|
2005-06-24 13:01:26 +08:00
|
|
|
__pu_err; \
|
|
|
|
})
|
|
|
|
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __put_user_check(x, ptr, size) \
|
|
|
|
({ \
|
|
|
|
long __pu_err = -EFAULT; \
|
2020-05-23 01:54:32 +08:00
|
|
|
__typeof__(*(ptr)) __user *__pu_addr = (ptr); \
|
Remove 'type' argument from access_ok() function
Nobody has actually used the type (VERIFY_READ vs VERIFY_WRITE) argument
of the user address range verification function since we got rid of the
old racy i386-only code to walk page tables by hand.
It existed because the original 80386 would not honor the write protect
bit when in kernel mode, so you had to do COW by hand before doing any
user access. But we haven't supported that in a long time, and these
days the 'type' argument is a purely historical artifact.
A discussion about extending 'user_access_begin()' to do the range
checking resulted this patch, because there is no way we're going to
move the old VERIFY_xyz interface to that model. And it's best done at
the end of the merge window when I've done most of my merges, so let's
just get this done once and for all.
This patch was mostly done with a sed-script, with manual fix-ups for
the cases that weren't of the trivial 'access_ok(VERIFY_xyz' form.
There were a couple of notable cases:
- csky still had the old "verify_area()" name as an alias.
- the iter_iov code had magical hardcoded knowledge of the actual
values of VERIFY_{READ,WRITE} (not that they mattered, since nothing
really used it)
- microblaze used the type argument for a debug printout
but other than those oddities this should be a total no-op patch.
I tried to fix up all architectures, did fairly extensive grepping for
access_ok() uses, and the changes are trivial, but I may have missed
something. Any missed conversion should be trivially fixable, though.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-01-04 10:57:57 +08:00
|
|
|
if (access_ok(__pu_addr, size)) \
|
2015-01-06 21:11:13 +08:00
|
|
|
__put_user_size((x), __pu_addr, (size), __pu_err); \
|
|
|
|
__pu_err; \
|
2005-06-24 13:01:26 +08:00
|
|
|
})
|
|
|
|
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __put_user_size(x, ptr, size, retval) \
|
2007-10-24 01:58:53 +08:00
|
|
|
do { \
|
|
|
|
int __cb; \
|
|
|
|
retval = 0; \
|
|
|
|
switch (size) { \
|
2015-01-06 21:11:13 +08:00
|
|
|
case 1: __put_user_asm(x, ptr, retval, 1, "s8i", __cb); break; \
|
|
|
|
case 2: __put_user_asm(x, ptr, retval, 2, "s16i", __cb); break; \
|
|
|
|
case 4: __put_user_asm(x, ptr, retval, 4, "s32i", __cb); break; \
|
2012-11-29 08:53:51 +08:00
|
|
|
case 8: { \
|
2007-10-24 01:58:53 +08:00
|
|
|
__typeof__(*ptr) __v64 = x; \
|
2019-10-10 03:21:05 +08:00
|
|
|
retval = __copy_to_user(ptr, &__v64, 8) ? -EFAULT : 0; \
|
2007-10-24 01:58:53 +08:00
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
default: __put_user_bad(); \
|
|
|
|
} \
|
2005-06-24 13:01:26 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Consider a case of a user single load/store would cause both an
|
|
|
|
* unaligned exception and an MMU-related exception (unaligned
|
|
|
|
* exceptions happen first):
|
|
|
|
*
|
|
|
|
* User code passes a bad variable ptr to a system call.
|
|
|
|
* Kernel tries to access the variable.
|
|
|
|
* Unaligned exception occurs.
|
|
|
|
* Unaligned exception handler tries to make aligned accesses.
|
|
|
|
* Double exception occurs for MMU-related cause (e.g., page not mapped).
|
|
|
|
* do_page_fault() thinks the fault address belongs to the kernel, not the
|
|
|
|
* user, and panics.
|
|
|
|
*
|
|
|
|
* The kernel currently prohibits user unaligned accesses. We use the
|
|
|
|
* __check_align_* macros to check for unaligned addresses before
|
|
|
|
* accessing user space so we don't crash the kernel. Both
|
|
|
|
* __put_user_asm and __get_user_asm use these alignment macros, so
|
|
|
|
* macro-specific labels such as 0f, 1f, %0, %2, and %3 must stay in
|
|
|
|
* sync.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define __check_align_1 ""
|
|
|
|
|
|
|
|
#define __check_align_2 \
|
2019-10-16 05:03:03 +08:00
|
|
|
" _bbci.l %[mem] * 0, 1f \n" \
|
2019-10-10 10:41:24 +08:00
|
|
|
" movi %[err], %[efault] \n" \
|
2005-06-24 13:01:26 +08:00
|
|
|
" _j 2f \n"
|
|
|
|
|
|
|
|
#define __check_align_4 \
|
2019-10-16 05:03:03 +08:00
|
|
|
" _bbsi.l %[mem] * 0, 0f \n" \
|
|
|
|
" _bbci.l %[mem] * 0 + 1, 1f \n" \
|
2019-10-10 10:41:24 +08:00
|
|
|
"0: movi %[err], %[efault] \n" \
|
2005-06-24 13:01:26 +08:00
|
|
|
" _j 2f \n"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We don't tell gcc that we are accessing memory, but this is OK
|
|
|
|
* because we do not write to any memory gcc knows about, so there
|
|
|
|
* are no aliasing issues.
|
|
|
|
*
|
|
|
|
* WARNING: If you modify this macro at all, verify that the
|
|
|
|
* __check_align_* macros still work.
|
|
|
|
*/
|
2019-10-10 10:41:24 +08:00
|
|
|
#define __put_user_asm(x_, addr_, err_, align, insn, cb)\
|
2012-11-29 08:53:51 +08:00
|
|
|
__asm__ __volatile__( \
|
2007-10-24 01:58:53 +08:00
|
|
|
__check_align_##align \
|
2019-10-16 05:03:03 +08:00
|
|
|
"1: "insn" %[x], %[mem] \n" \
|
2007-10-24 01:58:53 +08:00
|
|
|
"2: \n" \
|
|
|
|
" .section .fixup,\"ax\" \n" \
|
|
|
|
" .align 4 \n" \
|
2018-12-06 04:48:19 +08:00
|
|
|
" .literal_position \n" \
|
2007-10-24 01:58:53 +08:00
|
|
|
"5: \n" \
|
2019-10-10 10:41:24 +08:00
|
|
|
" movi %[tmp], 2b \n" \
|
|
|
|
" movi %[err], %[efault] \n" \
|
|
|
|
" jx %[tmp] \n" \
|
2007-10-24 01:58:53 +08:00
|
|
|
" .previous \n" \
|
|
|
|
" .section __ex_table,\"a\" \n" \
|
|
|
|
" .long 1b, 5b \n" \
|
|
|
|
" .previous" \
|
2019-10-16 05:03:03 +08:00
|
|
|
:[err] "+r"(err_), [tmp] "=r"(cb), [mem] "=m"(*(addr_)) \
|
|
|
|
:[x] "r"(x_), [efault] "i"(-EFAULT))
|
2005-06-24 13:01:26 +08:00
|
|
|
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __get_user_nocheck(x, ptr, size) \
|
2005-06-24 13:01:26 +08:00
|
|
|
({ \
|
2019-10-11 11:55:35 +08:00
|
|
|
long __gu_err; \
|
|
|
|
__get_user_size((x), (ptr), (size), __gu_err); \
|
2005-06-24 13:01:26 +08:00
|
|
|
__gu_err; \
|
|
|
|
})
|
|
|
|
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __get_user_check(x, ptr, size) \
|
2005-06-24 13:01:26 +08:00
|
|
|
({ \
|
2019-10-11 11:55:35 +08:00
|
|
|
long __gu_err = -EFAULT; \
|
2020-05-23 01:54:32 +08:00
|
|
|
const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
|
2019-10-11 11:55:35 +08:00
|
|
|
if (access_ok(__gu_addr, size)) \
|
|
|
|
__get_user_size((x), __gu_addr, (size), __gu_err); \
|
|
|
|
else \
|
2020-05-23 06:52:03 +08:00
|
|
|
(x) = (__typeof__(*(ptr)))0; \
|
2005-06-24 13:01:26 +08:00
|
|
|
__gu_err; \
|
|
|
|
})
|
|
|
|
|
|
|
|
extern long __get_user_bad(void);
|
|
|
|
|
2015-01-06 21:11:13 +08:00
|
|
|
#define __get_user_size(x, ptr, size, retval) \
|
2005-06-24 13:01:26 +08:00
|
|
|
do { \
|
2007-10-24 01:58:53 +08:00
|
|
|
int __cb; \
|
2005-06-24 13:01:26 +08:00
|
|
|
retval = 0; \
|
2012-11-29 08:53:51 +08:00
|
|
|
switch (size) { \
|
2015-01-06 21:11:13 +08:00
|
|
|
case 1: __get_user_asm(x, ptr, retval, 1, "l8ui", __cb); break;\
|
|
|
|
case 2: __get_user_asm(x, ptr, retval, 2, "l16ui", __cb); break;\
|
|
|
|
case 4: __get_user_asm(x, ptr, retval, 4, "l32i", __cb); break;\
|
2019-10-10 03:21:05 +08:00
|
|
|
case 8: { \
|
|
|
|
u64 __x; \
|
|
|
|
if (unlikely(__copy_from_user(&__x, ptr, 8))) { \
|
|
|
|
retval = -EFAULT; \
|
2020-05-23 06:52:03 +08:00
|
|
|
(x) = (__typeof__(*(ptr)))0; \
|
2019-10-10 03:21:05 +08:00
|
|
|
} else { \
|
2020-05-23 04:20:05 +08:00
|
|
|
(x) = *(__force __typeof__(*(ptr)) *)&__x; \
|
2019-10-10 03:21:05 +08:00
|
|
|
} \
|
|
|
|
break; \
|
|
|
|
} \
|
2020-05-23 06:52:03 +08:00
|
|
|
default: \
|
|
|
|
(x) = (__typeof__(*(ptr)))0; \
|
|
|
|
__get_user_bad(); \
|
2012-11-29 08:53:51 +08:00
|
|
|
} \
|
2005-06-24 13:01:26 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* WARNING: If you modify this macro at all, verify that the
|
|
|
|
* __check_align_* macros still work.
|
|
|
|
*/
|
2019-10-10 10:41:24 +08:00
|
|
|
#define __get_user_asm(x_, addr_, err_, align, insn, cb) \
|
2019-10-11 11:55:35 +08:00
|
|
|
do { \
|
|
|
|
u32 __x = 0; \
|
|
|
|
__asm__ __volatile__( \
|
|
|
|
__check_align_##align \
|
2019-10-16 05:03:03 +08:00
|
|
|
"1: "insn" %[x], %[mem] \n" \
|
2019-10-11 11:55:35 +08:00
|
|
|
"2: \n" \
|
|
|
|
" .section .fixup,\"ax\" \n" \
|
|
|
|
" .align 4 \n" \
|
|
|
|
" .literal_position \n" \
|
|
|
|
"5: \n" \
|
|
|
|
" movi %[tmp], 2b \n" \
|
|
|
|
" movi %[err], %[efault] \n" \
|
|
|
|
" jx %[tmp] \n" \
|
|
|
|
" .previous \n" \
|
|
|
|
" .section __ex_table,\"a\" \n" \
|
|
|
|
" .long 1b, 5b \n" \
|
|
|
|
" .previous" \
|
|
|
|
:[err] "+r"(err_), [tmp] "=r"(cb), [x] "+r"(__x) \
|
2019-10-16 05:03:03 +08:00
|
|
|
:[mem] "m"(*(addr_)), [efault] "i"(-EFAULT)); \
|
2019-10-11 11:55:35 +08:00
|
|
|
(x_) = (__force __typeof__(*(addr_)))__x; \
|
|
|
|
} while (0)
|
2005-06-24 13:01:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy to/from user space
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern unsigned __xtensa_copy_user(void *to, const void *from, unsigned n);
|
|
|
|
|
|
|
|
static inline unsigned long
|
2017-03-23 01:02:41 +08:00
|
|
|
raw_copy_from_user(void *to, const void __user *from, unsigned long n)
|
2005-06-24 13:01:26 +08:00
|
|
|
{
|
2017-03-23 01:02:41 +08:00
|
|
|
prefetchw(to);
|
|
|
|
return __xtensa_copy_user(to, (__force const void *)from, n);
|
2005-06-24 13:01:26 +08:00
|
|
|
}
|
|
|
|
static inline unsigned long
|
2017-03-23 01:02:41 +08:00
|
|
|
raw_copy_to_user(void __user *to, const void *from, unsigned long n)
|
2005-06-24 13:01:26 +08:00
|
|
|
{
|
2017-04-05 04:26:29 +08:00
|
|
|
prefetch(from);
|
2017-03-23 01:02:41 +08:00
|
|
|
return __xtensa_copy_user((__force void *)to, from, n);
|
2005-06-24 13:01:26 +08:00
|
|
|
}
|
2017-03-23 01:02:41 +08:00
|
|
|
#define INLINE_COPY_FROM_USER
|
|
|
|
#define INLINE_COPY_TO_USER
|
2005-06-24 13:01:26 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to return the number of bytes not cleared. Our memset()
|
|
|
|
* returns zero if a problem occurs while accessing user-space memory.
|
|
|
|
* In that event, return no memory cleared. Otherwise, zero for
|
|
|
|
* success.
|
|
|
|
*/
|
|
|
|
|
2005-09-04 06:57:53 +08:00
|
|
|
static inline unsigned long
|
2020-05-23 02:40:20 +08:00
|
|
|
__xtensa_clear_user(void __user *addr, unsigned long size)
|
2005-06-24 13:01:26 +08:00
|
|
|
{
|
2020-05-23 02:40:20 +08:00
|
|
|
if (!__memset((void __force *)addr, 0, size))
|
2005-06-24 13:01:26 +08:00
|
|
|
return size;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-09-04 06:57:53 +08:00
|
|
|
static inline unsigned long
|
2020-05-23 02:40:20 +08:00
|
|
|
clear_user(void __user *addr, unsigned long size)
|
2005-06-24 13:01:26 +08:00
|
|
|
{
|
Remove 'type' argument from access_ok() function
Nobody has actually used the type (VERIFY_READ vs VERIFY_WRITE) argument
of the user address range verification function since we got rid of the
old racy i386-only code to walk page tables by hand.
It existed because the original 80386 would not honor the write protect
bit when in kernel mode, so you had to do COW by hand before doing any
user access. But we haven't supported that in a long time, and these
days the 'type' argument is a purely historical artifact.
A discussion about extending 'user_access_begin()' to do the range
checking resulted this patch, because there is no way we're going to
move the old VERIFY_xyz interface to that model. And it's best done at
the end of the merge window when I've done most of my merges, so let's
just get this done once and for all.
This patch was mostly done with a sed-script, with manual fix-ups for
the cases that weren't of the trivial 'access_ok(VERIFY_xyz' form.
There were a couple of notable cases:
- csky still had the old "verify_area()" name as an alias.
- the iter_iov code had magical hardcoded knowledge of the actual
values of VERIFY_{READ,WRITE} (not that they mattered, since nothing
really used it)
- microblaze used the type argument for a debug printout
but other than those oddities this should be a total no-op patch.
I tried to fix up all architectures, did fairly extensive grepping for
access_ok() uses, and the changes are trivial, but I may have missed
something. Any missed conversion should be trivially fixable, though.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-01-04 10:57:57 +08:00
|
|
|
if (access_ok(addr, size))
|
2005-06-24 13:01:26 +08:00
|
|
|
return __xtensa_clear_user(addr, size);
|
|
|
|
return size ? -EFAULT : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define __clear_user __xtensa_clear_user
|
|
|
|
|
|
|
|
|
2021-05-17 15:22:34 +08:00
|
|
|
#ifdef CONFIG_ARCH_HAS_STRNCPY_FROM_USER
|
2020-05-23 02:40:20 +08:00
|
|
|
extern long __strncpy_user(char *dst, const char __user *src, long count);
|
2005-06-24 13:01:26 +08:00
|
|
|
|
2005-09-04 06:57:53 +08:00
|
|
|
static inline long
|
2020-05-23 02:40:20 +08:00
|
|
|
strncpy_from_user(char *dst, const char __user *src, long count)
|
2005-06-24 13:01:26 +08:00
|
|
|
{
|
Remove 'type' argument from access_ok() function
Nobody has actually used the type (VERIFY_READ vs VERIFY_WRITE) argument
of the user address range verification function since we got rid of the
old racy i386-only code to walk page tables by hand.
It existed because the original 80386 would not honor the write protect
bit when in kernel mode, so you had to do COW by hand before doing any
user access. But we haven't supported that in a long time, and these
days the 'type' argument is a purely historical artifact.
A discussion about extending 'user_access_begin()' to do the range
checking resulted this patch, because there is no way we're going to
move the old VERIFY_xyz interface to that model. And it's best done at
the end of the merge window when I've done most of my merges, so let's
just get this done once and for all.
This patch was mostly done with a sed-script, with manual fix-ups for
the cases that weren't of the trivial 'access_ok(VERIFY_xyz' form.
There were a couple of notable cases:
- csky still had the old "verify_area()" name as an alias.
- the iter_iov code had magical hardcoded knowledge of the actual
values of VERIFY_{READ,WRITE} (not that they mattered, since nothing
really used it)
- microblaze used the type argument for a debug printout
but other than those oddities this should be a total no-op patch.
I tried to fix up all architectures, did fairly extensive grepping for
access_ok() uses, and the changes are trivial, but I may have missed
something. Any missed conversion should be trivially fixable, though.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2019-01-04 10:57:57 +08:00
|
|
|
if (access_ok(src, 1))
|
2017-04-08 05:54:24 +08:00
|
|
|
return __strncpy_user(dst, src, count);
|
2005-06-24 13:01:26 +08:00
|
|
|
return -EFAULT;
|
|
|
|
}
|
2017-12-18 06:43:15 +08:00
|
|
|
#else
|
2020-09-01 05:09:37 +08:00
|
|
|
long strncpy_from_user(char *dst, const char __user *src, long count);
|
2017-12-18 06:43:15 +08:00
|
|
|
#endif
|
2005-06-24 13:01:26 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the size of a string (including the ending 0!)
|
|
|
|
*/
|
2020-05-23 02:40:20 +08:00
|
|
|
extern long __strnlen_user(const char __user *str, long len);
|
2005-06-24 13:01:26 +08:00
|
|
|
|
2020-05-23 02:40:20 +08:00
|
|
|
static inline long strnlen_user(const char __user *str, long len)
|
2005-06-24 13:01:26 +08:00
|
|
|
{
|
2020-05-23 02:40:20 +08:00
|
|
|
if (!access_ok(str, 1))
|
2005-06-24 13:01:26 +08:00
|
|
|
return 0;
|
|
|
|
return __strnlen_user(str, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* _XTENSA_UACCESS_H */
|