Skip to content

Multiple heap buffer overflows and assertion failure in microvium #87

@snoopysecurity

Description

@snoopysecurity

HI, i fuzzed microvium with libfuzzer and found multiple security issues. Opening an issue since i contacted the maintainer via email and there was no reply, and looking at commits i assume this project isn't active anymore.

Heap Buffer Overflow in mvm_restore()

The mvm_restore() function attempts to read 45,568 bytes from a 46-byte buffer during bytecode restoration. The bytecode header contains attacker-controlled size fields that are not validated before being used in memcpy() operations.

Code Location

// dist-c/microvium.c:5395
memcpy_long(destination, source, size); // No bounds checking!

Stack Trace

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 45568 at 0xfdb695800e7e thread T0

#0 in __asan_memcpy
#1 in memcpy_long /dist-c/microvium.c:8505:3
#2 in mvm_restore /dist-c/microvium.c:5395:3

0xfdb695800e7e is located 0 bytes to the right of 46-byte region
=================================================================
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xfdb695800e7e
READ of size 45568 at 0xfdb695800e7e thread T0
    #0 in __asan_memcpy
    #1 in memcpy_long /dist-c/microvium.c:8505:3
    #2 in mvm_restore /dist-c/microvium.c:5395:3

0xfdb695800e7e is located 0 bytes to the right of 46-byte region
allocated by thread T0
=================================================================

Heap Buffer Overflow in vm_resolveExports()

When resolving exported functions, vm_resolveExports() reads 2 bytes beyond the allocated 46-byte buffer. This occurs when the bytecode header contains malformed export table offsets that point beyond the file boundary.

Code Location

// dist-c/microvium.c:6813
LongPtr_read2_aligned(exportTablePtr); // No bounds checking!

Stack Trace

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 2 at 0xff050d400e80 thread T0

#0 in LongPtr_read2_aligned /dist-c/microvium.c:6170:21
#1 in vm_resolveExport /dist-c/microvium.c:6813:31
#2 in mvm_resolveExports /dist-c/microvium.c:6835:23

0xff050d400e80 is located 2 bytes to the right of 46-byte region
=================================================================
==12346==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xff050d400e80
READ of size 2 at 0xff050d400e80 thread T0
    #0 in LongPtr_read2_aligned /dist-c/microvium.c:6170:21
    #1 in vm_resolveExport /dist-c/microvium.c:6813:31
    #2 in mvm_resolveExports /dist-c/microvium.c:6835:23

0xff050d400e80 is located 2 bytes to the right of 46-byte region
=================================================================

Assertion Failure in vm_getHandleTargetOrNull()

The vm_getHandleTargetOrNull() function contains a reachable assert(false) statement that crashes the VM when processing certain bytecode patterns during function calls. This assertion can be triggered by malformed handle values in the bytecode.

Code Location

// dist-c/microvium.c:7551
default:
  assert(false); // Reachable with malformed bytecode!
  return NULL;

Stack Trace

fuzzer: dist-c/microvium.c:7551: Assertion `false' failed.

#9  in vm_getHandleTargetOrNull /dist-c/microvium.c:7551:3
#10 in vm_resolveIndirections /dist-c/microvium.c:7564:19
#11 in mvm_call /dist-c/microvium.c:2162:23
fuzzer: dist-c/microvium.c:7551: Assertion `false' failed.
    #9  in vm_getHandleTargetOrNull /dist-c/microvium.c:7551:3
    #10 in vm_resolveIndirections /dist-c/microvium.c:7564:19
    #11 in mvm_call /dist-c/microvium.c:2162:23

Assertion Failure in ShortPtr_decode()

During garbage collection, the ShortPtr_decode() function hits a reachable assert(false) when processing malformed pointer values. This causes immediate VM termination during memory management operations.

Code Location

// dist-c/microvium.c:6009
default:
  assert(false); // Reachable during GC!
  return NULL;

Stack Trace

fuzzer: dist-c/microvium.c:6009: Assertion `false' failed.

#9  in ShortPtr_decode /dist-c/microvium.c:6009:5
#10 in gc_processShortPtrValue /dist-c/microvium.c:6270:37
#11 in gc_processValue /dist-c/microvium.c:6453:5
#12 in mvm_runGC /dist-c/microvium.c:6547:5
fuzzer: dist-c/microvium.c:6009: Assertion `false' failed.
    #9  in ShortPtr_decode /dist-c/microvium.c:6009:5
    #10 in gc_processShortPtrValue /dist-c/microvium.c:6270:37
    #11 in gc_processValue /dist-c/microvium.c:6453:5
    #12 in mvm_runGC /dist-c/microvium.c:6547:5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions