Mon Mar 11 20:38:28 2019 UTC ()
Add sanity check: make sure we retrieve a valid item header, by checking
its page address against the one we computed. If there's a mismatch it
means the buffer does not belong to the pool, and we panic.


(maxv)
diff -r1.234 -r1.235 src/sys/kern/subr_pool.c

cvs diff -r1.234 -r1.235 src/sys/kern/subr_pool.c (expand / switch to unified diff)

--- src/sys/kern/subr_pool.c 2019/03/11 20:21:32 1.234
+++ src/sys/kern/subr_pool.c 2019/03/11 20:38:27 1.235
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: subr_pool.c,v 1.234 2019/03/11 20:21:32 maxv Exp $ */ 1/* $NetBSD: subr_pool.c,v 1.235 2019/03/11 20:38:27 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008, 2010, 2014, 2015, 2018 4 * Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008, 2010, 2014, 2015, 2018
5 * The NetBSD Foundation, Inc. 5 * The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Paul Kranenburg; by Jason R. Thorpe of the Numerical Aerospace 9 * by Paul Kranenburg; by Jason R. Thorpe of the Numerical Aerospace
10 * Simulation Facility, NASA Ames Research Center; by Andrew Doran, and by 10 * Simulation Facility, NASA Ames Research Center; by Andrew Doran, and by
11 * Maxime Villard. 11 * Maxime Villard.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE. 32 * POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.234 2019/03/11 20:21:32 maxv Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.235 2019/03/11 20:38:27 maxv Exp $");
37 37
38#ifdef _KERNEL_OPT 38#ifdef _KERNEL_OPT
39#include "opt_ddb.h" 39#include "opt_ddb.h"
40#include "opt_lockdebug.h" 40#include "opt_lockdebug.h"
41#include "opt_kleak.h" 41#include "opt_kleak.h"
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/sysctl.h> 46#include <sys/sysctl.h>
47#include <sys/bitops.h> 47#include <sys/bitops.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/errno.h> 49#include <sys/errno.h>
@@ -421,27 +421,32 @@ pr_find_pagehead_noalign(struct pool *pp @@ -421,27 +421,32 @@ pr_find_pagehead_noalign(struct pool *pp
421 */ 421 */
422static inline struct pool_item_header * 422static inline struct pool_item_header *
423pr_find_pagehead(struct pool *pp, void *v) 423pr_find_pagehead(struct pool *pp, void *v)
424{ 424{
425 struct pool_item_header *ph, tmp; 425 struct pool_item_header *ph, tmp;
426 426
427 if ((pp->pr_roflags & PR_NOALIGN) != 0) { 427 if ((pp->pr_roflags & PR_NOALIGN) != 0) {
428 ph = pr_find_pagehead_noalign(pp, v); 428 ph = pr_find_pagehead_noalign(pp, v);
429 } else { 429 } else {
430 void *page = 430 void *page =
431 (void *)((uintptr_t)v & pp->pr_alloc->pa_pagemask); 431 (void *)((uintptr_t)v & pp->pr_alloc->pa_pagemask);
432 432
433 if ((pp->pr_roflags & PR_PHINPAGE) != 0) { 433 if ((pp->pr_roflags & PR_PHINPAGE) != 0) {
434 ph = (struct pool_item_header *)((char *)page + pp->pr_phoffset); 434 ph = (struct pool_item_header *)
 435 ((char *)page + pp->pr_phoffset);
 436 if (__predict_false((void *)ph->ph_page != page)) {
 437 panic("%s: [%s] item not part of pool",
 438 __func__, pp->pr_wchan);
 439 }
435 } else { 440 } else {
436 tmp.ph_page = page; 441 tmp.ph_page = page;
437 ph = SPLAY_FIND(phtree, &pp->pr_phtree, &tmp); 442 ph = SPLAY_FIND(phtree, &pp->pr_phtree, &tmp);
438 } 443 }
439 } 444 }
440 445
441 KASSERT(ph == NULL || ((pp->pr_roflags & PR_PHINPAGE) != 0) || 446 KASSERT(ph == NULL || ((pp->pr_roflags & PR_PHINPAGE) != 0) ||
442 ((char *)ph->ph_page <= (char *)v && 447 ((char *)ph->ph_page <= (char *)v &&
443 (char *)v < (char *)ph->ph_page + pp->pr_alloc->pa_pagesz)); 448 (char *)v < (char *)ph->ph_page + pp->pr_alloc->pa_pagesz));
444 return ph; 449 return ph;
445} 450}
446 451
447static void 452static void