Mon Feb 4 15:13:54 2019 UTC ()
Clobber the size when freeing a buffer. This way, if the same buffer gets
freed twice, the second size check will fire.


(maxv)
diff -r1.72 -r1.73 src/sys/kern/subr_kmem.c

cvs diff -r1.72 -r1.73 src/sys/kern/subr_kmem.c (expand / switch to unified diff)

--- src/sys/kern/subr_kmem.c 2018/12/23 12:15:01 1.72
+++ src/sys/kern/subr_kmem.c 2019/02/04 15:13:54 1.73
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: subr_kmem.c,v 1.72 2018/12/23 12:15:01 maxv Exp $ */ 1/* $NetBSD: subr_kmem.c,v 1.73 2019/02/04 15:13:54 maxv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran and Maxime Villard. 8 * by Andrew Doran and Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -82,27 +82,27 @@ @@ -82,27 +82,27 @@
82 * A kernel with "option DEBUG" has "kmem_guard" debugging feature compiled 82 * A kernel with "option DEBUG" has "kmem_guard" debugging feature compiled
83 * in. See the comment below for what kind of bugs it tries to detect. Even 83 * in. See the comment below for what kind of bugs it tries to detect. Even
84 * if compiled in, it's disabled by default because it's very expensive. 84 * if compiled in, it's disabled by default because it's very expensive.
85 * You can enable it on boot by: 85 * You can enable it on boot by:
86 * boot -d 86 * boot -d
87 * db> w kmem_guard_depth 0t30000 87 * db> w kmem_guard_depth 0t30000
88 * db> c 88 * db> c
89 * 89 *
90 * The default value of kmem_guard_depth is 0, which means disabled. 90 * The default value of kmem_guard_depth is 0, which means disabled.
91 * It can be changed by KMEM_GUARD_DEPTH kernel config option. 91 * It can be changed by KMEM_GUARD_DEPTH kernel config option.
92 */ 92 */
93 93
94#include <sys/cdefs.h> 94#include <sys/cdefs.h>
95__KERNEL_RCSID(0, "$NetBSD: subr_kmem.c,v 1.72 2018/12/23 12:15:01 maxv Exp $"); 95__KERNEL_RCSID(0, "$NetBSD: subr_kmem.c,v 1.73 2019/02/04 15:13:54 maxv Exp $");
96 96
97#ifdef _KERNEL_OPT 97#ifdef _KERNEL_OPT
98#include "opt_kmem.h" 98#include "opt_kmem.h"
99#endif 99#endif
100 100
101#include <sys/param.h> 101#include <sys/param.h>
102#include <sys/callback.h> 102#include <sys/callback.h>
103#include <sys/kmem.h> 103#include <sys/kmem.h>
104#include <sys/pool.h> 104#include <sys/pool.h>
105#include <sys/debug.h> 105#include <sys/debug.h>
106#include <sys/lockdebug.h> 106#include <sys/lockdebug.h>
107#include <sys/cpu.h> 107#include <sys/cpu.h>
108#include <sys/asan.h> 108#include <sys/asan.h>
@@ -539,26 +539,28 @@ kmem_size_set(void *p, size_t sz) @@ -539,26 +539,28 @@ kmem_size_set(void *p, size_t sz)
539static void 539static void
540kmem_size_check(void *p, size_t sz) 540kmem_size_check(void *p, size_t sz)
541{ 541{
542 struct kmem_header *hd; 542 struct kmem_header *hd;
543 size_t hsz; 543 size_t hsz;
544 544
545 hd = (struct kmem_header *)p; 545 hd = (struct kmem_header *)p;
546 hsz = hd->size; 546 hsz = hd->size;
547 547
548 if (hsz != sz) { 548 if (hsz != sz) {
549 panic("kmem_free(%p, %zu) != allocated size %zu", 549 panic("kmem_free(%p, %zu) != allocated size %zu",
550 (const uint8_t *)p + SIZE_SIZE, sz, hsz); 550 (const uint8_t *)p + SIZE_SIZE, sz, hsz);
551 } 551 }
 552
 553 hd->size = -1;
552} 554}
553#endif /* defined(KMEM_SIZE) */ 555#endif /* defined(KMEM_SIZE) */
554 556
555#if defined(KMEM_GUARD) 557#if defined(KMEM_GUARD)
556/* 558/*
557 * The ultimate memory allocator for debugging, baby. It tries to catch: 559 * The ultimate memory allocator for debugging, baby. It tries to catch:
558 * 560 *
559 * 1. Overflow, in realtime. A guard page sits immediately after the 561 * 1. Overflow, in realtime. A guard page sits immediately after the
560 * requested area; a read/write overflow therefore triggers a page 562 * requested area; a read/write overflow therefore triggers a page
561 * fault. 563 * fault.
562 * 2. Invalid pointer/size passed, at free. A kmem_header structure sits 564 * 2. Invalid pointer/size passed, at free. A kmem_header structure sits
563 * just before the requested area, and holds the allocated size. Any 565 * just before the requested area, and holds the allocated size. Any
564 * difference with what is given at free triggers a panic. 566 * difference with what is given at free triggers a panic.