Skip to content

Conversation

@rmalmain
Copy link
Member

@rmalmain rmalmain commented Jan 5, 2026

@WorksButNotTested
Copy link
Collaborator

Looks good. But we probably only want to change the 64-bit address space from its current configuration on aarch64. On x64, addresses must be canonical (sign extended from the 47th bit) so the new layout won't work there. The base of the low shadow will also need to change for the qemu-libafl-bridge. A further change may help required if the target supports aarch64 v8.2 where 52bit virtual addresses are introduced.

@rmalmain
Copy link
Member Author

rmalmain commented Jan 5, 2026

at this point, wouldn't it make more sense to have one definition of the layout per host architecture?
i guess we could even use build.rs to generate the right layout depending on the host cpu and os' configuration

@WorksButNotTested
Copy link
Collaborator

It is architecture dependent, but some architectures may share the same configuration. Also some architectures may have multiple configurations depending on the size of the address space used by the application, so may need to be dynamically detected.

1 similar comment
@WorksButNotTested
Copy link
Collaborator

It is architecture dependent, but some architectures may share the same configuration. Also some architectures may have multiple configurations depending on the size of the address space used by the application, so may need to be dynamically detected.

@rmalmain
Copy link
Member Author

rmalmain commented Jan 6, 2026

i drafted something to guess the layout from the host, we could iterate from there to handle all the corner cases.
the vma trick only works on linux and if host and guest (from the compiler point of view) are the same, not sure if this is a problem tho

Copy link
Collaborator

@WorksButNotTested WorksButNotTested left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget the qemu-libafl-bridge needs an update so that the tcg it generates when running in guest mode takes account of the shadow map layout.

Otherwise, looks really good. Thanks for taking the time to sort this!

}
}

fn find_max_vaddr_bits<const NB_TRIES: usize>() -> usize {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There may be an easier way to detect the supported VA space. See "52-bit userspace VAs" at the bottom of this article. https://opensource.com/article/20/12/52-bit-arm64-kernel

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i found the linux doc explaining the same things there: https://www.kernel.org/doc/html/latest/arch/arm64/memory.html

afaik this information is only accessible in kernel land, and not in userland.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the article is found said you can call mmap with a hint value to discover it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from what i understand it doesn't seem to be the exact purpose of calling mmap with ~0UL. it just hints to the kernel you are ready to receive addresses up to 52 bits, but it doesn't mean the kernel will even give you a 52bit address. also, it would not detect smaller vmas (39, 42, etc.), even if i guess this is not very common nowadays.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes. Good point. Might be worth scanning the current address map to see the highest address currently in use as a fallback? Or using the current address space to work out where to request new mappings when probing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thought about that, but i think the problem is a bit more tricky.
according to the documentation, linux will give by default 48 bit addresses, and give 52bit addresses if the application supports it. so i guess you could have an address map that looks like it's 48bits until later on the app requests a (possibly) 52bit address with the ~0UL trick. so i'm not sure it's easy to know in advance if the app will use 48bits or 52bits just by looking at the current address space.
with find_max_vaddr_bits, the idea is to know the 'real' max limit of the vma in the current environment, whatever the app does afterwards. we could end up using the 52-bits layout even though the app only gets 48-bits addresses, but i don't think that's a problem?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking if you know the current max va, then you know any requests to map higher addresses should only fail if the requested address is invalid rather than a collision? Maybe able to determine based on the value of errno too? Eexist vs einval?

@WorksButNotTested
Copy link
Collaborator

Neat solution using the weak symbol for the shadow base!

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.

3 participants