diff options
author | Kees Cook <keescook@chromium.org> | 2017-02-03 18:26:50 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-02-10 03:04:20 -0500 |
commit | ff86b30010eee8249dc244ce1868b886bbee6449 (patch) | |
tree | dcfe7ed064e89cdc61c5e61391c4639cdd3bf964 | |
parent | 10383aea2f445bce9b2a2b308def08134b438c8e (diff) |
lkdtm: Convert to refcount_t testing
Since we'll be using refcount_t instead of atomic_t for refcounting,
change the LKDTM tests to reflect the new interface and test conditions.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Hans Liljestrand <ishkamiel@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: arnd@arndb.de
Cc: dhowells@redhat.com
Cc: dwindsor@gmail.com
Cc: elena.reshetova@intel.com
Cc: gregkh@linuxfoundation.org
Cc: h.peter.anvin@intel.com
Cc: kernel-hardening@lists.openwall.com
Cc: will.deacon@arm.com
Link: http://lkml.kernel.org/r/1486164412-7338-3-git-send-email-keescook@chromium.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | drivers/misc/lkdtm.h | 8 | ||||
-rw-r--r-- | drivers/misc/lkdtm_bugs.c | 87 | ||||
-rw-r--r-- | drivers/misc/lkdtm_core.c | 8 |
3 files changed, 85 insertions, 18 deletions
diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index cfa1039c62e7..67d27be60405 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h | |||
@@ -19,8 +19,12 @@ void lkdtm_SOFTLOCKUP(void); | |||
19 | void lkdtm_HARDLOCKUP(void); | 19 | void lkdtm_HARDLOCKUP(void); |
20 | void lkdtm_SPINLOCKUP(void); | 20 | void lkdtm_SPINLOCKUP(void); |
21 | void lkdtm_HUNG_TASK(void); | 21 | void lkdtm_HUNG_TASK(void); |
22 | void lkdtm_ATOMIC_UNDERFLOW(void); | 22 | void lkdtm_REFCOUNT_SATURATE_INC(void); |
23 | void lkdtm_ATOMIC_OVERFLOW(void); | 23 | void lkdtm_REFCOUNT_SATURATE_ADD(void); |
24 | void lkdtm_REFCOUNT_ZERO_DEC(void); | ||
25 | void lkdtm_REFCOUNT_ZERO_INC(void); | ||
26 | void lkdtm_REFCOUNT_ZERO_SUB(void); | ||
27 | void lkdtm_REFCOUNT_ZERO_ADD(void); | ||
24 | void lkdtm_CORRUPT_LIST_ADD(void); | 28 | void lkdtm_CORRUPT_LIST_ADD(void); |
25 | void lkdtm_CORRUPT_LIST_DEL(void); | 29 | void lkdtm_CORRUPT_LIST_DEL(void); |
26 | 30 | ||
diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index 91edd0b55e5c..cba0837aee2e 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include "lkdtm.h" | 7 | #include "lkdtm.h" |
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/refcount.h> | ||
9 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
10 | 11 | ||
11 | struct lkdtm_list { | 12 | struct lkdtm_list { |
@@ -129,28 +130,86 @@ void lkdtm_HUNG_TASK(void) | |||
129 | schedule(); | 130 | schedule(); |
130 | } | 131 | } |
131 | 132 | ||
132 | void lkdtm_ATOMIC_UNDERFLOW(void) | 133 | void lkdtm_REFCOUNT_SATURATE_INC(void) |
133 | { | 134 | { |
134 | atomic_t under = ATOMIC_INIT(INT_MIN); | 135 | refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); |
135 | 136 | ||
136 | pr_info("attempting good atomic increment\n"); | 137 | pr_info("attempting good refcount decrement\n"); |
137 | atomic_inc(&under); | 138 | refcount_dec(&over); |
138 | atomic_dec(&under); | 139 | refcount_inc(&over); |
139 | 140 | ||
140 | pr_info("attempting bad atomic underflow\n"); | 141 | pr_info("attempting bad refcount inc overflow\n"); |
141 | atomic_dec(&under); | 142 | refcount_inc(&over); |
143 | refcount_inc(&over); | ||
144 | if (refcount_read(&over) == UINT_MAX) | ||
145 | pr_err("Correctly stayed saturated, but no BUG?!\n"); | ||
146 | else | ||
147 | pr_err("Fail: refcount wrapped\n"); | ||
148 | } | ||
149 | |||
150 | void lkdtm_REFCOUNT_SATURATE_ADD(void) | ||
151 | { | ||
152 | refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); | ||
153 | |||
154 | pr_info("attempting good refcount decrement\n"); | ||
155 | refcount_dec(&over); | ||
156 | refcount_inc(&over); | ||
157 | |||
158 | pr_info("attempting bad refcount add overflow\n"); | ||
159 | refcount_add(2, &over); | ||
160 | if (refcount_read(&over) == UINT_MAX) | ||
161 | pr_err("Correctly stayed saturated, but no BUG?!\n"); | ||
162 | else | ||
163 | pr_err("Fail: refcount wrapped\n"); | ||
164 | } | ||
165 | |||
166 | void lkdtm_REFCOUNT_ZERO_DEC(void) | ||
167 | { | ||
168 | refcount_t zero = REFCOUNT_INIT(1); | ||
169 | |||
170 | pr_info("attempting bad refcount decrement to zero\n"); | ||
171 | refcount_dec(&zero); | ||
172 | if (refcount_read(&zero) == 0) | ||
173 | pr_err("Stayed at zero, but no BUG?!\n"); | ||
174 | else | ||
175 | pr_err("Fail: refcount went crazy\n"); | ||
142 | } | 176 | } |
143 | 177 | ||
144 | void lkdtm_ATOMIC_OVERFLOW(void) | 178 | void lkdtm_REFCOUNT_ZERO_SUB(void) |
145 | { | 179 | { |
146 | atomic_t over = ATOMIC_INIT(INT_MAX); | 180 | refcount_t zero = REFCOUNT_INIT(1); |
181 | |||
182 | pr_info("attempting bad refcount subtract past zero\n"); | ||
183 | if (!refcount_sub_and_test(2, &zero)) | ||
184 | pr_info("wrap attempt was noticed\n"); | ||
185 | if (refcount_read(&zero) == 1) | ||
186 | pr_err("Correctly stayed above 0, but no BUG?!\n"); | ||
187 | else | ||
188 | pr_err("Fail: refcount wrapped\n"); | ||
189 | } | ||
147 | 190 | ||
148 | pr_info("attempting good atomic decrement\n"); | 191 | void lkdtm_REFCOUNT_ZERO_INC(void) |
149 | atomic_dec(&over); | 192 | { |
150 | atomic_inc(&over); | 193 | refcount_t zero = REFCOUNT_INIT(0); |
151 | 194 | ||
152 | pr_info("attempting bad atomic overflow\n"); | 195 | pr_info("attempting bad refcount increment from zero\n"); |
153 | atomic_inc(&over); | 196 | refcount_inc(&zero); |
197 | if (refcount_read(&zero) == 0) | ||
198 | pr_err("Stayed at zero, but no BUG?!\n"); | ||
199 | else | ||
200 | pr_err("Fail: refcount went past zero\n"); | ||
201 | } | ||
202 | |||
203 | void lkdtm_REFCOUNT_ZERO_ADD(void) | ||
204 | { | ||
205 | refcount_t zero = REFCOUNT_INIT(0); | ||
206 | |||
207 | pr_info("attempting bad refcount addition from zero\n"); | ||
208 | refcount_add(2, &zero); | ||
209 | if (refcount_read(&zero) == 0) | ||
210 | pr_err("Stayed at zero, but no BUG?!\n"); | ||
211 | else | ||
212 | pr_err("Fail: refcount went past zero\n"); | ||
154 | } | 213 | } |
155 | 214 | ||
156 | void lkdtm_CORRUPT_LIST_ADD(void) | 215 | void lkdtm_CORRUPT_LIST_ADD(void) |
diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 7eeb71a75549..16e4cf110930 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c | |||
@@ -220,8 +220,12 @@ struct crashtype crashtypes[] = { | |||
220 | CRASHTYPE(WRITE_RO), | 220 | CRASHTYPE(WRITE_RO), |
221 | CRASHTYPE(WRITE_RO_AFTER_INIT), | 221 | CRASHTYPE(WRITE_RO_AFTER_INIT), |
222 | CRASHTYPE(WRITE_KERN), | 222 | CRASHTYPE(WRITE_KERN), |
223 | CRASHTYPE(ATOMIC_UNDERFLOW), | 223 | CRASHTYPE(REFCOUNT_SATURATE_INC), |
224 | CRASHTYPE(ATOMIC_OVERFLOW), | 224 | CRASHTYPE(REFCOUNT_SATURATE_ADD), |
225 | CRASHTYPE(REFCOUNT_ZERO_DEC), | ||
226 | CRASHTYPE(REFCOUNT_ZERO_INC), | ||
227 | CRASHTYPE(REFCOUNT_ZERO_SUB), | ||
228 | CRASHTYPE(REFCOUNT_ZERO_ADD), | ||
225 | CRASHTYPE(USERCOPY_HEAP_SIZE_TO), | 229 | CRASHTYPE(USERCOPY_HEAP_SIZE_TO), |
226 | CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), | 230 | CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), |
227 | CRASHTYPE(USERCOPY_HEAP_FLAG_TO), | 231 | CRASHTYPE(USERCOPY_HEAP_FLAG_TO), |