Thread (36 messages) flat view 36 messages, 12 authors, 2016-03-08
STALE3808d

Revision v2 of 2 in this series.

Revisions (2)
  1. v2 [diff vs current]
  2. v2 current

[PATCH v2 0/5] arm64: kernel: Add support for User Access Override

From: Russell King - ARM Linux <hidden>
Date: 2016-03-07 17:51:28

On Mon, Mar 07, 2016 at 05:40:23PM +0000, James Morse wrote:
On 07/03/16 17:23, Russell King - ARM Linux wrote:
quoted
On Mon, Mar 07, 2016 at 04:43:19PM +0000, James Morse wrote:
quoted
As far as I can see, this would only affect arm64. I can't find an equivalent
memset() for x86_64.
I don't think you've looked hard enough. :)
Heh, Thanks! I ignored the 32bit code and instead got lost in the maze of
underscores and alternative-strings for the 64 bit path.

Having seen that path, I've now found:
quoted
/* If the destination is a kernel buffer, we always clear the end */
if (!__addr_ok(to))
	memset(to, 0, len);
in arch/x86/lib/usercopy_64.c:copy_user_handle_tail(), which may be the x86_64
equivalent, or I may be lost in the maze again.
x86_64 has the function in assembler:

/* Standard copy_from_user with segment limit checking */
ENTRY(_copy_from_user)
        GET_THREAD_INFO(%rax)
        movq %rsi,%rcx
        addq %rdx,%rcx
        jc bad_from_user
        cmpq TI_addr_limit(%rax),%rcx
        ja bad_from_user
        ALTERNATIVE_2 "jmp copy_user_generic_unrolled",         \
                      "jmp copy_user_generic_string",           \
                      X86_FEATURE_REP_GOOD,                     \
                      "jmp copy_user_enhanced_fast_string",     \
                      X86_FEATURE_ERMS
ENDPROC(_copy_from_user)

        .section .fixup,"ax"
        /* must zero dest */
ENTRY(bad_from_user)
bad_from_user:
        movl %edx,%ecx
        xorl %eax,%eax
        rep
        stosb
bad_to_user:
        movl %edx,%eax
        ret
ENDPROC(bad_from_user)

The memset() are the 4 instructions after bad_from_user:.  This will
be triggered if 'from' is an invalid address.

However, you're right that we end up in copy_user_handle_tail() if
we fault, which will try to copy as much data and then memset() the
remainder.  Since this is used for both copy_from_user() and
copy_to_user() I think the __addr_ok() is just a side-effect of
avoiding memsetting for the copy_to_user() case.

-- 
RMK's Patch system: http://www.arm.linux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help