00001 /* 00002 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 00003 * The President and Fellows of Harvard College. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the University nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 */ 00029 00030 #include <types.h> 00031 #include <kern/errno.h> 00032 #include <lib.h> 00033 #include <setjmp.h> 00034 #include <thread.h> 00035 #include <current.h> 00036 #include <vm.h> 00037 #include <copyinout.h> 00038 00039 /* 00040 * User/kernel memory copying functions. 00041 * 00042 * These are arranged to prevent fatal kernel memory faults if invalid 00043 * addresses are supplied by user-level code. This code is itself 00044 * machine-independent; it uses the machine-dependent C setjmp/longjmp 00045 * facility to perform recovery. 00046 * 00047 * However, it assumes things about the memory subsystem that may not 00048 * be true on all platforms. 00049 * 00050 * (1) It assumes that user memory is mapped into the current address 00051 * space while running in the kernel, and can be accessed by just 00052 * dereferencing a pointer in the ordinary way. (And not, for example, 00053 * with special instructions or via special segment registers.) 00054 * 00055 * (2) It assumes that the user-space region of memory is contiguous 00056 * and extends from 0 to some virtual address USERSPACETOP, and so if 00057 * a user process passes a kernel address the logic in copycheck() 00058 * will trap it. 00059 * 00060 * (3) It assumes that access to user memory from the kernel behaves 00061 * the same way as access to user memory from user space: for 00062 * instance, that the processor honors read-only bits on memory pages 00063 * when in kernel mode. 00064 * 00065 * (4) It assumes that if a proper user-space address that is valid 00066 * but not present, or not valid at all, is touched from the kernel, 00067 * that the correct faults will occur and the VM system will load the 00068 * necessary pages and whatnot. 00069 * 00070 * (5) It assumes that the machine-dependent trap logic provides and 00071 * honors a tm_badfaultfunc field in the thread_machdep structure. 00072 * This feature works as follows: if an otherwise fatal fault occurs 00073 * in kernel mode, and tm_badfaultfunc is set, execution resumes in 00074 * the function pointed to by tm_badfaultfunc. 00075 * 00076 * This code works by setting tm_badfaultfunc and then copying memory 00077 * in an ordinary fashion. If these five assumptions are satisfied, 00078 * which is the case for many ordinary CPU types, this code should 00079 * function correctly. If the assumptions are not satisfied on some 00080 * platform (for instance, certain old 80386 processors violate 00081 * assumption 3), this code cannot be used, and cpu- or platform- 00082 * specific code must be written. 00083 * 00084 * To make use of this code, in addition to tm_badfaultfunc the 00085 * thread_machdep structure should contain a jmp_buf called 00086 * "tm_copyjmp". 00087 */ 00088 00089 /* 00090 * Recovery function. If a fatal fault occurs during copyin, copyout, 00091 * copyinstr, or copyoutstr, execution resumes here. (This behavior is 00092 * caused by setting t_machdep.tm_badfaultfunc and is implemented in 00093 * machine-dependent code.) 00094 * 00095 * We use the C standard function longjmp() to teleport up the call 00096 * stack to where setjmp() was called. At that point we return EFAULT. 00097 */ 00098 static 00099 void 00100 copyfail(void) 00101 { 00102 longjmp(curthread->t_machdep.tm_copyjmp, 1); 00103 } 00104 00105 /* 00106 * Memory region check function. This checks to make sure the block of 00107 * user memory provided (an address and a length) falls within the 00108 * proper userspace region. If it does not, EFAULT is returned. 00109 * 00110 * stoplen is set to the actual maximum length that can be copied. 00111 * This differs from len if and only if the region partially overlaps 00112 * the kernel. 00113 * 00114 * Assumes userspace runs from 0 through USERSPACETOP-1. 00115 */ 00116 static 00117 int 00118 copycheck(const_userptr_t userptr, size_t len, size_t *stoplen) 00119 { 00120 vaddr_t bot, top; 00121 00122 *stoplen = len; 00123 00124 bot = (vaddr_t) userptr; 00125 top = bot+len-1; 00126 00127 if (top < bot) { 00128 /* addresses wrapped around */ 00129 return EFAULT; 00130 } 00131 00132 if (bot >= USERSPACETOP) { 00133 /* region is within the kernel */ 00134 return EFAULT; 00135 } 00136 00137 if (top >= USERSPACETOP) { 00138 /* region overlaps the kernel. adjust the max length. */ 00139 *stoplen = USERSPACETOP - bot; 00140 } 00141 00142 return 0; 00143 } 00144 00145 /* 00146 * copyin 00147 * 00148 * Copy a block of memory of length LEN from user-level address USERSRC 00149 * to kernel address DEST. We can use memcpy because it's protected by 00150 * the tm_badfaultfunc/copyfail logic. 00151 */ 00152 int 00153 copyin(const_userptr_t usersrc, void *dest, size_t len) 00154 { 00155 int result; 00156 size_t stoplen; 00157 00158 result = copycheck(usersrc, len, &stoplen); 00159 if (result) { 00160 return result; 00161 } 00162 if (stoplen != len) { 00163 /* Single block, can't legally truncate it. */ 00164 return EFAULT; 00165 } 00166 00167 curthread->t_machdep.tm_badfaultfunc = copyfail; 00168 00169 result = setjmp(curthread->t_machdep.tm_copyjmp); 00170 if (result) { 00171 curthread->t_machdep.tm_badfaultfunc = NULL; 00172 return EFAULT; 00173 } 00174 00175 memcpy(dest, (const void *)usersrc, len); 00176 00177 curthread->t_machdep.tm_badfaultfunc = NULL; 00178 return 0; 00179 } 00180 00181 /* 00182 * copyout 00183 * 00184 * Copy a block of memory of length LEN from kernel address SRC to 00185 * user-level address USERDEST. We can use memcpy because it's 00186 * protected by the tm_badfaultfunc/copyfail logic. 00187 */ 00188 int 00189 copyout(const void *src, userptr_t userdest, size_t len) 00190 { 00191 int result; 00192 size_t stoplen; 00193 00194 result = copycheck(userdest, len, &stoplen); 00195 if (result) { 00196 return result; 00197 } 00198 if (stoplen != len) { 00199 /* Single block, can't legally truncate it. */ 00200 return EFAULT; 00201 } 00202 00203 curthread->t_machdep.tm_badfaultfunc = copyfail; 00204 00205 result = setjmp(curthread->t_machdep.tm_copyjmp); 00206 if (result) { 00207 curthread->t_machdep.tm_badfaultfunc = NULL; 00208 return EFAULT; 00209 } 00210 00211 memcpy((void *)userdest, src, len); 00212 00213 curthread->t_machdep.tm_badfaultfunc = NULL; 00214 return 0; 00215 } 00216 00217 /* 00218 * Common string copying function that behaves the way that's desired 00219 * for copyinstr and copyoutstr. 00220 * 00221 * Copies a null-terminated string of maximum length MAXLEN from SRC 00222 * to DEST. If GOTLEN is not null, store the actual length found 00223 * there. Both lengths include the null-terminator. If the string 00224 * exceeds the available length, the call fails and returns 00225 * ENAMETOOLONG. 00226 * 00227 * STOPLEN is like MAXLEN but is assumed to have come from copycheck. 00228 * If we hit MAXLEN it's because the string is too long to fit; if we 00229 * hit STOPLEN it's because the string has run into the end of 00230 * userspace. Thus in the latter case we return EFAULT, not 00231 * ENAMETOOLONG. 00232 */ 00233 static 00234 int 00235 copystr(char *dest, const char *src, size_t maxlen, size_t stoplen, 00236 size_t *gotlen) 00237 { 00238 size_t i; 00239 00240 for (i=0; i<maxlen && i<stoplen; i++) { 00241 dest[i] = src[i]; 00242 if (src[i] == 0) { 00243 if (gotlen != NULL) { 00244 *gotlen = i+1; 00245 } 00246 return 0; 00247 } 00248 } 00249 if (stoplen < maxlen) { 00250 /* ran into user-kernel boundary */ 00251 return EFAULT; 00252 } 00253 /* otherwise just ran out of space */ 00254 return ENAMETOOLONG; 00255 } 00256 00257 /* 00258 * copyinstr 00259 * 00260 * Copy a string from user-level address USERSRC to kernel address 00261 * DEST, as per copystr above. Uses the tm_badfaultfunc/copyfail 00262 * logic to protect against invalid addresses supplied by a user 00263 * process. 00264 */ 00265 int 00266 copyinstr(const_userptr_t usersrc, char *dest, size_t len, size_t *actual) 00267 { 00268 int result; 00269 size_t stoplen; 00270 00271 result = copycheck(usersrc, len, &stoplen); 00272 if (result) { 00273 return result; 00274 } 00275 00276 curthread->t_machdep.tm_badfaultfunc = copyfail; 00277 00278 result = setjmp(curthread->t_machdep.tm_copyjmp); 00279 if (result) { 00280 curthread->t_machdep.tm_badfaultfunc = NULL; 00281 return EFAULT; 00282 } 00283 00284 result = copystr(dest, (const char *)usersrc, len, stoplen, actual); 00285 00286 curthread->t_machdep.tm_badfaultfunc = NULL; 00287 return result; 00288 } 00289 00290 /* 00291 * copyoutstr 00292 * 00293 * Copy a string from kernel address SRC to user-level address 00294 * USERDEST, as per copystr above. Uses the tm_badfaultfunc/copyfail 00295 * logic to protect against invalid addresses supplied by a user 00296 * process. 00297 */ 00298 int 00299 copyoutstr(const char *src, userptr_t userdest, size_t len, size_t *actual) 00300 { 00301 int result; 00302 size_t stoplen; 00303 00304 result = copycheck(userdest, len, &stoplen); 00305 if (result) { 00306 return result; 00307 } 00308 00309 curthread->t_machdep.tm_badfaultfunc = copyfail; 00310 00311 result = setjmp(curthread->t_machdep.tm_copyjmp); 00312 if (result) { 00313 curthread->t_machdep.tm_badfaultfunc = NULL; 00314 return EFAULT; 00315 } 00316 00317 result = copystr((char *)userdest, src, len, stoplen, actual); 00318 00319 curthread->t_machdep.tm_badfaultfunc = NULL; 00320 return result; 00321 }