Annotation of qemu/linux-user/uaccess.c, revision 1.1.1.2

1.1       root        1: /* User memory access */
                      2: #include <stdio.h>
                      3: #include <string.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: /* XXX: use host strnlen if available ? */
                     41: static int qemu_strnlen(const char *s, int max_len)
                     42: {
                     43:     int i;
                     44:     for(i = 0; i < max_len; i++) {
                     45:         if (s[i] == '\0')
                     46:             break;
                     47:     }
                     48:     return i;
                     49: }
                     50: 
                     51: /* Return the length of a string in target memory or -TARGET_EFAULT if
                     52:    access error  */
                     53: abi_long target_strlen(abi_ulong guest_addr1)
                     54: {
                     55:     uint8_t *ptr;
                     56:     abi_ulong guest_addr;
                     57:     int max_len, len;
                     58: 
                     59:     guest_addr = guest_addr1;
                     60:     for(;;) {
                     61:         max_len = TARGET_PAGE_SIZE - (guest_addr & ~TARGET_PAGE_MASK);
                     62:         ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1);
                     63:         if (!ptr)
                     64:             return -TARGET_EFAULT;
1.1.1.2 ! root       65:         len = qemu_strnlen((const char *)ptr, max_len);
1.1       root       66:         unlock_user(ptr, guest_addr, 0);
                     67:         guest_addr += len;
                     68:         /* we don't allow wrapping or integer overflow */
                     69:         if (guest_addr == 0 || 
                     70:             (guest_addr - guest_addr1) > 0x7fffffff)
                     71:             return -TARGET_EFAULT;
                     72:         if (len != max_len)
                     73:             break;
                     74:     }
                     75:     return guest_addr - guest_addr1;
                     76: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.