linux/lib/strncpy_from_user.c
<<
valu12valu12>>vavaluvalu12 ">valu12valu12Searchvalu12Prefs. 12vava ">vlu12 2.
2 21#include <linux/module.h> 2 22#include <linux/uaccess.h> 2 23#include <linux/kernel.h> 2 24#include <linux/errno.h> 2 25v2 26#include <asm/byteorder.h> 2 27#include <asm/word-at-a-time.h> 2 28v2 29#ifdef2CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESSv2 " a>#define2IS_UNALIGNED a>(src a>,2dst a>) 0v2 11#elsev2 12 a>#define2IS_UNALIGNED a>(src a>,2dst a>) \v2 13 (((long)2dst a> | (long)2src a>) & (sizeof(long)2- 1))v2 14#endifv2 15v2 16/*2 17 * Do a strncpy, return length of string without final '\0'.2 18 * 'count' is the user-supplied count (return 'count' if we2 19 * hit it), 'max' is the address space maximum (and we return2 20 * -EFAULT if we hit it).2 21 */2 22 a>static2inline a> long2do_strncpy_from_user a>(char *dst a>, const char __user a> *src a>,2long2count a>,2unsigned long2max a>).2 23{.2 24 const struct2word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; 2 25 long2res = 0; 2 26v2 27 /*2 28 * Truncate 'max' to the user-specified limit, so that2 29 * we only have one limit we need to check in the loop2 30 */2 31 if (max a> >2count a>).2 32 max a> = count a>; 2 33v2 34 if (IS_UNALIGNED a>(src a>,2dst a>)).2 35 goto byte_at_a_time a>; 2 36v2 37 while (max a> >= sizeof(unsigned long)) {.2 38 unsigned long2c a>,2data a>; 2 39v2 40 /* Fall back to byte-at-a-time if we get a page fault */2 41 if (unlikely a>(__get_user a>(c a>,(unsigned long2__user a> *)(src a>+res)))).2 42 break; 2 43 *(unsigned long2*)(dst a>+res) = c a>; 2 44 if (has_zero a>(c a>, &data a>, &constants)) {.2 45 data a> = prep_zero_mask a>(c a>, data a>, &constants); 2 46 data a> = create_zero_mask a>(data a>); 2 47 return res + find_zero a>(data a>); 2 48 } 2 49 res += sizeof(unsigned long); 2 50 max a> -= sizeof(unsigned long); 2 51 } 2 52v2 53byte_at_a_time a>:v2 54 while (max a>) {.2 55 char c a>; 2 56v2 57 if (unlikely a>(__get_user a>(c a>,src a>+res)))v2 58 return -EFAULT a>; 2 59 dst a>[res] = c a>; 2 60 if (!c a>)v2 61 return res; 2 62 res++; 2 63 max a>--; 2 64 } 2 65v2 66 /*2 67 * Uhhuh. We hit 'max'. But was that the user-specified maximum2 68 * too? If so, that's ok - we got as much as the user asked for.2 69 */2 70 if (res >= count a>).2 71 return res; 2 72v2 73 /*2 74 * Nope: we hit the address space limit, and we still had more2 75 * characters the caller would have wanted. That's av EFAULT.2 76 */2 77 return -EFAULT a>; 2 78} 2 79v2 80/**2 81 * strncpy_from_user: - Copy a NUL terminated string from userspace.2 82 * @dst: Destinattionaddress, in kernel space. This buffer must be at2 83 * least @count bytes long.2 84 * @src: Sourcenaddress, in user space.2 85 * @count: Maximum number of bytes to copy, including the trailing NUL.2 86 *2 87 * Copies a NUL-terminated string from userspace to kernel space.2 88 *2 89 * On success, returns the length of the string (not including the trailing2 90 * NUL).2 91 *2 92 * If access to userspace fails, returns -EFAULT (some data may have been2 93 * copied).2 94 *2 95 * If @count is smaller than the length of the string, copies @count bytes2 96 * and returns @count.2 97 */2 98long2strncpy_from_user a>(char *dst a>, const char __user a> *src a>,2long2count a>).2 99{.2100 unsigned long2max_addr a>, src_addr a>; 2101v2102 if (unlikely a>(count a> <= 0))v2103 return 0; 2104v2105 max_addr a> = user_addr_max a>(); 2106 src_addr a> = (unsigned long)src a>; 2107 if (likely a>(src_addr a> < max_addr a>)) {.2108 unsigned long2max a> = max_addr a> - src_addr a>; 2109 return do_strncpy_from_user a>(dst a>, src a>,2count a>,2max a>); 2110 } 2111 return -EFAULT a>; 2112 a>} 2113EXPORT_SYMBOL a>(strncpy_from_user a>); 2114 The original LXR software by the LXR community a>,2this experimental verstionby lxr@linux.no a>. lxr.linux.no kindly hosted by Redpill Linpro AS a>,2provider of Linux consulting and operattios services since 1995.