Re: [PATCH v3 3/3] LoongArch: Avoid initrd overlap during kernel relocation

Huacai Chen <[email protected]>
Newsgroups org.kernel.vger.linux-efi,dev.linux.lists.loongarch,org.kernel.vger.linux-kernel
Message-ID <CAAhV-H60vUx8PyT6nhxbog3=sYFL+E5Hgt1aS+7HWHddtLdb7w@mail.gmail.com>
Hi, Rui,

On Wed, Apr 29, 2026 at 1:14 PM WANG Rui <[email protected]> wrote:
>
> Validate the relocation address against the initrd region specified
> via "initrd=" or "initrdmem=" on the command line. Reject relocation
> targets that overlap the initrd to prevent memory corruption during
> early boot.
>
> Signed-off-by: WANG Rui <[email protected]>
> ---
>  arch/loongarch/kernel/relocate.c | 45 ++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>
> diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
> index c36604a81d08..c303c0be8f06 100644
> --- a/arch/loongarch/kernel/relocate.c
> +++ b/arch/loongarch/kernel/relocate.c
> @@ -214,14 +214,59 @@ static inline void __init *determine_relocation_address(void)
>         return RELOCATED_KASLR(destination);
>  }
>
> +static unsigned long __init try_get_initrd(unsigned long *size)
Rename to determine_initrd_address() can keep consistency.

> +{
> +       unsigned long start = 0;
> +       unsigned int key_length;
It's type should be "unsigned long" because strstr() returns "unsigned long".

Huacai

> +       const char *key;
> +       char *p;
> +
> +       key = "initrd=";
> +       key_length = strlen(key);
> +       p = strstr(boot_command_line, key);
> +
> +       if (!p) {
> +               key = "initrdmem=";
> +               key_length = strlen(key);
> +               p = strstr(boot_command_line, key);
> +       }
> +
> +       if (p == boot_command_line || (p > boot_command_line && *(p - 1) == ' ')) {
> +               char *endp;
> +
> +               p += key_length;
> +               start = memparse(p, &endp);
> +               if (*endp == ',')
> +                       *size = memparse(endp + 1, NULL);
> +       }
> +
> +       return start;
> +}
> +
>  static inline int __init relocation_addr_valid(void *location_new)
>  {
> +       unsigned long initrd_start;
> +       unsigned long initrd_size = 0;
> +
>         if ((unsigned long)location_new & 0x00000ffff)
>                 return 0; /* Inappropriately aligned new location */
>
>         if ((unsigned long)location_new < (unsigned long)_end)
>                 return 0; /* New location overlaps original kernel */
>
> +       initrd_start = try_get_initrd(&initrd_size);
> +       if (initrd_start && initrd_size) {
> +               unsigned long kernel_start;
> +               unsigned long kernel_size;
> +
> +               kernel_start = PHYSADDR(location_new);
> +               kernel_size = (unsigned long)_end - (unsigned long)_text;
> +
> +               if (kernel_start < (initrd_start + initrd_size) &&
> +                       initrd_start < (kernel_start + kernel_size))
> +                       return 0; /* Initrd overlaps kernel */
> +       }
> +
>         return 1;
>  }
>  #endif
> --
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.