| Linus Torvalds | a08c535 | 2012-05-26 11:06:38 -0700 | [diff] [blame] | 1 | #include <linux/kernel.h> | 
 | 2 | #include <linux/export.h> | 
 | 3 | #include <linux/uaccess.h> | 
 | 4 |  | 
 | 5 | #include <asm/word-at-a-time.h> | 
 | 6 |  | 
 | 7 | /* Set bits in the first 'n' bytes when loaded from memory */ | 
 | 8 | #ifdef __LITTLE_ENDIAN | 
 | 9 | #  define aligned_byte_mask(n) ((1ul << 8*(n))-1) | 
 | 10 | #else | 
| Paul Mackerras | 69ea640 | 2012-05-28 12:59:56 +1000 | [diff] [blame] | 11 | #  define aligned_byte_mask(n) (~0xfful << (BITS_PER_LONG - 8 - 8*(n))) | 
| Linus Torvalds | a08c535 | 2012-05-26 11:06:38 -0700 | [diff] [blame] | 12 | #endif | 
 | 13 |  | 
 | 14 | /* | 
 | 15 |  * Do a strnlen, return length of string *with* final '\0'. | 
 | 16 |  * 'count' is the user-supplied count, while 'max' is the | 
 | 17 |  * address space maximum. | 
 | 18 |  * | 
 | 19 |  * Return 0 for exceptions (which includes hitting the address | 
 | 20 |  * space maximum), or 'count+1' if hitting the user-supplied | 
 | 21 |  * maximum count. | 
 | 22 |  * | 
 | 23 |  * NOTE! We can sometimes overshoot the user-supplied maximum | 
 | 24 |  * if it fits in a aligned 'long'. The caller needs to check | 
 | 25 |  * the return value against "> max". | 
 | 26 |  */ | 
 | 27 | static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) | 
 | 28 | { | 
 | 29 | 	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; | 
 | 30 | 	long align, res = 0; | 
 | 31 | 	unsigned long c; | 
 | 32 |  | 
 | 33 | 	/* | 
 | 34 | 	 * Truncate 'max' to the user-specified limit, so that | 
 | 35 | 	 * we only have one limit we need to check in the loop | 
 | 36 | 	 */ | 
 | 37 | 	if (max > count) | 
 | 38 | 		max = count; | 
 | 39 |  | 
 | 40 | 	/* | 
 | 41 | 	 * Do everything aligned. But that means that we | 
 | 42 | 	 * need to also expand the maximum.. | 
 | 43 | 	 */ | 
 | 44 | 	align = (sizeof(long) - 1) & (unsigned long)src; | 
 | 45 | 	src -= align; | 
 | 46 | 	max += align; | 
 | 47 |  | 
 | 48 | 	if (unlikely(__get_user(c,(unsigned long __user *)src))) | 
 | 49 | 		return 0; | 
 | 50 | 	c |= aligned_byte_mask(align); | 
 | 51 |  | 
 | 52 | 	for (;;) { | 
 | 53 | 		unsigned long data; | 
 | 54 | 		if (has_zero(c, &data, &constants)) { | 
 | 55 | 			data = prep_zero_mask(c, data, &constants); | 
 | 56 | 			data = create_zero_mask(data); | 
 | 57 | 			return res + find_zero(data) + 1 - align; | 
 | 58 | 		} | 
 | 59 | 		res += sizeof(unsigned long); | 
 | 60 | 		if (unlikely(max < sizeof(unsigned long))) | 
 | 61 | 			break; | 
 | 62 | 		max -= sizeof(unsigned long); | 
 | 63 | 		if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) | 
 | 64 | 			return 0; | 
 | 65 | 	} | 
 | 66 | 	res -= align; | 
 | 67 |  | 
 | 68 | 	/* | 
 | 69 | 	 * Uhhuh. We hit 'max'. But was that the user-specified maximum | 
 | 70 | 	 * too? If so, return the marker for "too long". | 
 | 71 | 	 */ | 
 | 72 | 	if (res >= count) | 
 | 73 | 		return count+1; | 
 | 74 |  | 
 | 75 | 	/* | 
 | 76 | 	 * Nope: we hit the address space limit, and we still had more | 
 | 77 | 	 * characters the caller would have wanted. That's 0. | 
 | 78 | 	 */ | 
 | 79 | 	return 0; | 
 | 80 | } | 
 | 81 |  | 
 | 82 | /** | 
 | 83 |  * strnlen_user: - Get the size of a user string INCLUDING final NUL. | 
 | 84 |  * @str: The string to measure. | 
 | 85 |  * @count: Maximum count (including NUL character) | 
 | 86 |  * | 
 | 87 |  * Context: User context only.  This function may sleep. | 
 | 88 |  * | 
 | 89 |  * Get the size of a NUL-terminated string in user space. | 
 | 90 |  * | 
 | 91 |  * Returns the size of the string INCLUDING the terminating NUL. | 
 | 92 |  * If the string is too long, returns 'count+1'. | 
 | 93 |  * On exception (or invalid count), returns 0. | 
 | 94 |  */ | 
 | 95 | long strnlen_user(const char __user *str, long count) | 
 | 96 | { | 
 | 97 | 	unsigned long max_addr, src_addr; | 
 | 98 |  | 
 | 99 | 	if (unlikely(count <= 0)) | 
 | 100 | 		return 0; | 
 | 101 |  | 
 | 102 | 	max_addr = user_addr_max(); | 
 | 103 | 	src_addr = (unsigned long)str; | 
 | 104 | 	if (likely(src_addr < max_addr)) { | 
 | 105 | 		unsigned long max = max_addr - src_addr; | 
 | 106 | 		return do_strnlen_user(str, count, max); | 
 | 107 | 	} | 
 | 108 | 	return 0; | 
 | 109 | } | 
 | 110 | EXPORT_SYMBOL(strnlen_user); | 
 | 111 |  | 
 | 112 | /** | 
 | 113 |  * strlen_user: - Get the size of a user string INCLUDING final NUL. | 
 | 114 |  * @str: The string to measure. | 
 | 115 |  * | 
 | 116 |  * Context: User context only.  This function may sleep. | 
 | 117 |  * | 
 | 118 |  * Get the size of a NUL-terminated string in user space. | 
 | 119 |  * | 
 | 120 |  * Returns the size of the string INCLUDING the terminating NUL. | 
 | 121 |  * On exception, returns 0. | 
 | 122 |  * | 
 | 123 |  * If there is a limit on the length of a valid string, you may wish to | 
 | 124 |  * consider using strnlen_user() instead. | 
 | 125 |  */ | 
 | 126 | long strlen_user(const char __user *str) | 
 | 127 | { | 
 | 128 | 	unsigned long max_addr, src_addr; | 
 | 129 |  | 
 | 130 | 	max_addr = user_addr_max(); | 
 | 131 | 	src_addr = (unsigned long)str; | 
 | 132 | 	if (likely(src_addr < max_addr)) { | 
 | 133 | 		unsigned long max = max_addr - src_addr; | 
 | 134 | 		return do_strnlen_user(str, ~0ul, max); | 
 | 135 | 	} | 
 | 136 | 	return 0; | 
 | 137 | } | 
 | 138 | EXPORT_SYMBOL(strlen_user); |