-
-
Notifications
You must be signed in to change notification settings - Fork 434
Fix asan according to aarch64 48-bit VMA #3650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
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. |
|
at this point, wouldn't it make more sense to have one definition of the layout per host architecture? |
|
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
|
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. |
|
i drafted something to guess the layout from the host, we could iterate from there to handle all the corner cases. |
WorksButNotTested
left a comment
There was a problem hiding this 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 { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
|
Neat solution using the weak symbol for the shadow base! |
companion patch: AFLplusplus/qemu-libafl-bridge#124