Skip to content

uc_mem: reject address+size wrap-around in check_mem_area#2324

Open
MarkLee131 wants to merge 1 commit into
unicorn-engine:devfrom
MarkLee131:fix/issue-2321-mem-wrap-check
Open

uc_mem: reject address+size wrap-around in check_mem_area#2324
MarkLee131 wants to merge 1 commit into
unicorn-engine:devfrom
MarkLee131:fix/issue-2321-mem-wrap-check

Conversation

@MarkLee131

Copy link
Copy Markdown

uc_mem_map() rejects address+size wrap-around in mem_map_check(), but uc_mem_read/write/unmap/protect() didn't have the same guard. They go through check_mem_area(), which iterated pages without an overflow check and happily walked from the top of the address space back to 0 when a low page was also mapped.

Concretely, with two legal mappings at the top page and at address 0:

  • uc_mem_read(top, buf, 0x2000) writes 0x2000 bytes into a 0x1000 buffer (host heap-overflow into the caller's storage) and returns UC_ERR_OK.
  • uc_mem_write mirrors that as a 0x1000 OOB read of the source.
  • uc_mem_unmap returns OK and silently drops both regions.
  • uc_mem_protect returns OK and demotes both regions' permissions.

Adding the wrap check inside check_mem_area() lets the four callers keep their existing not-mapped error codes (READ_UNMAPPED / WRITE_UNMAPPED / NOMEM) without any per-call-site changes.

Adds a regression test in tests/unit/test_mem.c that maps both pages, exercises all four entry points with a wrapping range, and checks that the non-wrapping single-page case still works.

Closes #1641. Fixes #2321.

uc_mem_map() rejects address+size wrap-around in mem_map_check(), but
uc_mem_read/write/unmap/protect() didn't have the same guard. They go
through check_mem_area(), which iterated pages without an overflow
check and happily walked from the top of the address space back to 0
when a low page was also mapped.

Concretely, with two legal mappings at the top page and at address 0:

  - uc_mem_read(top, buf, 0x2000) writes 0x2000 bytes into a 0x1000
    buffer (host heap-overflow into the caller's storage) and returns
    UC_ERR_OK.
  - uc_mem_write mirrors that as a 0x1000 OOB read of the source.
  - uc_mem_unmap returns OK and silently drops both regions.
  - uc_mem_protect returns OK and demotes both regions' permissions.

Adding the wrap check inside check_mem_area() lets the four callers
keep their existing not-mapped error codes (READ_UNMAPPED /
WRITE_UNMAPPED / NOMEM) without any per-call-site changes.

Adds a regression test in tests/unit/test_mem.c that maps both pages,
exercises all four entry points with a wrapping range, and checks that
the non-wrapping single-page case still works.

Closes unicorn-engine#1641. Fixes unicorn-engine#2321.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant