aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/sched/task.h14
-rw-r--r--include/linux/slab.h41
-rw-r--r--include/linux/slab_def.h3
-rw-r--r--include/linux/slub_def.h3
-rw-r--r--include/linux/stddef.h10
-rw-r--r--include/linux/uaccess.h8
6 files changed, 64 insertions, 15 deletions
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index 05b8650f06f5..5be31eb7b266 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -104,6 +104,20 @@ extern int arch_task_struct_size __read_mostly;
104# define arch_task_struct_size (sizeof(struct task_struct)) 104# define arch_task_struct_size (sizeof(struct task_struct))
105#endif 105#endif
106 106
107#ifndef CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST
108/*
109 * If an architecture has not declared a thread_struct whitelist we
110 * must assume something there may need to be copied to userspace.
111 */
112static inline void arch_thread_struct_whitelist(unsigned long *offset,
113 unsigned long *size)
114{
115 *offset = 0;
116 /* Handle dynamically sized thread_struct. */
117 *size = arch_task_struct_size - offsetof(struct task_struct, thread);
118}
119#endif
120
107#ifdef CONFIG_VMAP_STACK 121#ifdef CONFIG_VMAP_STACK
108static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t) 122static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
109{ 123{
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 50697a1d6621..231abc8976c5 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -135,9 +135,15 @@ struct mem_cgroup;
135void __init kmem_cache_init(void); 135void __init kmem_cache_init(void);
136bool slab_is_available(void); 136bool slab_is_available(void);
137 137
138struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, 138extern bool usercopy_fallback;
139 slab_flags_t, 139
140 void (*)(void *)); 140struct kmem_cache *kmem_cache_create(const char *name, size_t size,
141 size_t align, slab_flags_t flags,
142 void (*ctor)(void *));
143struct kmem_cache *kmem_cache_create_usercopy(const char *name,
144 size_t size, size_t align, slab_flags_t flags,
145 size_t useroffset, size_t usersize,
146 void (*ctor)(void *));
141void kmem_cache_destroy(struct kmem_cache *); 147void kmem_cache_destroy(struct kmem_cache *);
142int kmem_cache_shrink(struct kmem_cache *); 148int kmem_cache_shrink(struct kmem_cache *);
143 149
@@ -153,9 +159,20 @@ void memcg_destroy_kmem_caches(struct mem_cgroup *);
153 * f.e. add ____cacheline_aligned_in_smp to the struct declaration 159 * f.e. add ____cacheline_aligned_in_smp to the struct declaration
154 * then the objects will be properly aligned in SMP configurations. 160 * then the objects will be properly aligned in SMP configurations.
155 */ 161 */
156#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\ 162#define KMEM_CACHE(__struct, __flags) \
157 sizeof(struct __struct), __alignof__(struct __struct),\ 163 kmem_cache_create(#__struct, sizeof(struct __struct), \
158 (__flags), NULL) 164 __alignof__(struct __struct), (__flags), NULL)
165
166/*
167 * To whitelist a single field for copying to/from usercopy, use this
168 * macro instead for KMEM_CACHE() above.
169 */
170#define KMEM_CACHE_USERCOPY(__struct, __flags, __field) \
171 kmem_cache_create_usercopy(#__struct, \
172 sizeof(struct __struct), \
173 __alignof__(struct __struct), (__flags), \
174 offsetof(struct __struct, __field), \
175 sizeof_field(struct __struct, __field), NULL)
159 176
160/* 177/*
161 * Common kmalloc functions provided by all allocators 178 * Common kmalloc functions provided by all allocators
@@ -167,15 +184,11 @@ void kzfree(const void *);
167size_t ksize(const void *); 184size_t ksize(const void *);
168 185
169#ifdef CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR 186#ifdef CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR
170const char *__check_heap_object(const void *ptr, unsigned long n, 187void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
171 struct page *page); 188 bool to_user);
172#else 189#else
173static inline const char *__check_heap_object(const void *ptr, 190static inline void __check_heap_object(const void *ptr, unsigned long n,
174 unsigned long n, 191 struct page *page, bool to_user) { }
175 struct page *page)
176{
177 return NULL;
178}
179#endif 192#endif
180 193
181/* 194/*
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 072e46e9e1d5..7385547c04b1 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -85,6 +85,9 @@ struct kmem_cache {
85 unsigned int *random_seq; 85 unsigned int *random_seq;
86#endif 86#endif
87 87
88 size_t useroffset; /* Usercopy region offset */
89 size_t usersize; /* Usercopy region size */
90
88 struct kmem_cache_node *node[MAX_NUMNODES]; 91 struct kmem_cache_node *node[MAX_NUMNODES];
89}; 92};
90 93
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 0adae162dc8f..8ad99c47b19c 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -135,6 +135,9 @@ struct kmem_cache {
135 struct kasan_cache kasan_info; 135 struct kasan_cache kasan_info;
136#endif 136#endif
137 137
138 size_t useroffset; /* Usercopy region offset */
139 size_t usersize; /* Usercopy region size */
140
138 struct kmem_cache_node *node[MAX_NUMNODES]; 141 struct kmem_cache_node *node[MAX_NUMNODES];
139}; 142};
140 143
diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index 2181719fd907..998a4ba28eba 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -20,12 +20,20 @@ enum {
20#endif 20#endif
21 21
22/** 22/**
23 * sizeof_field(TYPE, MEMBER)
24 *
25 * @TYPE: The structure containing the field of interest
26 * @MEMBER: The field to return the size of
27 */
28#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
29
30/**
23 * offsetofend(TYPE, MEMBER) 31 * offsetofend(TYPE, MEMBER)
24 * 32 *
25 * @TYPE: The type of the structure 33 * @TYPE: The type of the structure
26 * @MEMBER: The member within the structure to get the end offset of 34 * @MEMBER: The member within the structure to get the end offset of
27 */ 35 */
28#define offsetofend(TYPE, MEMBER) \ 36#define offsetofend(TYPE, MEMBER) \
29 (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER)) 37 (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
30 38
31#endif 39#endif
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 251e655d407f..efe79c1cdd47 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -273,4 +273,12 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
273#define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0) 273#define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0)
274#endif 274#endif
275 275
276#ifdef CONFIG_HARDENED_USERCOPY
277void usercopy_warn(const char *name, const char *detail, bool to_user,
278 unsigned long offset, unsigned long len);
279void __noreturn usercopy_abort(const char *name, const char *detail,
280 bool to_user, unsigned long offset,
281 unsigned long len);
282#endif
283
276#endif /* __LINUX_UACCESS_H__ */ 284#endif /* __LINUX_UACCESS_H__ */