aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-11-23 04:04:28 -0500
committerIngo Molnar <mingo@kernel.org>2016-11-23 04:04:28 -0500
commitaf91a81131aee3e233a977632a23b839857a327b (patch)
tree9b46f8a8ad9e5df08dab110d5e8aac1544ef36fa /drivers/misc
parent23400ac997062647f2b63c82030d189671b1effe (diff)
parent6190aaafd06cd3db77f1d7343bd097f6bd526727 (diff)
Merge branch 'for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu
Pull RCU updates from Paul E. McKenney: - Documentation updates, yet again just simple changes. - Miscellaneous fixes, including a change to call_rcu()'s rcu_head alignment check. - Security-motivated list consistency checks, which are disabled by default behind DEBUG_LIST. - Torture-test updates. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/lkdtm.h2
-rw-r--r--drivers/misc/lkdtm_bugs.c68
-rw-r--r--drivers/misc/lkdtm_core.c2
3 files changed, 72 insertions, 0 deletions
diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h
index fdf954c2107f..cfa1039c62e7 100644
--- a/drivers/misc/lkdtm.h
+++ b/drivers/misc/lkdtm.h
@@ -21,6 +21,8 @@ void lkdtm_SPINLOCKUP(void);
21void lkdtm_HUNG_TASK(void); 21void lkdtm_HUNG_TASK(void);
22void lkdtm_ATOMIC_UNDERFLOW(void); 22void lkdtm_ATOMIC_UNDERFLOW(void);
23void lkdtm_ATOMIC_OVERFLOW(void); 23void lkdtm_ATOMIC_OVERFLOW(void);
24void lkdtm_CORRUPT_LIST_ADD(void);
25void lkdtm_CORRUPT_LIST_DEL(void);
24 26
25/* lkdtm_heap.c */ 27/* lkdtm_heap.c */
26void lkdtm_OVERWRITE_ALLOCATION(void); 28void lkdtm_OVERWRITE_ALLOCATION(void);
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c
index 182ae1894b32..f336206d4b1f 100644
--- a/drivers/misc/lkdtm_bugs.c
+++ b/drivers/misc/lkdtm_bugs.c
@@ -5,8 +5,13 @@
5 * test source files. 5 * test source files.
6 */ 6 */
7#include "lkdtm.h" 7#include "lkdtm.h"
8#include <linux/list.h>
8#include <linux/sched.h> 9#include <linux/sched.h>
9 10
11struct lkdtm_list {
12 struct list_head node;
13};
14
10/* 15/*
11 * Make sure our attempts to over run the kernel stack doesn't trigger 16 * Make sure our attempts to over run the kernel stack doesn't trigger
12 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we 17 * a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
@@ -146,3 +151,66 @@ void lkdtm_ATOMIC_OVERFLOW(void)
146 pr_info("attempting bad atomic overflow\n"); 151 pr_info("attempting bad atomic overflow\n");
147 atomic_inc(&over); 152 atomic_inc(&over);
148} 153}
154
155void lkdtm_CORRUPT_LIST_ADD(void)
156{
157 /*
158 * Initially, an empty list via LIST_HEAD:
159 * test_head.next = &test_head
160 * test_head.prev = &test_head
161 */
162 LIST_HEAD(test_head);
163 struct lkdtm_list good, bad;
164 void *target[2] = { };
165 void *redirection = &target;
166
167 pr_info("attempting good list addition\n");
168
169 /*
170 * Adding to the list performs these actions:
171 * test_head.next->prev = &good.node
172 * good.node.next = test_head.next
173 * good.node.prev = test_head
174 * test_head.next = good.node
175 */
176 list_add(&good.node, &test_head);
177
178 pr_info("attempting corrupted list addition\n");
179 /*
180 * In simulating this "write what where" primitive, the "what" is
181 * the address of &bad.node, and the "where" is the address held
182 * by "redirection".
183 */
184 test_head.next = redirection;
185 list_add(&bad.node, &test_head);
186
187 if (target[0] == NULL && target[1] == NULL)
188 pr_err("Overwrite did not happen, but no BUG?!\n");
189 else
190 pr_err("list_add() corruption not detected!\n");
191}
192
193void lkdtm_CORRUPT_LIST_DEL(void)
194{
195 LIST_HEAD(test_head);
196 struct lkdtm_list item;
197 void *target[2] = { };
198 void *redirection = &target;
199
200 list_add(&item.node, &test_head);
201
202 pr_info("attempting good list removal\n");
203 list_del(&item.node);
204
205 pr_info("attempting corrupted list removal\n");
206 list_add(&item.node, &test_head);
207
208 /* As with the list_add() test above, this corrupts "next". */
209 item.node.next = redirection;
210 list_del(&item.node);
211
212 if (target[0] == NULL && target[1] == NULL)
213 pr_err("Overwrite did not happen, but no BUG?!\n");
214 else
215 pr_err("list_del() corruption not detected!\n");
216}
diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c
index f9154b8d67f6..7eeb71a75549 100644
--- a/drivers/misc/lkdtm_core.c
+++ b/drivers/misc/lkdtm_core.c
@@ -197,6 +197,8 @@ struct crashtype crashtypes[] = {
197 CRASHTYPE(EXCEPTION), 197 CRASHTYPE(EXCEPTION),
198 CRASHTYPE(LOOP), 198 CRASHTYPE(LOOP),
199 CRASHTYPE(OVERFLOW), 199 CRASHTYPE(OVERFLOW),
200 CRASHTYPE(CORRUPT_LIST_ADD),
201 CRASHTYPE(CORRUPT_LIST_DEL),
200 CRASHTYPE(CORRUPT_STACK), 202 CRASHTYPE(CORRUPT_STACK),
201 CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), 203 CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
202 CRASHTYPE(OVERWRITE_ALLOCATION), 204 CRASHTYPE(OVERWRITE_ALLOCATION),