Skip to content

mmap() should handle collisions with areas mapped with mmu::linear_map()  #1135

@wkozaczuk

Description

@wkozaczuk

While investigating crash when trying to run Node.JS on OSv on aarch64 (this problem does not seem to be arch specific), I have come to realize that OSv mmap() does not check for any potential collisions with areas of memory mapped with mmu::linear_map().

For example, is case of this crash with extra debug info added one can see clear collision:

OSv v0.55.0-248-g504b5423
linear_map: mapped from: ffff8000407bc000
                     to: ffff8000c0000000
linear_map: mapped from: ffff9000407bc000
                     to: ffff9000c0000000
linear_map: mapped from: ffffa000407bc000
                     to: ffffa000c0000000
linear_map: mapped from: 0000000040000000
                     to: 00000000407bc000
linear_map: mapped from: 0000000009000000
                     to: 0000000009001000
linear_map: mapped from: 0000000008000000
                     to: 0000000008010000
linear_map: mapped from: 0000000008010000
                     to: 0000000008020000
linear_map: mapped from: 0000004010000000
                     to: 0000004020000000
linear_map: mapped from: 000000003eff0000
                     to: 000000003f000000
linear_map: mapped from: 0000000010000000
                     to: 000000003eff0000
linear_map: mapped from: 0000000009010000
                     to: 0000000009011000
getauxval() stubbed
PSCI: version 65536.0 detected.
2 CPUs detected
getauxval() stubbed
Firmware vendor: Unknown
ELF [tid:0, mod:0, ]: The base set to: 000000000000000000 and end: 0x00000000407bab50
bsd: initializing - done
VFS: mounting ramfs at /
VFS: mounting devfs at /dev
net: initializing - done
linear_map: mapped from: ffff80000a000000
                     to: ffff80000a000200
Version 1 not supported!
linear_map: mapped from: ffff80000a000200
                     to: ffff80000a000400
Version 1 not supported!
linear_map: mapped from: ffff80000a000400
                     to: ffff80000a000600
Version 1 not supported!
linear_map: mapped from: ffff80000a000600
                     to: ffff80000a000800
Version 1 not supported!
linear_map: mapped from: ffff80000a000800
                     to: ffff80000a000a00
Version 1 not supported!
linear_map: mapped from: ffff80000a000a00
                     to: ffff80000a000c00
Version 1 not supported!
linear_map: mapped from: ffff80000a000c00
                     to: ffff80000a000e00
Version 1 not supported!
linear_map: mapped from: ffff80000a000e00
                     to: ffff80000a001000
Version 1 not supported!
eth0: ethernet address: 52:54:00:12:34:56
virtio-blk: Add blk device instances 0 as vblk0, devsize=72177664
random: virtio-rng registered as a source.
random: <Software, Yarrow> initialized
VFS: unmounting /dev
VFS: mounting rofs at /rofs
VFS: mounting devfs at /dev
VFS: mounting procfs at /proc
VFS: mounting sysfs at /sys
VFS: mounting ramfs at /tmp
[I/31 dhcp]: Broadcasting DHCPDISCOVER message with xid: [870938799]
[I/31 dhcp]: Waiting for IP...
[I/39 dhcp]: Received DHCPOFFER message from DHCP server: 192.168.122.1 regarding offerred IP address: 192.168.122.15
[I/39 dhcp]: Broadcasting DHCPREQUEST message with xid: [870938799] to SELECT offered IP: 192.168.122.15
[I/39 dhcp]: Received DHCPACK message from DHCP server: 192.168.122.1 regarding offerred IP address: 192.168.122.15
[I/39 dhcp]: Server acknowledged IP 192.168.122.15 for interface eth0 with time to lease in seconds: 86400
eth0: 192.168.122.15
[I/39 dhcp]: Configuring eth0: ip 192.168.122.15 subnet mask 255.255.255.0 gateway 192.168.122.1 MTU 1500
Booted up in 93.50 ms
Cmdline: /node !
ELF [tid:31, mod:1, /libvdso.so]: The base set to: 0x0000100000000000 and end: 0x0000100000011018
ELF [tid:31, mod:2, /node]: The base set to: 0x0000100000020000 and end: 0x0000100000032018
ELF [tid:31, mod:3, /usr/lib/libnode.so.72]: The base set to: 0x0000100000040000 and end: 0x000010000211e8d8
ELF [tid:31, mod:4, /usr/lib/libz.so.1]: The base set to: 0x0000100002120000 and end: 0x00001000021490b0
ELF [tid:31, mod:5, /usr/lib/libbrotlidec.so.1]: The base set to: 0x0000100002150000 and end: 0x000010000216a068
ELF [tid:31, mod:6, /usr/lib/libbrotlicommon.so.1]: The base set to: 0x0000100002170000 and end: 0x00001000021a0030
ELF [tid:31, mod:7, /usr/lib/libbrotlienc.so.1]: The base set to: 0x00001000021b0000 and end: 0x0000100002244070
ELF [tid:31, mod:8, /usr/lib/libcares.so.2]: The base set to: 0x0000100002250000 and end: 0x00001000022740f0
ELF [tid:31, mod:9, /usr/lib/libnghttp2.so.14]: The base set to: 0x0000100002280000 and end: 0x00001000022b70d0
ELF [tid:31, mod:10, /usr/lib/libcrypto.so.1.1]: The base set to: 0x00001000022c0000 and end: 0x0000100002554c68
ELF [tid:31, mod:11, /usr/lib/libssl.so.1.1]: The base set to: 0x0000100002560000 and end: 0x00001000025fa898
ELF [tid:31, mod:12, /usr/lib/libicui18n.so.67]: The base set to: 0x0000100002600000 and end: 0x0000100002904250
ELF [tid:31, mod:13, /usr/lib/libicuuc.so.67]: The base set to: 0x0000100002910000 and end: 0x0000100002b04140
ELF [tid:31, mod:14, /usr/lib/libicudata.so.67]: The base set to: 0x0000100002b10000 and end: 0x0000100004636010
ELF [tid:31, mod:15, /usr/lib/libgcc_s.so.1]: The base set to: 0x0000100004640000 and end: 0x0000100004664458
--> mmap MAP_ANONYMOUS: trying to map from: 0x36e0d000 to: 0x3ee0d000
--> mmap MAP_ANONYMOUS: trying to map from: 0x42d00000 to: 0x42d7f000
--> mmap MAP_ANONYMOUS: trying to map from: 0x3cd00000 to: 0x3cd7f000

error: kvm run failed Function not implemented
 PC=0000100000afb694 X00=0000000000000001 X01=0000000000001000
X02=000000003ee40118 X03=000000003ee80000 X04=0000000000040000
X05=0000000000000000 X06=ffffa000426ff4d8 X07=0000200000700310
X08=00000000000092d8 X09=0000000000000080 X10=0000000000001728
X11=0000200000700150 X12=000000003ee80000 X13=0000000000000000
X14=0000100002481448 X15=0000000000000000 X16=00001000020d5a70
X17=0000100000afb670 X18=000000000000005c X19=000000003ee40000
X20=000000003ee80000 X21=0000200000700310 X22=ffffa000426ff4d8
X23=000000003ee40118 X24=ffff8000428d0318 X25=0000000000000000
X26=000000003ee7ffff X27=00002000007002f0 X28=000000003ee40118
X29=00002000007001e0 X30=0000100000b9ed40  SP=00002000007001e0
PSTATE=00000345 ---- EL1h
qemu failed.

The key lines are here:

linear_map: mapped from: 000000003eff0000
                     to: 000000003f000000
linear_map: mapped from: 0000000010000000
                     to: 000000003eff0000

--> mmap MAP_ANONYMOUS: trying to map from: 0x36e0d000 to: 0x3ee0d000
--> mmap MAP_ANONYMOUS: trying to map from: 0x42d00000 to: 0x42d7f000
--> mmap MAP_ANONYMOUS: trying to map from: 0x3cd00000 to: 0x3cd7f000

One can see 1st and 3rd MAP_ANONYMOUS mmap() received an addr hint that collides the memory mapped from 0x0000000010000000 to 0x000000003f000000. And our mmap implementation only checks the addr hint against vma_list not what was mapped by mmu::linear_map.

I am surprised this has not been an issue so far in the past.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions