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