[PATCH 6/6] arm64: module: rework module VA range selection
Mark Rutland
mark.rutland at arm.com
Fri May 12 07:33:33 PDT 2023
On Wed, May 10, 2023 at 07:12:42AM -0500, Shanker Donthineni wrote:
> Hi Mark,
>
> On 5/9/23 06:14, Mark Rutland wrote:
> > if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
> > - /*
> > - * Randomize the module region over a 2 GB window covering the
> > - * kernel. This reduces the risk of modules leaking information
> > - * about the address of the kernel itself, but results in
> > - * branches between modules and the core kernel that are
> > - * resolved via PLTs. (Branches between modules will be
> > - * resolved normally.)
> > - */
> > - module_range = SZ_2G - (u64)(_end - _stext);
> > - module_alloc_base = max((u64)_end - SZ_2G, (u64)MODULES_VADDR);
> > + pr_info("2G module region forced by RANDOMIZE_MODULE_REGION_FULL\n");
> > + } else if (kernel_size >= SZ_128M) {
> > + pr_info("2G module region forced by kernel size (%llu bytes)\n",
> > + kernel_size);
> > + } else if (IS_ENABLED(CONFIG_RANOMIZE_BASE)) {
> > + module_direct_base = choose_random_bounding_box(SZ_128M,
> > + kernel_start,
> > + kernel_end);
> > } else {
> > - /*
> > - * Randomize the module region by setting module_alloc_base to
> > - * a PAGE_SIZE multiple in the range [_etext - MODULES_VSIZE,
> > - * _stext) . This guarantees that the resulting region still
> > - * covers [_stext, _etext], and that all relative branches can
> > - * be resolved without veneers unless this region is exhausted
> > - * and we fall back to a larger 2GB window in module_alloc()
> > - * when ARM64_MODULE_PLTS is enabled.
> > - */
> > - module_range = MODULES_VSIZE - (u64)(_etext - _stext);
> > + module_direct_base = kernel_end - SZ_128M;
> > }
> >
> > - /* use the lower 21 bits to randomize the base of the module region */
> > - module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
> > - module_alloc_base &= PAGE_MASK;
> > + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
> > + u64 min, max;
> > +
> > + if (module_direct_base) {
> > + min = module_direct_base;
> > + max = module_direct_base + SZ_128M;
> > + } else {
> > + min = kernel_start;
> > + max = kernel_end;
> > + }
> > +
> > + module_plt_base = choose_random_bounding_box(SZ_2G, min, max);
> > + } else {
> > + module_plt_base = kernel_end - SZ_2G;
> > + }
>
> Sharing the 2GB space with other VMALLOC callers caused it to run out, which was
> the original problem. Is it feasible to avoid randomizing 'module_plt_base' and
> 'module_direct_base' when KASLR is disabled via the kernel boot parameter or when
> a random seed is not available? This approach would guarantee the full availability
> of the entire 2GB space for modules/kernel.
Ah, sorry, I'd messed up the conditions here, I had meant to use the deafult
region when KASLR was disabled dynamically.
I'll spin a v2 with that corrected.
> --- a/arch/arm64/kernel/module.c
> +++ b/arch/arm64/kernel/module.c
> @@ -88,7 +88,7 @@ static int __init module_init_limits(void)
> } else if (kernel_size >= SZ_128M) {
> pr_info("2G module region forced by kernel size (%llu bytes)\n",
> kernel_size);
> - } else if (IS_ENABLED(CONFIG_RANOMIZE_BASE)) {
> + } else if (IS_ENABLED(CONFIG_RANOMIZE_BASE) && kaslr_enabled()) {
An earlier patch makes kaslr_enabled() consider CONFIG_RANOMIZE_BASE, so we
only need to check kaslr_enabled().
I'll respin with this reworked.
Thanks,
Mark.
More information about the linux-arm-kernel
mailing list