1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2 * Barret Rhoden <brho@cs.berkeley.edu>
3 * Andrew Waterman <waterman@cs.berkeley.edu>
4 * See LICENSE for details.
6 * Functions for working with userspace's address space. */
10 #include <ros/common.h>
13 /* Is this a valid user pointer for read/write? It doesn't care if the address
14 * is paged out or even an unmapped region: simply if it is in part of the
15 * address space that could be RW user. Will also check for len bytes. */
16 static inline bool is_user_rwaddr(const void *addr, size_t len);
17 /* Same deal, but read-only */
18 static inline bool is_user_raddr(const void *addr, size_t len);
20 #include <arch/uaccess.h>
22 int strcpy_from_user(struct proc *p, char *dst, const char *src);
23 int strcpy_to_user(struct proc *p, char *dst, const char *src);
26 * @brief Copies data from a user buffer to a kernel buffer.
28 * @param p the process associated with the user program
29 * from which the buffer is being copied
30 * @param dest the destination address of the kernel buffer
31 * @param va the address of the userspace buffer from which we are copying
32 * @param len the length of the userspace buffer
34 * @return ESUCCESS on success
35 * @return -EFAULT the page assocaited with 'va' is not present, the user
36 * lacks the proper permissions, or there was an invalid 'va'
38 int memcpy_from_user(struct proc *p, void *dest, const void *va, size_t len);
41 * @brief Copies data to a user buffer from a kernel buffer.
43 * @param p the process associated with the user program
44 * to which the buffer is being copied
45 * @param dest the destination address of the user buffer
46 * @param src the address of the kernel buffer from which we are copying
47 * @param len the length of the user buffer
49 * @return ESUCCESS on success
50 * @return -EFAULT the page assocaited with 'va' is not present, the user
51 * lacks the proper permissions, or there was an invalid 'va'
53 int memcpy_to_user(struct proc *p, void *dest, const void *src, size_t len);
55 /* Same as above, but sets errno */
56 int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len);
57 int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len);
58 void memcpy_to_safe(void *dst, const void *src, size_t amt);
59 void memcpy_from_safe(void *dst, const void *src, size_t amt);
61 /* Creates a buffer (kmalloc) and safely copies into it from va. Can return an
62 * error code. Check its response with IS_ERR(). Must be paired with
63 * user_memdup_free() if this succeeded. */
64 void *user_memdup(struct proc *p, const void *va, int len);
65 /* Same as above, but sets errno */
66 void *user_memdup_errno(struct proc *p, const void *va, int len);
67 void user_memdup_free(struct proc *p, void *va);
68 /* Same as memdup, but just does strings. still needs memdup_freed */
69 char *user_strdup(struct proc *p, const char *u_string, size_t strlen);
70 char *user_strdup_errno(struct proc *p, const char *u_string, size_t strlen);
71 char *copy_in_path(struct proc *p, const char *path, size_t path_l);
72 void free_path(struct proc *p, char *t_path);
73 void *kmalloc_errno(int len);
74 bool uva_is_kva(struct proc *p, void *uva, void *kva);
75 uintptr_t uva2kva(struct proc *p, void *uva, size_t len, int prot);
76 /* In arch/pmap{64}.c */
77 uintptr_t gva2gpa(struct proc *p, uintptr_t cr3, uintptr_t gva);
79 /* Helper for is_user_r{w,}addr.
81 * These checks are for addresses that the kernel accesses on behalf of the
82 * user, which are mapped into the user's address space. One interpretation is
83 * whether or not the user is allowed to refer to this memory, hence the
84 * MMAP_LOWEST_VA check. But note that the user is allowed to attempt virtual
85 * memory accesses outside of this range. VMM code may interpose on low memory
86 * PFs to emulate certain instructions. However, the kernel should never be
87 * given such a pointer.
89 * Without the MMAP_LOWEST_VA check, the kernel would still PF on a bad user
90 * pointer (say the user gave us 0x10; we have nothing mapped at addr 0).
91 * However, it would be more difficult to detect if the PF was the kernel acting
92 * on behalf of the user or if the kernel itself had a null pointer deref. By
93 * checking early, the kernel will catch low addresses and error out before page
95 static inline bool __is_user_addr(const void *addr, size_t len, uintptr_t lim)
97 if (unlikely((uintptr_t) addr < MMAP_LOWEST_VA))
99 if (unlikely((uintptr_t) addr >= lim))
101 if (unlikely(lim - (uintptr_t) addr < len))
107 static inline size_t __valid_user_bytes_from(const void *addr, uintptr_t lim)
109 if (unlikely((uintptr_t) addr < MMAP_LOWEST_VA))
111 if (unlikely((uintptr_t) addr >= lim))
114 return (size_t) (lim - (uintptr_t) addr);
117 /* UWLIM is defined as virtual address below which a process can write */
118 static inline bool is_user_rwaddr(const void *addr, size_t len)
120 return __is_user_addr(addr, len, UWLIM);
123 /* ULIM is defined as virtual address below which a process can read */
124 static inline bool is_user_raddr(const void *addr, size_t len)
126 return __is_user_addr(addr, len, ULIM);
129 static inline size_t valid_user_rwbytes_from(const void *addr)
131 return __valid_user_bytes_from(addr, UWLIM);
134 static inline size_t valid_user_rbytes_from(const void *addr)
136 return __valid_user_bytes_from(addr, ULIM);