b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
bf3c2d6d2f964 (Rasmus Villemoes 2015-02-12 15:03:16 -0800 2) #include <linux/compiler.h>
bf3c2d6d2f964 (Rasmus Villemoes 2015-02-12 15:03:16 -0800 3) #include <linux/export.h>
4d0e9df5e43db (Albert van der Linde 2020-10-15 20:13:50 -0700 4) #include <linux/fault-inject-usercopy.h>
1771c6e1a567e (Andrey Ryabinin 2016-05-20 16:59:31 -0700 5) #include <linux/kasan-checks.h>
bf90e56e467ed (Mark Rutland 2016-10-11 13:51:27 -0700 6) #include <linux/thread_info.h>
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 7) #include <linux/uaccess.h>
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 8) #include <linux/kernel.h>
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 9) #include <linux/errno.h>
903f433f8f7a3 (Andrey Konovalov 2019-09-25 16:48:27 -0700 10) #include <linux/mm.h>
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 11)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 12) #include <asm/byteorder.h>
36126f8f2ed81 (Linus Torvalds 2012-05-26 10:43:17 -0700 13) #include <asm/word-at-a-time.h>
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 14)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 15) #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 16) #define IS_UNALIGNED(src, dst) 0
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 17) #else
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 18) #define IS_UNALIGNED(src, dst) \
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 19) (((long) dst | (long) src) & (sizeof(long) - 1))
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 20) #endif
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 21)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 22) /*
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 23) * Do a strncpy, return length of string without final '\0'.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 24) * 'count' is the user-supplied count (return 'count' if we
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 25) * hit it), 'max' is the address space maximum (and we return
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 26) * -EFAULT if we hit it).
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 27) */
29da93fea3ea3 (Peter Zijlstra 2019-04-24 09:19:25 +0200 28) static inline long do_strncpy_from_user(char *dst, const char __user *src,
29da93fea3ea3 (Peter Zijlstra 2019-04-24 09:19:25 +0200 29) unsigned long count, unsigned long max)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 30) {
36126f8f2ed81 (Linus Torvalds 2012-05-26 10:43:17 -0700 31) const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
29da93fea3ea3 (Peter Zijlstra 2019-04-24 09:19:25 +0200 32) unsigned long res = 0;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 33)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 34) if (IS_UNALIGNED(src, dst))
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 35) goto byte_at_a_time;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 36)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 37) while (max >= sizeof(unsigned long)) {
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 38) unsigned long c, data, mask;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 39)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 40) /* Fall back to byte-at-a-time if we get a page fault */
1bd4403d86a1c (Linus Torvalds 2016-08-08 13:02:01 -0700 41) unsafe_get_user(c, (unsigned long __user *)(src+res), byte_at_a_time);
1bd4403d86a1c (Linus Torvalds 2016-08-08 13:02:01 -0700 42)
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 43) /*
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 44) * Note that we mask out the bytes following the NUL. This is
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 45) * important to do because string oblivious code may read past
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 46) * the NUL. For those routines, we don't want to give them
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 47) * potentially random bytes after the NUL in `src`.
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 48) *
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 49) * One example of such code is BPF map keys. BPF treats map keys
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 50) * as an opaque set of bytes. Without the post-NUL mask, any BPF
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 51) * maps keyed by strings returned from strncpy_from_user() may
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 52) * have multiple entries for semantically identical strings.
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 53) */
36126f8f2ed81 (Linus Torvalds 2012-05-26 10:43:17 -0700 54) if (has_zero(c, &data, &constants)) {
36126f8f2ed81 (Linus Torvalds 2012-05-26 10:43:17 -0700 55) data = prep_zero_mask(c, data, &constants);
36126f8f2ed81 (Linus Torvalds 2012-05-26 10:43:17 -0700 56) data = create_zero_mask(data);
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 57) mask = zero_bytemask(data);
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 58) *(unsigned long *)(dst+res) = c & mask;
36126f8f2ed81 (Linus Torvalds 2012-05-26 10:43:17 -0700 59) return res + find_zero(data);
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 60) }
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 61)
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 62) *(unsigned long *)(dst+res) = c;
6fa6d28051e9f (Daniel Xu 2020-11-17 12:05:45 -0800 63)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 64) res += sizeof(unsigned long);
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 65) max -= sizeof(unsigned long);
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 66) }
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 67)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 68) byte_at_a_time:
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 69) while (max) {
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 70) char c;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 71)
1bd4403d86a1c (Linus Torvalds 2016-08-08 13:02:01 -0700 72) unsafe_get_user(c,src+res, efault);
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 73) dst[res] = c;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 74) if (!c)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 75) return res;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 76) res++;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 77) max--;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 78) }
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 79)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 80) /*
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 81) * Uhhuh. We hit 'max'. But was that the user-specified maximum
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 82) * too? If so, that's ok - we got as much as the user asked for.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 83) */
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 84) if (res >= count)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 85) return res;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 86)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 87) /*
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 88) * Nope: we hit the address space limit, and we still had more
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 89) * characters the caller would have wanted. That's an EFAULT.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 90) */
1bd4403d86a1c (Linus Torvalds 2016-08-08 13:02:01 -0700 91) efault:
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 92) return -EFAULT;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 93) }
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 94)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 95) /**
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 96) * strncpy_from_user: - Copy a NUL terminated string from userspace.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 97) * @dst: Destination address, in kernel space. This buffer must be at
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 98) * least @count bytes long.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 99) * @src: Source address, in user space.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 100) * @count: Maximum number of bytes to copy, including the trailing NUL.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 101) *
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 102) * Copies a NUL-terminated string from userspace to kernel space.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 103) *
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 104) * On success, returns the length of the string (not including the trailing
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 105) * NUL).
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 106) *
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 107) * If access to userspace fails, returns -EFAULT (some data may have been
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 108) * copied).
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 109) *
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 110) * If @count is smaller than the length of the string, copies @count bytes
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 111) * and returns @count.
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 112) */
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 113) long strncpy_from_user(char *dst, const char __user *src, long count)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 114) {
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 115) unsigned long max_addr, src_addr;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 116)
07887358993d4 (KP Singh 2020-06-04 16:50:11 -0700 117) might_fault();
4d0e9df5e43db (Albert van der Linde 2020-10-15 20:13:50 -0700 118) if (should_fail_usercopy())
4d0e9df5e43db (Albert van der Linde 2020-10-15 20:13:50 -0700 119) return -EFAULT;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 120) if (unlikely(count <= 0))
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 121) return 0;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 122)
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 123) max_addr = user_addr_max();
903f433f8f7a3 (Andrey Konovalov 2019-09-25 16:48:27 -0700 124) src_addr = (unsigned long)untagged_addr(src);
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 125) if (likely(src_addr < max_addr)) {
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 126) unsigned long max = max_addr - src_addr;
9fd4470ff4974 (Linus Torvalds 2015-12-17 10:05:19 -0800 127) long retval;
9fd4470ff4974 (Linus Torvalds 2015-12-17 10:05:19 -0800 128)
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 129) /*
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 130) * Truncate 'max' to the user-specified limit, so that
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 131) * we only have one limit we need to check in the loop
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 132) */
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 133) if (max > count)
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 134) max = count;
ab10ae1c3bef5 (Christophe Leroy 2020-01-23 08:34:18 +0000 135)
1771c6e1a567e (Andrey Ryabinin 2016-05-20 16:59:31 -0700 136) kasan_check_write(dst, count);
bf90e56e467ed (Mark Rutland 2016-10-11 13:51:27 -0700 137) check_object_size(dst, count, false);
41cd780524674 (Christophe Leroy 2020-04-03 07:20:51 +0000 138) if (user_read_access_begin(src, max)) {
594cc251fdd0d (Linus Torvalds 2019-01-04 12:56:09 -0800 139) retval = do_strncpy_from_user(dst, src, count, max);
41cd780524674 (Christophe Leroy 2020-04-03 07:20:51 +0000 140) user_read_access_end();
594cc251fdd0d (Linus Torvalds 2019-01-04 12:56:09 -0800 141) return retval;
594cc251fdd0d (Linus Torvalds 2019-01-04 12:56:09 -0800 142) }
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 143) }
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 144) return -EFAULT;
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 145) }
2922585b93294 (David S. Miller 2012-05-24 13:12:28 -0700 146) EXPORT_SYMBOL(strncpy_from_user);