^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/word-at-a-time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Do a strnlen, return length of string *with* final '\0'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * 'count' is the user-supplied count, while 'max' is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * address space maximum.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Return 0 for exceptions (which includes hitting the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * space maximum), or 'count+1' if hitting the user-supplied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * maximum count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * NOTE! We can sometimes overshoot the user-supplied maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * if it fits in a aligned 'long'. The caller needs to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * the return value against "> max".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) unsigned long align, res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unsigned long c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Do everything aligned. But that means that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * need to also expand the maximum..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) align = (sizeof(unsigned long) - 1) & (unsigned long)src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) src -= align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) max += align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsafe_get_user(c, (unsigned long __user *)src, efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) c |= aligned_byte_mask(align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned long data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (has_zero(c, &data, &constants)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) data = prep_zero_mask(c, data, &constants);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) data = create_zero_mask(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return res + find_zero(data) + 1 - align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) res += sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* We already handled 'unsigned long' bytes. Did we do it all ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (unlikely(max <= sizeof(unsigned long)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) max -= sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsafe_get_user(c, (unsigned long __user *)(src+res), efault);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) res -= align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Uhhuh. We hit 'max'. But was that the user-specified maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * too? If so, return the marker for "too long".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (res >= count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return count+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * Nope: we hit the address space limit, and we still had more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * characters the caller would have wanted. That's 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) efault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * strnlen_user: - Get the size of a user string INCLUDING final NUL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @str: The string to measure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @count: Maximum count (including NUL character)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Context: User context only. This function may sleep if pagefaults are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Get the size of a NUL-terminated string in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Returns the size of the string INCLUDING the terminating NUL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * If the string is too long, returns a number larger than @count. User
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * has to check the return value against "> count".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * On exception (or invalid count), returns 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * NOTE! You should basically never use this function. There is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * almost never any valid case for using the length of a user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * string, since the string can be changed at any time by other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * threads. Use "strncpy_from_user()" instead to get a stable copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * of the string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) long strnlen_user(const char __user *str, long count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned long max_addr, src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (unlikely(count <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) max_addr = user_addr_max();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) src_addr = (unsigned long)untagged_addr(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (likely(src_addr < max_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long max = max_addr - src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) long retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Truncate 'max' to the user-specified limit, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * we only have one limit we need to check in the loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (max > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) max = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (user_read_access_begin(str, max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) retval = do_strnlen_user(str, count, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) user_read_access_end();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) EXPORT_SYMBOL(strnlen_user);