-
Notifications
You must be signed in to change notification settings - Fork 63
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
[Question] mmap
os error 12
in Cloud Run
#292
Comments
Oh, I glossed over this (though this shouldn't apply in our case): Lines 563 to 576 in 6a99e6a
|
The panic is occurring here: Lines 263 to 267 in fc9617d
Apparently there's not enough memory for the WASM runtime. This depends on the number of rules, not the size of the scanned file. Could you replace the // Create module's main memory.
let main_memory = wasmtime::Memory::new(
wasm_store.as_context_mut(),
MemoryType::new(mem_size, None),
)
.unwrap_or_else(|_| {
panic!(
"{}",
format!(
"unable to create wasmtime memory with {} pages",
mem_size
)
.to_string()
)
}); |
After some investigation it looks that The operating system can impose a limit to the size of the process address space, in most Linux systems this is unlimited (you are limited only by the physical RAM), but you are hitting the limit imposed by the Cloud Run environment. As you said this can be reproduced using a Docker container, or more easily: changing the limits in your Linux system. For instance, this sets the limit to 4194304KB, (0x100000000 bytes): ulimit -v 4194304 With a very simple rule the issue is reproduced: yr scan test.yar test.yar
warning[invariant_expr]: invariant boolean expression
--> test.yar:1:21
|
1 | rule t { condition: true }
| ---- this expression is always true
|
= note: rule `t` is always `true`
thread '<unnamed>' panicked at lib/src/scanner/mod.rs:270:10:
called `Result::unwrap()` on an `Err` value: mmap failed to reserve 0x104000000 bytes
Caused by:
Cannot allocate memory (os error 12)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace |
Please try this change f1fc21d, experiment with different values and tell me if it works. I would say that 2GB is enough for accomodating even the largest set of rules, and it should work in most environment. I could also make it configurable. |
Will do! Making it configurable would be great if it's not too much of a lift, especially since it would allow us to make changes on the fly if we run into any further issues in more restrictive environments. |
Looks like only a single page is created before panicking:
Here's a stack trace excerpt too:
|
Played around with the new commit a bit. With a 16Gi equivalent limit in a container, I can run a decent number of concurrent I dropped the reservation value as low as Edit: bytecodealliance/wasmtime#3695 (comment) pretty much covers the same issue and bytecodealliance/wasmtime#9545 is mentioned as the follow up (with the modified settings I referenced above). |
Based on this comment around using "8GB guard pages": bytecodealliance/wasmtime#1501 (comment) I tried turning off https://docs.rs/wasmtime/latest/wasmtime/struct.Config.html#method.guard_before_linear_memory which seemed to help as well (still having to use a more conservative concurrency limit):
Dropping the reservation value is still important since I encountered the same crash with the default value; I landed on I think having these four options as being configurable should provide enough flexibility:
|
Using these config options present in
I'm not sure how these translate to the newly-reworded I doubt these are anywhere near as performant as the default settings, so I think being able to tune them will be important. |
@egibs With the lastest changes in https://github.com/VirusTotal/yara-x/tree/addr-space-reservation I believe you should not have problems. |
@plusvic -- looks good to me! I tested your new changes against the changes in my previous comment and they were functionally the same. |
@egibs I intend to merge #295 for fixing this issue. At the end I kept the guard page in front of the memory, as this should not increase the virtual address space consumption by too much, and it provides additional protection against bugs. I think this final configuration should be enough in most cases, but let me know if works for you. For the time being I'm not adding any API for configuring this. I prefer to find a configuration that works in all real-life cases, and don't burden users with too many details about the inner workings of the library. If this proves to be insufficient, then I can add some configuration knobs. |
@plusvic -- I'm not seeing any OOMs with the default guard settings which appear to be 32MiB:
Based on what I'm seeing this is ready for |
Each WASM module tries to reserve a large amount of virtual address space (4GB in 64-bits systems). This doesn't means that they actually needs this amount of RAM, it only means that it reserves address space in case the memory required by the module grows dynamically. As each YARA-X scanner needs one of these WASM modules, this implies that YARA-X ends up reserving a very large amount of virtual address space. This is problematic in some environments where the amount of virtual address space per process is limited (in Docker containers, for instance). This PR reduces the amount of virtual address space reserved by each WASM module, mainly by limiting the amount of memory of each WASM module to 16MB. This is enough to accommodate very large sets of rules, with millions of rules and patterns. Closes #292.
I'm seeing an interesting panic when running Go code that leverages yara-x in Cloud Run when and scanning certain files:

I imagine that this has something to do with Cloud Run's filesystem being entirely in-memory since I'm unable to reproduce this anywhere else outside of a Docker container using a tmpfs and memory limit. Additionally, even when using 24Gi+ of memory for the Cloud Run Service, creating a single scanner will result in this panic when scanning said files.
For reference, the scanner is being created with roughly ~15,000 rules, but it doesn't seem like that should require a reservation of 8GB of memory (
0x200000000
bytes) unless I'm completely misunderstanding.yara-x/lib/src/scanner/mod.rs
Lines 217 to 267 in 6a99e6a
Here's the rough outline of what's happening:
FWIW, I don't see any difference in behavior between
scanner.Scan
orrules.Scan(fc)
since the latter is just creating a new scanner behind the scenes. Could this just be due to reading said larger files into memory and then scanning them or is there something else at play?The text was updated successfully, but these errors were encountered: