qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

uaccess.c (1699B)


      1 /* User memory access */
      2 #include "qemu/osdep.h"
      3 #include "qemu/cutils.h"
      4 
      5 #include "qemu.h"
      6 
      7 /* copy_from_user() and copy_to_user() are usually used to copy data
      8  * buffers between the target and host.  These internally perform
      9  * locking/unlocking of the memory.
     10  */
     11 abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len)
     12 {
     13     abi_long ret = 0;
     14     void *ghptr;
     15 
     16     if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) {
     17         memcpy(hptr, ghptr, len);
     18         unlock_user(ghptr, gaddr, 0);
     19     } else
     20         ret = -TARGET_EFAULT;
     21 
     22     return ret;
     23 }
     24 
     25 
     26 abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len)
     27 {
     28     abi_long ret = 0;
     29     void *ghptr;
     30 
     31     if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) {
     32         memcpy(ghptr, hptr, len);
     33         unlock_user(ghptr, gaddr, len);
     34     } else
     35         ret = -TARGET_EFAULT;
     36 
     37     return ret;
     38 }
     39 
     40 /* Return the length of a string in target memory or -TARGET_EFAULT if
     41    access error  */
     42 abi_long target_strlen(abi_ulong guest_addr1)
     43 {
     44     uint8_t *ptr;
     45     abi_ulong guest_addr;
     46     int max_len, len;
     47 
     48     guest_addr = guest_addr1;
     49     for (;;) {
     50         max_len = TARGET_PAGE_SIZE - (guest_addr & ~TARGET_PAGE_MASK);
     51         ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
     52         if (!ptr)
     53             return -TARGET_EFAULT;
     54         len = qemu_strnlen((const char *)ptr, max_len);
     55         unlock_user(ptr, guest_addr, 0);
     56         guest_addr += len;
     57         /* we don't allow wrapping or integer overflow */
     58         if (guest_addr == 0 ||
     59             (guest_addr - guest_addr1) > 0x7fffffff)
     60             return -TARGET_EFAULT;
     61         if (len != max_len)
     62             break;
     63     }
     64     return guest_addr - guest_addr1;
     65 }