mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
page-alloc: detect double free earlier
Right now this goes unnoticed until some subsequent page allocator operation stumbles across the thus corrupted list. We can do better: Only PGC_state_inuse and PGC_state_offlining pages can legitimately be passed to free_heap_pages(). Take the opportunity and also restrict the PGC_broken check to the PGC_state_offlining case, as only pages of that type or PGC_state_offlined may have this flag set on them. Similarly, since PGC_state_offlined is not a valid input state, the setting of "tainted" can be restricted to just this case. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
24f1a58d19
commit
f882fadbeb
1 file changed
+15
-6
+15
-6
@@ -1413,13 +1413,22 @@ static void free_heap_pages(
|
||||
* in its pseudophysical address space).
|
||||
* In all the above cases there can be no guest mappings of this page.
|
||||
*/
|
||||
ASSERT(!page_state_is(&pg[i], offlined));
|
||||
pg[i].count_info =
|
||||
((pg[i].count_info & PGC_broken) |
|
||||
(page_state_is(&pg[i], offlining)
|
||||
? PGC_state_offlined : PGC_state_free));
|
||||
if ( page_state_is(&pg[i], offlined) )
|
||||
switch ( pg[i].count_info & PGC_state )
|
||||
{
|
||||
case PGC_state_inuse:
|
||||
BUG_ON(pg[i].count_info & PGC_broken);
|
||||
pg[i].count_info = PGC_state_free;
|
||||
break;
|
||||
|
||||
case PGC_state_offlining:
|
||||
pg[i].count_info = (pg[i].count_info & PGC_broken) |
|
||||
PGC_state_offlined;
|
||||
tainted = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* If a page has no owner it will need no safety TLB flush. */
|
||||
pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL);
|
||||
|
||||