162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/compiler.h>
362306a36Sopenharmony_ci#include <linux/export.h>
462306a36Sopenharmony_ci#include <linux/fault-inject-usercopy.h>
562306a36Sopenharmony_ci#include <linux/kasan-checks.h>
662306a36Sopenharmony_ci#include <linux/thread_info.h>
762306a36Sopenharmony_ci#include <linux/uaccess.h>
862306a36Sopenharmony_ci#include <linux/kernel.h>
962306a36Sopenharmony_ci#include <linux/errno.h>
1062306a36Sopenharmony_ci#include <linux/mm.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <asm/byteorder.h>
1362306a36Sopenharmony_ci#include <asm/word-at-a-time.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
1662306a36Sopenharmony_ci#define IS_UNALIGNED(src, dst)	0
1762306a36Sopenharmony_ci#else
1862306a36Sopenharmony_ci#define IS_UNALIGNED(src, dst)	\
1962306a36Sopenharmony_ci	(((long) dst | (long) src) & (sizeof(long) - 1))
2062306a36Sopenharmony_ci#endif
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * Do a strncpy, return length of string without final '\0'.
2462306a36Sopenharmony_ci * 'count' is the user-supplied count (return 'count' if we
2562306a36Sopenharmony_ci * hit it), 'max' is the address space maximum (and we return
2662306a36Sopenharmony_ci * -EFAULT if we hit it).
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_cistatic __always_inline long do_strncpy_from_user(char *dst, const char __user *src,
2962306a36Sopenharmony_ci					unsigned long count, unsigned long max)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
3262306a36Sopenharmony_ci	unsigned long res = 0;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	if (IS_UNALIGNED(src, dst))
3562306a36Sopenharmony_ci		goto byte_at_a_time;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	while (max >= sizeof(unsigned long)) {
3862306a36Sopenharmony_ci		unsigned long c, data, mask;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci		/* Fall back to byte-at-a-time if we get a page fault */
4162306a36Sopenharmony_ci		unsafe_get_user(c, (unsigned long __user *)(src+res), byte_at_a_time);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci		/*
4462306a36Sopenharmony_ci		 * Note that we mask out the bytes following the NUL. This is
4562306a36Sopenharmony_ci		 * important to do because string oblivious code may read past
4662306a36Sopenharmony_ci		 * the NUL. For those routines, we don't want to give them
4762306a36Sopenharmony_ci		 * potentially random bytes after the NUL in `src`.
4862306a36Sopenharmony_ci		 *
4962306a36Sopenharmony_ci		 * One example of such code is BPF map keys. BPF treats map keys
5062306a36Sopenharmony_ci		 * as an opaque set of bytes. Without the post-NUL mask, any BPF
5162306a36Sopenharmony_ci		 * maps keyed by strings returned from strncpy_from_user() may
5262306a36Sopenharmony_ci		 * have multiple entries for semantically identical strings.
5362306a36Sopenharmony_ci		 */
5462306a36Sopenharmony_ci		if (has_zero(c, &data, &constants)) {
5562306a36Sopenharmony_ci			data = prep_zero_mask(c, data, &constants);
5662306a36Sopenharmony_ci			data = create_zero_mask(data);
5762306a36Sopenharmony_ci			mask = zero_bytemask(data);
5862306a36Sopenharmony_ci			*(unsigned long *)(dst+res) = c & mask;
5962306a36Sopenharmony_ci			return res + find_zero(data);
6062306a36Sopenharmony_ci		}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci		*(unsigned long *)(dst+res) = c;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci		res += sizeof(unsigned long);
6562306a36Sopenharmony_ci		max -= sizeof(unsigned long);
6662306a36Sopenharmony_ci	}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cibyte_at_a_time:
6962306a36Sopenharmony_ci	while (max) {
7062306a36Sopenharmony_ci		char c;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci		unsafe_get_user(c,src+res, efault);
7362306a36Sopenharmony_ci		dst[res] = c;
7462306a36Sopenharmony_ci		if (!c)
7562306a36Sopenharmony_ci			return res;
7662306a36Sopenharmony_ci		res++;
7762306a36Sopenharmony_ci		max--;
7862306a36Sopenharmony_ci	}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	/*
8162306a36Sopenharmony_ci	 * Uhhuh. We hit 'max'. But was that the user-specified maximum
8262306a36Sopenharmony_ci	 * too? If so, that's ok - we got as much as the user asked for.
8362306a36Sopenharmony_ci	 */
8462306a36Sopenharmony_ci	if (res >= count)
8562306a36Sopenharmony_ci		return res;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/*
8862306a36Sopenharmony_ci	 * Nope: we hit the address space limit, and we still had more
8962306a36Sopenharmony_ci	 * characters the caller would have wanted. That's an EFAULT.
9062306a36Sopenharmony_ci	 */
9162306a36Sopenharmony_ciefault:
9262306a36Sopenharmony_ci	return -EFAULT;
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/**
9662306a36Sopenharmony_ci * strncpy_from_user: - Copy a NUL terminated string from userspace.
9762306a36Sopenharmony_ci * @dst:   Destination address, in kernel space.  This buffer must be at
9862306a36Sopenharmony_ci *         least @count bytes long.
9962306a36Sopenharmony_ci * @src:   Source address, in user space.
10062306a36Sopenharmony_ci * @count: Maximum number of bytes to copy, including the trailing NUL.
10162306a36Sopenharmony_ci *
10262306a36Sopenharmony_ci * Copies a NUL-terminated string from userspace to kernel space.
10362306a36Sopenharmony_ci *
10462306a36Sopenharmony_ci * On success, returns the length of the string (not including the trailing
10562306a36Sopenharmony_ci * NUL).
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * If access to userspace fails, returns -EFAULT (some data may have been
10862306a36Sopenharmony_ci * copied).
10962306a36Sopenharmony_ci *
11062306a36Sopenharmony_ci * If @count is smaller than the length of the string, copies @count bytes
11162306a36Sopenharmony_ci * and returns @count.
11262306a36Sopenharmony_ci */
11362306a36Sopenharmony_cilong strncpy_from_user(char *dst, const char __user *src, long count)
11462306a36Sopenharmony_ci{
11562306a36Sopenharmony_ci	unsigned long max_addr, src_addr;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	might_fault();
11862306a36Sopenharmony_ci	if (should_fail_usercopy())
11962306a36Sopenharmony_ci		return -EFAULT;
12062306a36Sopenharmony_ci	if (unlikely(count <= 0))
12162306a36Sopenharmony_ci		return 0;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	max_addr = TASK_SIZE_MAX;
12462306a36Sopenharmony_ci	src_addr = (unsigned long)untagged_addr(src);
12562306a36Sopenharmony_ci	if (likely(src_addr < max_addr)) {
12662306a36Sopenharmony_ci		unsigned long max = max_addr - src_addr;
12762306a36Sopenharmony_ci		long retval;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci		/*
13062306a36Sopenharmony_ci		 * Truncate 'max' to the user-specified limit, so that
13162306a36Sopenharmony_ci		 * we only have one limit we need to check in the loop
13262306a36Sopenharmony_ci		 */
13362306a36Sopenharmony_ci		if (max > count)
13462306a36Sopenharmony_ci			max = count;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci		kasan_check_write(dst, count);
13762306a36Sopenharmony_ci		check_object_size(dst, count, false);
13862306a36Sopenharmony_ci		if (user_read_access_begin(src, max)) {
13962306a36Sopenharmony_ci			retval = do_strncpy_from_user(dst, src, count, max);
14062306a36Sopenharmony_ci			user_read_access_end();
14162306a36Sopenharmony_ci			return retval;
14262306a36Sopenharmony_ci		}
14362306a36Sopenharmony_ci	}
14462306a36Sopenharmony_ci	return -EFAULT;
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ciEXPORT_SYMBOL(strncpy_from_user);
147