This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM A53 copy_to_user failed

Hi all

I want to use copy_to_user to copy data to kernel space buffer.

I have following test:

mm_segment_t fs;

char *src, *dsr;

int ret;

fs = get_fs();

set_fs(KERNEL_DS);

src = kmalloc(0x10, GFP_KERNEL);

dst = kmalloc(0x10, GFP_KERNEL);

ret = copy_to_user(dst, src, 0x10);

set_fs(fs);

If test run in kernel version 5.10, ret = 0x10, if run in kernel verion 4.19, ret = 0x0.

I have checked the ttbr0_el1/ttbr1_el1/tcr_el1, all seems well, I also checked the pagetable of src/dst in kernel 5.10 and in kernel 4.19 separately, look like same. 

I also digged into the copy_to_user, found that dst pagefault in  kernel 5.10, finally reach to the lable 9998 of __arch_copy_to_user, if I change x0 to 0 after 9998, copy_to_uesr got 0x0.

If something I missed in kernel 5.10?  If anyone could give me some advice

Parents
  • I guess that Kernel 5.10 enhances the security check for memory protection.  Maybe your detailed logs can help further analysis.

    In your example code,  dst pointer is a kernel space memory (it should be user space memory) , which doesn't obey the API expectation of __copy_to_user().

    unsigned long __copy_to_user ( void __user * to,
      const void * from,
      unsigned long n);

    Arguments

    void __user * to

    Destination address, in user space.

    const void * from

    Source address, in kernel space.

    unsigned long n

    Number of bytes to copy.

Reply
  • I guess that Kernel 5.10 enhances the security check for memory protection.  Maybe your detailed logs can help further analysis.

    In your example code,  dst pointer is a kernel space memory (it should be user space memory) , which doesn't obey the API expectation of __copy_to_user().

    unsigned long __copy_to_user ( void __user * to,
      const void * from,
      unsigned long n);

    Arguments

    void __user * to

    Destination address, in user space.

    const void * from

    Source address, in kernel space.

    unsigned long n

    Number of bytes to copy.

Children