Linux: add sanity check in find_aslr
#1070
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Describe the bug
We encountered a situation where Volatility would wrongly assume that a memory image had a virtual ASLR of zero because the first matching
init_task
was in a fragment of the.data
section of the kernel ELF file in the page cache, instead of the one in the running kernel's.data
section. The kernel ELF file was opened prior to acquisition and thus fragments of it were scattered in physical memory.The kernel ELF file's
.data
section contains theinit_task
'stask_struct
with values for thefiles
,thread_pid
,fs
, ... members initialized to the non-randomized addresses that are also found in the system map.Volatility currently picks the first valid-looking
init_task
it finds in the image and thus if such a fragment of the data section precedes the realinit_task
a virtual ASLR of zero is determined by the following code:To identify such "phony" matches I'd propose two heuristics:
"match is phony" <=> .active_mm == init_mm
where the address ofinit_mm
is taken from the system map/json symbols. This works because kernel threads, i.e. tasks with.mm=NULL
, "steal" theactive_mm
of the previous task when they are scheduled to run on a CPU. Thus, as long as some CPU on the system has been idle at least once theactive_mm
of the real init_task will be unequal toinit_mm
, even on systems that really had no ASLR. (Theoretically it would be possible to construct an edge case where this is wrong, but it is incredibly unlikely ^^).tasks.next == .tasks.prev
, which should never be the case for the realinit_task
.I personally prefer the latter option due to its simplicity (just tell me if you think so too and I'll happily remove the other one from the PR).
Context
Volatility Version: a4b927f
To Reproduce
In case you are interested I uploaded some dump+symbol that exhibits this behavior. Download
Process listing plugins will show no output (empty task list), other plugins like
kmsg
will list dereference invalid pointers and crash.