string: Add additional __realloc_size() annotations for "dup" helpers
Several other "dup"-style interfaces could use the __realloc_size() attribute. (As a reminder to myself and others: "realloc" is used here instead of "alloc" because the "alloc_size" attribute implies that the memory contents are uninitialized. Since we're copying contents into the resulting allocation, it must use "realloc_size" to avoid confusing the compiler's optimization passes.) Add KUnit test coverage where possible. (KUnit still does not have the ability to manipulate userspace memory.) Reviewed-by: Andy Shevchenko <andy@kernel.org> Link: https://lore.kernel.org/r/20240502145218.it.729-kees@kernel.org Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
74df22453c
commit
7d78a77733
@ -14,8 +14,8 @@
|
||||
#include <uapi/linux/string.h>
|
||||
|
||||
extern char *strndup_user(const char __user *, long);
|
||||
extern void *memdup_user(const void __user *, size_t);
|
||||
extern void *vmemdup_user(const void __user *, size_t);
|
||||
extern void *memdup_user(const void __user *, size_t) __realloc_size(2);
|
||||
extern void *vmemdup_user(const void __user *, size_t) __realloc_size(2);
|
||||
extern void *memdup_user_nul(const void __user *, size_t);
|
||||
|
||||
/**
|
||||
@ -27,7 +27,8 @@ extern void *memdup_user_nul(const void __user *, size_t);
|
||||
* Return: an ERR_PTR() on failure. Result is physically
|
||||
* contiguous, to be freed by kfree().
|
||||
*/
|
||||
static inline void *memdup_array_user(const void __user *src, size_t n, size_t size)
|
||||
static inline __realloc_size(2, 3)
|
||||
void *memdup_array_user(const void __user *src, size_t n, size_t size)
|
||||
{
|
||||
size_t nbytes;
|
||||
|
||||
@ -46,7 +47,8 @@ static inline void *memdup_array_user(const void __user *src, size_t n, size_t s
|
||||
* Return: an ERR_PTR() on failure. Result may be not
|
||||
* physically contiguous. Use kvfree() to free.
|
||||
*/
|
||||
static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size)
|
||||
static inline __realloc_size(2, 3)
|
||||
void *vmemdup_array_user(const void __user *src, size_t n, size_t size)
|
||||
{
|
||||
size_t nbytes;
|
||||
|
||||
@ -285,7 +287,8 @@ extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
|
||||
extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
|
||||
extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
|
||||
extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
|
||||
extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp);
|
||||
extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp)
|
||||
__realloc_size(2, 3);
|
||||
|
||||
/* lib/argv_split.c */
|
||||
extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
|
||||
|
@ -363,6 +363,31 @@ DEFINE_ALLOC_SIZE_TEST_PAIR(kvmalloc)
|
||||
} while (0)
|
||||
DEFINE_ALLOC_SIZE_TEST_PAIR(devm_kmalloc)
|
||||
|
||||
static const char * const test_strs[] = {
|
||||
"",
|
||||
"Hello there",
|
||||
"A longer string, just for variety",
|
||||
};
|
||||
|
||||
#define TEST_realloc(checker) do { \
|
||||
gfp_t gfp = GFP_KERNEL; \
|
||||
size_t len; \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < ARRAY_SIZE(test_strs); i++) { \
|
||||
len = strlen(test_strs[i]); \
|
||||
KUNIT_EXPECT_EQ(test, __builtin_constant_p(len), 0); \
|
||||
checker(len, kmemdup_array(test_strs[i], len, 1, gfp), \
|
||||
kfree(p)); \
|
||||
checker(len, kmemdup(test_strs[i], len, gfp), \
|
||||
kfree(p)); \
|
||||
} \
|
||||
} while (0)
|
||||
static void fortify_test_realloc_size(struct kunit *test)
|
||||
{
|
||||
TEST_realloc(check_dynamic);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't have an array at the end of a structure or else
|
||||
* builds without -fstrict-flex-arrays=3 will report them as
|
||||
@ -1046,6 +1071,7 @@ static struct kunit_case fortify_test_cases[] = {
|
||||
KUNIT_CASE(fortify_test_alloc_size_kvmalloc_dynamic),
|
||||
KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_const),
|
||||
KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_dynamic),
|
||||
KUNIT_CASE(fortify_test_realloc_size),
|
||||
KUNIT_CASE(fortify_test_strlen),
|
||||
KUNIT_CASE(fortify_test_strnlen),
|
||||
KUNIT_CASE(fortify_test_strcpy),
|
||||
|
Loading…
Reference in New Issue
Block a user