diff mbox series

[Crash-utility,V2] RISCV64: Add KASLR support

Message ID 20230818095028.1012639-1-songshuaishuai@tinylab.org (mailing list archive)
State Handled Elsewhere
Headers show
Series [Crash-utility,V2] RISCV64: Add KASLR support | expand

Checks

Context Check Description
conchuod/tree_selection fail Failed to apply to next/pending-fixes, riscv/for-next or riscv/master

Commit Message

Song Shuai Aug. 18, 2023, 9:50 a.m. UTC
From: Song Shuai <suagrfillet@gmail.com>

This patch adds KASLR support for Crash to analyze KASLR-ed vmcore
since RISC-V Linux is already sufficiently prepared for KASLR [1].

With this patch, even if the Crash '--kaslr' option is not set or Linux
CONFIG_RANDOMIZE_BASE is not configured, the 'derive_kaslr_offset()'
function will always work to calculate 'kt->relocate' which serves to
update the kernel virtual address.

Testing in Qemu rv64 virt, kernel log outputed the kernel offset:

[  121.214447] SMP: stopping secondary CPUs
[  121.215445] Kernel Offset: 0x37c00000 from 0xffffffff80000000
[  121.216312] Starting crashdump kernel...
[  121.216585] Will call new kernel at 94800000 from hart id 0
[  121.216834] FDT image at 9c7fd000
[  121.216982] Bye...

Running crash with `-d 1` option and without `--kaslr` option,
we get the right `kt->relocate` and kernel link addr:

$ ../crash/crash -d 1 vmlinux vmcore_kaslr_0815
...
KASLR:
  _stext from vmlinux: ffffffff80002000
  _stext from vmcoreinfo: ffffffffb7c02000
  relocate: 37c00000 (892MB)
vmemmap : 0xff1c000000000000 - 0xff20000000000000
vmalloc : 0xff20000000000000 - 0xff60000000000000
mudules : 0xffffffff3952f000 - 0xffffffffb7c00000
lowmem  : 0xff60000000000000 -
kernel link addr        : 0xffffffffb7c00000
...
      KERNEL: /home/song/9_linux/linux/00_rv_kaslr/vmlinux
    DUMPFILE: /tmp/hello/vmcore_kaslr_0815
        CPUS: 2
        DATE: Tue Aug 15 16:36:15 CST 2023
      UPTIME: 00:02:01
LOAD AVERAGE: 0.40, 0.23, 0.09
       TASKS: 63
    NODENAME: stage4.fedoraproject.org
     RELEASE: 6.5.0-rc3-00008-gad18dee423ac
     VERSION: #17 SMP Tue Aug 15 14:41:12 CST 2023
     MACHINE: riscv64  (unknown Mhz)
      MEMORY: 511.8 MB
       PANIC: "Kernel panic - not syncing: sysrq triggered crash"
         PID: 160
     COMMAND: "bash"
        TASK: ff6000000152bac0  [THREAD_INFO: ff6000000152bac0]
         CPU: 1
       STATE: TASK_RUNNING (PANIC)
crash>

[1]: https://lore.kernel.org/linux-riscv/20230722123850.634544-1-alexghiti@rivosinc.com/

Signed-off-by: Song Shuai <suagrfillet@gmail.com>
Reviewed-by: Guo Ren <guoren@kernel.org>

---
Changes since V1:
https://lore.kernel.org/linux-riscv/20230815104800.705753-1-songshuaishuai@tinylab.org/
  - supplement the output of my Crash test in the commit-msg 
  - add the Reviewed-by from Guo

---
 main.c    |  2 +-
 riscv64.c | 11 +++++++++++
 symbols.c |  4 ++--
 3 files changed, 14 insertions(+), 3 deletions(-)

Comments

HAGIO KAZUHITO(萩尾 一仁) Aug. 21, 2023, 12:43 a.m. UTC | #1
On 2023/08/18 18:50, Song Shuai wrote:
> From: Song Shuai <suagrfillet@gmail.com>
> 
> This patch adds KASLR support for Crash to analyze KASLR-ed vmcore
> since RISC-V Linux is already sufficiently prepared for KASLR [1].
> 
> With this patch, even if the Crash '--kaslr' option is not set or Linux
> CONFIG_RANDOMIZE_BASE is not configured, the 'derive_kaslr_offset()'
> function will always work to calculate 'kt->relocate' which serves to
> update the kernel virtual address.
> 
> Testing in Qemu rv64 virt, kernel log outputed the kernel offset:
> 
> [  121.214447] SMP: stopping secondary CPUs
> [  121.215445] Kernel Offset: 0x37c00000 from 0xffffffff80000000
> [  121.216312] Starting crashdump kernel...
> [  121.216585] Will call new kernel at 94800000 from hart id 0
> [  121.216834] FDT image at 9c7fd000
> [  121.216982] Bye...
> 
> Running crash with `-d 1` option and without `--kaslr` option,
> we get the right `kt->relocate` and kernel link addr:
> 
> $ ../crash/crash -d 1 vmlinux vmcore_kaslr_0815
> ...
> KASLR:
>    _stext from vmlinux: ffffffff80002000
>    _stext from vmcoreinfo: ffffffffb7c02000
>    relocate: 37c00000 (892MB)
> vmemmap : 0xff1c000000000000 - 0xff20000000000000
> vmalloc : 0xff20000000000000 - 0xff60000000000000
> mudules : 0xffffffff3952f000 - 0xffffffffb7c00000
> lowmem  : 0xff60000000000000 -
> kernel link addr        : 0xffffffffb7c00000
> ...
>        KERNEL: /home/song/9_linux/linux/00_rv_kaslr/vmlinux
>      DUMPFILE: /tmp/hello/vmcore_kaslr_0815
>          CPUS: 2
>          DATE: Tue Aug 15 16:36:15 CST 2023
>        UPTIME: 00:02:01
> LOAD AVERAGE: 0.40, 0.23, 0.09
>         TASKS: 63
>      NODENAME: stage4.fedoraproject.org
>       RELEASE: 6.5.0-rc3-00008-gad18dee423ac
>       VERSION: #17 SMP Tue Aug 15 14:41:12 CST 2023
>       MACHINE: riscv64  (unknown Mhz)
>        MEMORY: 511.8 MB
>         PANIC: "Kernel panic - not syncing: sysrq triggered crash"
>           PID: 160
>       COMMAND: "bash"
>          TASK: ff6000000152bac0  [THREAD_INFO: ff6000000152bac0]
>           CPU: 1
>         STATE: TASK_RUNNING (PANIC)
> crash>
> 
> [1]: https://lore.kernel.org/linux-riscv/20230722123850.634544-1-alexghiti@rivosinc.com/
> 
> Signed-off-by: Song Shuai <suagrfillet@gmail.com>
> Reviewed-by: Guo Ren <guoren@kernel.org>
> 
> ---
> Changes since V1:
> https://lore.kernel.org/linux-riscv/20230815104800.705753-1-songshuaishuai@tinylab.org/
>    - supplement the output of my Crash test in the commit-msg
>    - add the Reviewed-by from Guo
> 
> ---
>   main.c    |  2 +-
>   riscv64.c | 11 +++++++++++
>   symbols.c |  4 ++--
>   3 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/main.c b/main.c
> index b278c22..0c6e595 100644
> --- a/main.c
> +++ b/main.c
> @@ -228,7 +228,7 @@ main(int argc, char **argv)
>   			} else if (STREQ(long_options[option_index].name, "kaslr")) {
>   				if (!machine_type("X86_64") &&
>   				    !machine_type("ARM64") && !machine_type("X86") &&
> -				    !machine_type("S390X"))
> +				    !machine_type("S390X") && !machine_type("RISCV64"))
>   					error(INFO, "--kaslr not valid "
>   						"with this machine type.\n");
>   				else if (STREQ(optarg, "auto"))
> diff --git a/riscv64.c b/riscv64.c
> index a02f75a..288c7ae 100644
> --- a/riscv64.c
> +++ b/riscv64.c
> @@ -378,6 +378,9 @@ static void riscv64_get_va_range(struct machine_specific *ms)
>   	} else
>   		goto error;
>   
> +	if ((kt->flags2 & KASLR) && (kt->flags & RELOC_SET))
> +		ms->kernel_link_addr += (kt->relocate * -1);
> +
>   	/*
>   	 * From Linux 5.13, the kernel mapping is moved to the last 2GB
>   	 * of the address space, modules use the 2GB memory range right
> @@ -1360,6 +1363,14 @@ riscv64_init(int when)
>   
>   		machdep->verify_paddr = generic_verify_paddr;
>   		machdep->ptrs_per_pgd = PTRS_PER_PGD;
> +
> +		/*
> +		 * Even if CONFIG_RANDOMIZE_BASE is not configured,
> +		 * derive_kaslr_offset() should work and set
> +		 * kt->relocate to 0
> +		 */
> +		if (!kt->relocate && !(kt->flags2 & (RELOC_AUTO|KASLR)))
> +			kt->flags2 |= (RELOC_AUTO|KASLR);
>   		break;
>   
>   	case PRE_GDB:
> diff --git a/symbols.c b/symbols.c
> index 876be7a..8e8b4c3 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -629,7 +629,7 @@ kaslr_init(void)
>   	char *string;
>   
>   	if ((!machine_type("X86_64") && !machine_type("ARM64") && !machine_type("X86") &&
> -	    !machine_type("S390X")) || (kt->flags & RELOC_SET))
> +	    !machine_type("S390X") && !machine_type("RISCV64")) || (kt->flags & RELOC_SET))
>   		return;
>   
>   	if (!kt->vmcoreinfo._stext_SYMBOL &&
> @@ -795,7 +795,7 @@ store_symbols(bfd *abfd, int dynamic, void *minisyms, long symcount,
>   		} else if (!(kt->flags & RELOC_SET))
>   			kt->flags |= RELOC_FORCE;
>   	} else if (machine_type("X86_64") || machine_type("ARM64") ||
> -		   machine_type("S390X")) {
> +		   machine_type("S390X") || machine_type("RISCV64")) {
>   		if ((kt->flags2 & RELOC_AUTO) && !(kt->flags & RELOC_SET))
>   			derive_kaslr_offset(abfd, dynamic, from,
>   				fromend, size, store);

Thanks, applied.
https://github.com/crash-utility/crash/commit/1aa93cd33fa11f9d9bc9dc7e6a698d690fdd1bb3

Kazu
diff mbox series

Patch

diff --git a/main.c b/main.c
index b278c22..0c6e595 100644
--- a/main.c
+++ b/main.c
@@ -228,7 +228,7 @@  main(int argc, char **argv)
 			} else if (STREQ(long_options[option_index].name, "kaslr")) {
 				if (!machine_type("X86_64") &&
 				    !machine_type("ARM64") && !machine_type("X86") &&
-				    !machine_type("S390X"))
+				    !machine_type("S390X") && !machine_type("RISCV64"))
 					error(INFO, "--kaslr not valid "
 						"with this machine type.\n");
 				else if (STREQ(optarg, "auto"))
diff --git a/riscv64.c b/riscv64.c
index a02f75a..288c7ae 100644
--- a/riscv64.c
+++ b/riscv64.c
@@ -378,6 +378,9 @@  static void riscv64_get_va_range(struct machine_specific *ms)
 	} else
 		goto error;
 
+	if ((kt->flags2 & KASLR) && (kt->flags & RELOC_SET))
+		ms->kernel_link_addr += (kt->relocate * -1);
+
 	/*
 	 * From Linux 5.13, the kernel mapping is moved to the last 2GB
 	 * of the address space, modules use the 2GB memory range right
@@ -1360,6 +1363,14 @@  riscv64_init(int when)
 
 		machdep->verify_paddr = generic_verify_paddr;
 		machdep->ptrs_per_pgd = PTRS_PER_PGD;
+
+		/*
+		 * Even if CONFIG_RANDOMIZE_BASE is not configured,
+		 * derive_kaslr_offset() should work and set
+		 * kt->relocate to 0
+		 */
+		if (!kt->relocate && !(kt->flags2 & (RELOC_AUTO|KASLR)))
+			kt->flags2 |= (RELOC_AUTO|KASLR);
 		break;
 
 	case PRE_GDB:
diff --git a/symbols.c b/symbols.c
index 876be7a..8e8b4c3 100644
--- a/symbols.c
+++ b/symbols.c
@@ -629,7 +629,7 @@  kaslr_init(void)
 	char *string;
 
 	if ((!machine_type("X86_64") && !machine_type("ARM64") && !machine_type("X86") &&
-	    !machine_type("S390X")) || (kt->flags & RELOC_SET))
+	    !machine_type("S390X") && !machine_type("RISCV64")) || (kt->flags & RELOC_SET))
 		return;
 
 	if (!kt->vmcoreinfo._stext_SYMBOL &&
@@ -795,7 +795,7 @@  store_symbols(bfd *abfd, int dynamic, void *minisyms, long symcount,
 		} else if (!(kt->flags & RELOC_SET))
 			kt->flags |= RELOC_FORCE;
 	} else if (machine_type("X86_64") || machine_type("ARM64") ||
-		   machine_type("S390X")) {
+		   machine_type("S390X") || machine_type("RISCV64")) {
 		if ((kt->flags2 & RELOC_AUTO) && !(kt->flags & RELOC_SET))
 			derive_kaslr_offset(abfd, dynamic, from,
 				fromend, size, store);