Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

Overlapping memslots can corrupt linked list #234

Closed
leecher1337 opened this issue Aug 14, 2019 · 5 comments
Closed

Overlapping memslots can corrupt linked list #234

leecher1337 opened this issue Aug 14, 2019 · 5 comments

Comments

@leecher1337
Copy link
Contributor

leecher1337 commented Aug 14, 2019

Describe the Bug
When I try to add a memblock that ends at the exact beginning of the next memblock via HAX_VM_IOCTL_SET_RAM, there seems to be a condition where the new block is being left as referencing itself via flink and blink causing an infinite loop in the driver.
See logfile below for details

Summary:

Host Environment

  • HAXM version: c072ad9
  • Host OS version: Windows 10 pro 1803
  • Host OS architecture: x86_64
  • Host CPU model: Xeon E31235
  • Host RAM size: 12 GB

To Reproduce
Connect memory pages in the layout described in the logfile.

Expected Behavior
No self-referencing pointer in the linked list.

Reproducibility
100%

Diagnostic Information

HAXM log:

haxm_info:memslot_set_mapping: start_gfn=0xa0, npages=0x10, uva=0x0, flags=0x80
haxm_debug:ramblock_ref: block (FFFF9F882E1D9040): base_uva = 0x570000, size = 0x20000, ref_count = 2
haxm_debug:ramblock_deref: block (FFFF9F882E1D9040): base_uva = 0x570000, size = 0x20000, ref_count = 1
haxm_info:ept_handle_mapping_removed: RAM=>MMIO: start_gfn=0xa0, npages=0x10, uva=0x570000
haxm_info:ept_handle_mapping_removed: Invalidated 0 PTEs
haxm_debug:ramblock_deref: Reset RAM block (FFFF9F882E1D9040): base_uva = 0x570000, size = 0x20000, ref_count = 0
haxm_info:ramblock_free_chunks: Freeing <= 1 chunks, bitmap:
haxm_info:ramblock_free_chunks:   [0]=0x00
haxm_info:ramblock_free_chunks:   [1]=0x00
haxm_info:ramblock_free_chunks:   [2]=0x00
haxm_info:ramblock_free_chunks:   [3]=0x00
haxm_info:ramblock_free_chunks:   [4]=0x00
haxm_info:ramblock_free_chunks:   [5]=0x00
haxm_info:ramblock_free_chunks:   [6]=0x00
haxm_info:ramblock_free_chunks:   [7]=0x00
haxm_info:ramblock_free_chunks:   [8]=0x00
haxm_info:ramblock_free_chunks: All chunks freed: 128KB total, 0KB used
haxm_info:memslot dump begins:
haxm_info:memslot [0]: base_gfn = 0x0000000000000000, npages = 0xa0, uva = 0x0000000002200000, flags = 0x00 (block_base_uva = 0x0000000002200000, offset_within_block = 0x0)
haxm_info:memslot [1]: base_gfn = 0x00000000000000b0, npages = 0x8, uva = 0x00000000022b0000, flags = 0x00 (block_base_uva = 0x0000000002200000, offset_within_block = 0xb0000)
haxm_info:memslot [2]: base_gfn = 0x00000000000000bc, npages = 0x4, uva = 0x00000000022bc000, flags = 0x00 (block_base_uva = 0x0000000002200000, offset_within_block = 0xbc000)
haxm_info:memslot [3]: base_gfn = 0x00000000000000c0, npages = 0x40, uva = 0x00000000022c0000, flags = 0x01 (block_base_uva = 0x0000000002200000, offset_within_block = 0xc0000)
haxm_info:memslot [4]: base_gfn = 0x0000000000000100, npages = 0x10, uva = 0x0000000002300000, flags = 0x00 (block_base_uva = 0x0000000002200000, offset_within_block = 0x100000)
haxm_info:memslot dump ends!
haxm_info:memslot_set_mapping: start_gfn=0xb8, npages=0x8, uva=0x570000, flags=0x0
haxm_debug:ramblock_find: (FFFF9F882E1D9040): base_uva 0x570000, size 0x20000, ref_count 0
haxm_debug:ramblock_ref: block (FFFF9F882E1D9040): base_uva = 0x570000, size = 0x20000, ref_count = 1
haxm_debug:ramblock_ref: block (FFFF9F882E1D9360): base_uva = 0x2200000, size = 0x110000, ref_count = 6
haxm_debug:ramblock_deref: block (FFFF9F882E1D9360): base_uva = 0x2200000, size = 0x110000, ref_count = 5
haxm_debug:ramblock_ref: block (FFFF9F882E1D9040): base_uva = 0x570000, size = 0x20000, ref_count = 2
haxm_info:ept_handle_mapping_changed: RAM=>RAM: start_gfn=0xbc, npages=0x4, old_uva=0x22bc000, new_uva=0x574000
haxm_info:ept_handle_mapping_changed: Invalidated 0 PTEs
haxm_debug:ramblock_deref: block (FFFF9F882E1D9360): base_uva = 0x2200000, size = 0x110000, ref_count = 4
haxm_debug:ramblock_deref: block (FFFF9F882E1D9040): base_uva = 0x570000, size = 0x20000, ref_count = 1
haxm_info:memslot dump begins:
haxm_info:memslot [0]: base_gfn = 0x0000000000000000, npages = 0xa0, uva = 0x0000000002200000, flags = 0x00 (block_base_uva = 0x0000000002200000, offset_within_block = 0x0)
haxm_info:memslot [1]: base_gfn = 0x00000000000000b0, npages = 0x8, uva = 0x00000000022b0000, flags = 0x00 (block_base_uva = 0x0000000002200000, offset_within_block = 0xb0000)
haxm_info:memslot [2]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [3]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [4]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [5]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [6]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [7]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [8]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [9]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [10]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [11]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [12]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
haxm_info:memslot [13]: base_gfn = 0x00000000000000b8, npages = 0x8, uva = 0x0000000000570000, flags = 0x00 (block_base_uva = 0x0000000000570000, offset_within_block = 0x0)
@coxuintel
Copy link
Contributor

Any specific reason you are referencing commit c072ad9?

@leecher1337
Copy link
Contributor Author

Na,it's just that I have checked out this version and using it actively with my modifications, but there was no change in the way of the memslot implementation since then, so it shouldn't be a problem.
I suspect that

        // [3]
        if (*state & MEMSLOT_TO_INSERT) {
            memslot_move(src, dest);
        }

in memslot_process_end_diff_type is the reason for it,because it just replaces an item with a version that is self-referencing (see memslot_init) and the links aren't updated anywhere as far as I can see

@leecher1337
Copy link
Contributor Author

This should fix it:

static inline void memslot_move(hax_memslot *dest, hax_memslot *src)
{
	hax_list_node entry;

    ramblock_deref(dest->block);
	entry = dest->entry;
    memslot_init(dest, src);
	dest->entry = entry;
}

leecher1337 added a commit to leecher1337/haxm that referenced this issue Aug 15, 2019
@wcwang
Copy link
Contributor

wcwang commented Aug 15, 2019

Great thanks for your trouble shoot! I have added a comment in #199 for your reference.

@wcwang
Copy link
Contributor

wcwang commented Aug 30, 2019

Thanks for your quick response and commit in #237.

@wcwang wcwang closed this as completed Aug 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants