The padding VMA is never inserted into the VMA tree; therefore we
don't need to have the mmap lock in exclusive mode to modify it.
Test: v2/android-gki/ack_platform_integration_main_cf_arm64_boot_test
on kernel_virt_debug_aarch64
Bug: 346741763
Bug: 352463814
Change-Id: I4ca3ed22dab45b6bb895cb41c5c6792344188b61
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
(cherry picked from commit a8b3ebe7f90afe0ad0d9a8b0b90f266da06a7007)
Depending on the platform binary being executed, the linker
(interpreter) requested can be one of:
1) /system/bin/bootstrap/linker64
2) /system/bin/linker64
3) /apex/com.android.runtime/bin/linker64
Relax the check to the basename (linker64), instead of the path.
Bug: 330767927
Bug: 335584973
Change-Id: I4a1f95b7cecd126f85ad8cefd9ff10d272947f9e
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
Usually to modify vm_flags we need to take exclusive mmap_lock but here
only have the lock in read mode, to avoid all DONTNEED/DONTNEED_LOCKED
calls needing the write lock.
A race to the flags update can only happen with another MADV_DONTNEED on
the same process and same range (VMA).
In practice, this specific scenario is not possible because the action
that could cause it is usually performed at most once per VMA and only by the dynamic linker.
Forego protection for this case, to avoid penalties in the common cases.
Bug: 344634072
Change-Id: I54ac1f204e0445291f3df3872fbaa16b37722812
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
If the kernel is built CONFIG_CFI_CLANG=y, reading smaps
may cause a panic. This is due to a failed CFI check; which
is triggered becuase the signature of the function pointer for
printing smaps padding VMAs does not match exactly with that
for show_smap().
Fix this by casting the function pointer to the expected type
based on whether printing maps or smaps padding.
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: I65564a547dacbc4131f8557344c8c96e51f90cd5
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
In some cases a VMA with padding representation may be split, and
therefore the padding flags must be updated accordingly.
There are 3 cases to handle:
Given:
| DDDDPPPP |
where:
- D represents 1 page of data;
- P represents 1 page of padding;
- | represents the boundaries (start/end) of the VMA
1) Split exactly at the padding boundary
| DDDDPPPP | --> | DDDD | PPPP |
- Remove padding flags from the first VMA.
- The second VMA is all padding
2) Split within the padding area
| DDDDPPPP | --> | DDDDPP | PP |
- Subtract the length of the second VMA from the first VMA's
padding.
- The second VMA is all padding, adjust its padding length (flags)
3) Split within the data area
| DDDDPPPP | --> | DD | DDPPPP |
- Remove padding flags from the first VMA.
- The second VMA is has the same padding as from before the split.
To simplify the semantics merging of padding VMAs is not allowed.
If a split produces a VMA that is entirely padding, show_[s]maps()
only outputs the padding VMA entry (as the data entry is of length 0).
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: Ie2628ced5512e2c7f8af25fabae1f38730c8bb1a
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
Some file systems like F2FS use a custom filemap_fault ops. Remove this
check, as checking vm_file is sufficient.
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: Id6a584d934f06650c0a95afd1823669fc77ba2c2
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
Only preform padding advise from the execution context on bionic's
dynamic linker. This ensures that madvise() doesn't have unwanted
side effects.
Also rearrange the order of fail checks in madvise_vma_pad_pages()
in order of ascending cost.
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: I3e05b8780c6eda78007f86b613f8c11dd18ac28f
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
When performing LOAD segment extension, the dynamic linker knows what
portion of the VMA is padding. In order for the kernel to implement
mitigations that ensure app compatibility, the extent of the padding
must be made available to the kernel.
To achieve this, reuse MADV_DONTNEED on single VMAs to hint the padding
range to the kernel. This information is then stored in vm_flag bits.
This allows userspace (dynamic linker) to set the padding pages on the
VMA without a need for new out-of-tree UAPI.
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: I3421de32ab38ad3cb0fbce73ecbd8f7314287cde
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
The dynamic linker may extend ELF LOAD segment mappings to be contiguous
in memory when loading a 16kB compatible ELF on a 4kB page-size system.
This is done to reduce the use of unreclaimable VMA slab memory for the
otherwise necessary "gap" VMAs. The extended portion of the mapping
(VMA) can be viewed as "padding", meaning that the mapping in that range
corresponds to an area of the file that does not contain contents of the
respective segments (maybe zero's depending on how the ELF is built).
For some compatibility mitigations, the region of a VMA corresponding to
these padding sections need to be known.
In order to represent such regions without adding addtional overhead or
breaking ABI, some upper bits of vm_flags are used.
Add the VMA padding pages representation and the necessary APIs to
manipulate it.
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: Ieb9fa98e30ec9b0bec62256624f14e3ed6062a75
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
Migrating from 4kB to 16kB page-size in Android requires first making
the platform page-agnostic, which involves increasing Android-ELFs'
max-page-size (p_align) from 4kB to 16kB.
Increasing the ELF max-page-size was found to cause compatibility issues
in apps that use obfuscation or depend on the ELF segments being mapped
based on 4kB-alignment.
Working around these compatibility issues involves both kernel and
userspace (dynamic linker) changes.
Introduce a knob for userspace (dynamic linker) to determine whether the
kernel supports the mitigations needed for page-size migration compatibility.
The knob also allows for userspace to turn on or off these mitigations
by writing 1 or 0 to /sys/kernel/mm/pgsize_miration/enabled:
echo 1 > /sys/kernel/mm//pgsize_miration/enabled # Enable
echo 0 > /sys/kernel/mm//pgsize_miration/enabled # Disable
Bug: 330117029
Bug: 327600007
Bug: 330767927
Bug: 328266487
Bug: 329803029
Change-Id: I9ac1d15d397b8226b27827ecffa30502da91e10e
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>