aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2015-11-05 21:50:51 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 22:34:48 -0500
commitfc5aeeaf593278f07ffa4d97296e27423ecae867 (patch)
tree17b6521e9f9ba2d43d6d0b4d416d5a599e561980 /mm
parentf2377d4eaab2aabe1938b3974b5b94f5ba4c7ead (diff)
mm/kasan: prevent deadlock in kasan reporting
When we end up calling kasan_report in real mode, our shadow mapping for the spinlock variable will show poisoned. This will result in us calling kasan_report_error with lock_report spin lock held. To prevent this disable kasan reporting when we are priting error w.r.t kasan. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Reviewed-by: Andrey Ryabinin <ryabinin.a.a@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/kasan/report.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index c5367089703c..7833f074ede8 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -173,12 +173,10 @@ static void print_shadow_for_address(const void *addr)
173 * function, because generic functions may try to 173 * function, because generic functions may try to
174 * access kasan mapping for the passed address. 174 * access kasan mapping for the passed address.
175 */ 175 */
176 kasan_disable_current();
177 memcpy(shadow_buf, shadow_row, SHADOW_BYTES_PER_ROW); 176 memcpy(shadow_buf, shadow_row, SHADOW_BYTES_PER_ROW);
178 print_hex_dump(KERN_ERR, buffer, 177 print_hex_dump(KERN_ERR, buffer,
179 DUMP_PREFIX_NONE, SHADOW_BYTES_PER_ROW, 1, 178 DUMP_PREFIX_NONE, SHADOW_BYTES_PER_ROW, 1,
180 shadow_buf, SHADOW_BYTES_PER_ROW, 0); 179 shadow_buf, SHADOW_BYTES_PER_ROW, 0);
181 kasan_enable_current();
182 180
183 if (row_is_guilty(shadow_row, shadow)) 181 if (row_is_guilty(shadow_row, shadow))
184 pr_err("%*c\n", 182 pr_err("%*c\n",
@@ -195,6 +193,10 @@ void kasan_report_error(struct kasan_access_info *info)
195{ 193{
196 unsigned long flags; 194 unsigned long flags;
197 195
196 /*
197 * Make sure we don't end up in loop.
198 */
199 kasan_disable_current();
198 spin_lock_irqsave(&report_lock, flags); 200 spin_lock_irqsave(&report_lock, flags);
199 pr_err("=================================" 201 pr_err("================================="
200 "=================================\n"); 202 "=================================\n");
@@ -204,12 +206,17 @@ void kasan_report_error(struct kasan_access_info *info)
204 pr_err("=================================" 206 pr_err("================================="
205 "=================================\n"); 207 "=================================\n");
206 spin_unlock_irqrestore(&report_lock, flags); 208 spin_unlock_irqrestore(&report_lock, flags);
209 kasan_enable_current();
207} 210}
208 211
209void kasan_report_user_access(struct kasan_access_info *info) 212void kasan_report_user_access(struct kasan_access_info *info)
210{ 213{
211 unsigned long flags; 214 unsigned long flags;
212 215
216 /*
217 * Make sure we don't end up in loop.
218 */
219 kasan_disable_current();
213 spin_lock_irqsave(&report_lock, flags); 220 spin_lock_irqsave(&report_lock, flags);
214 pr_err("=================================" 221 pr_err("================================="
215 "=================================\n"); 222 "=================================\n");
@@ -222,6 +229,7 @@ void kasan_report_user_access(struct kasan_access_info *info)
222 pr_err("=================================" 229 pr_err("================================="
223 "=================================\n"); 230 "=================================\n");
224 spin_unlock_irqrestore(&report_lock, flags); 231 spin_unlock_irqrestore(&report_lock, flags);
232 kasan_enable_current();
225} 233}
226 234
227void kasan_report(unsigned long addr, size_t size, 235void kasan_report(unsigned long addr, size_t size,