All of lore.kernel.org
 help / color / mirror / Atom feed
* [kernel-hardening] [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-08-17 16:47 ` Thomas Garnier
  0 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-08-17 16:47 UTC (permalink / raw)
  To: kexec; +Cc: horms, keescook, kernel-hardening, Thomas Garnier

Multiple changes were made on KASLR (right now in linux-next). One of
them is randomizing the virtual address of the physical mapping, vmalloc
and vmemmap memory sections. It breaks kdump ability to read physical
memory.

This change identifies if KASLR memories randomization is used by
checking if the page_offset_base variable exists. It search for the
correct PAGE_OFFSET value by looking at the loaded memory section and
find the lowest aligned on PUD (the randomization level).

Related commits on linux-next:
 - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
 - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
 kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index bbc0f35..ab833d4 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
 	return -1;
 }
 
-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
-static unsigned long long get_kernel_stext_sym(void)
+/* Retrieve kernel symbol virtual address from /proc/kallsyms */
+static unsigned long long get_kernel_sym(const char *symbol)
 {
 	const char *kallsyms = "/proc/kallsyms";
-	const char *stext = "_stext";
 	char sym[128];
 	char line[128];
 	FILE *fp;
@@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
 	while(fgets(line, sizeof(line), fp) != NULL) {
 		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
 			continue;
-		if (strcmp(sym, stext) == 0) {
-			dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
+		if (strcmp(sym, symbol) == 0) {
+			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
 			return vaddr;
 		}
 	}
 
-	fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
+	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
 	return 0;
 }
 
@@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
 	off_t size;
 	uint32_t elf_flags = 0;
 	uint64_t stext_sym;
+	const unsigned long long pud_mask = ~((1 << 30) - 1);
+	unsigned long long vaddr, lowest_vaddr = 0;
 
 	if (elf_info->machine != EM_X86_64)
 		return 0;
@@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
 
 	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
 
+	/* Search for the real PAGE_OFFSET when KASLR memory randomization
+	 * is enabled */
+	if (get_kernel_sym("page_offset_base") != 0) {
+		for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
+			if (phdr->p_type == PT_LOAD) {
+				vaddr = phdr->p_vaddr & pud_mask;
+				if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
+					lowest_vaddr = vaddr;
+			}
+		}
+		if (lowest_vaddr != 0)
+			elf_info->page_offset = lowest_vaddr;
+	}
+
 	/* Traverse through the Elf headers and find the region where
 	 * _stext symbol is located in. That's where kernel is mapped */
-	stext_sym = get_kernel_stext_sym();
+	stext_sym = get_kernel_sym("_stext");
 	for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
 		if (phdr->p_type == PT_LOAD) {
 			unsigned long long saddr = phdr->p_vaddr;
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-08-17 16:47 ` Thomas Garnier
  0 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-08-17 16:47 UTC (permalink / raw)
  To: kexec; +Cc: Thomas Garnier, horms, keescook, kernel-hardening

Multiple changes were made on KASLR (right now in linux-next). One of
them is randomizing the virtual address of the physical mapping, vmalloc
and vmemmap memory sections. It breaks kdump ability to read physical
memory.

This change identifies if KASLR memories randomization is used by
checking if the page_offset_base variable exists. It search for the
correct PAGE_OFFSET value by looking at the loaded memory section and
find the lowest aligned on PUD (the randomization level).

Related commits on linux-next:
 - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
 - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
 kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index bbc0f35..ab833d4 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
 	return -1;
 }
 
-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
-static unsigned long long get_kernel_stext_sym(void)
+/* Retrieve kernel symbol virtual address from /proc/kallsyms */
+static unsigned long long get_kernel_sym(const char *symbol)
 {
 	const char *kallsyms = "/proc/kallsyms";
-	const char *stext = "_stext";
 	char sym[128];
 	char line[128];
 	FILE *fp;
@@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
 	while(fgets(line, sizeof(line), fp) != NULL) {
 		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
 			continue;
-		if (strcmp(sym, stext) == 0) {
-			dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
+		if (strcmp(sym, symbol) == 0) {
+			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
 			return vaddr;
 		}
 	}
 
-	fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
+	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
 	return 0;
 }
 
@@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
 	off_t size;
 	uint32_t elf_flags = 0;
 	uint64_t stext_sym;
+	const unsigned long long pud_mask = ~((1 << 30) - 1);
+	unsigned long long vaddr, lowest_vaddr = 0;
 
 	if (elf_info->machine != EM_X86_64)
 		return 0;
@@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
 
 	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
 
+	/* Search for the real PAGE_OFFSET when KASLR memory randomization
+	 * is enabled */
+	if (get_kernel_sym("page_offset_base") != 0) {
+		for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
+			if (phdr->p_type == PT_LOAD) {
+				vaddr = phdr->p_vaddr & pud_mask;
+				if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
+					lowest_vaddr = vaddr;
+			}
+		}
+		if (lowest_vaddr != 0)
+			elf_info->page_offset = lowest_vaddr;
+	}
+
 	/* Traverse through the Elf headers and find the region where
 	 * _stext symbol is located in. That's where kernel is mapped */
-	stext_sym = get_kernel_stext_sym();
+	stext_sym = get_kernel_sym("_stext");
 	for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
 		if (phdr->p_type == PT_LOAD) {
 			unsigned long long saddr = phdr->p_vaddr;
-- 
2.8.0.rc3.226.g39d4020


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-08-17 16:47 ` Thomas Garnier
@ 2016-08-18  4:59   ` Baoquan He
  -1 siblings, 0 replies; 15+ messages in thread
From: Baoquan He @ 2016-08-18  4:59 UTC (permalink / raw)
  To: Thomas Garnier; +Cc: kexec, horms, keescook, kernel-hardening

On 08/17/16 at 09:47am, Thomas Garnier wrote:
> Multiple changes were made on KASLR (right now in linux-next). One of
> them is randomizing the virtual address of the physical mapping, vmalloc
> and vmemmap memory sections. It breaks kdump ability to read physical
> memory.
> 
> This change identifies if KASLR memories randomization is used by
> checking if the page_offset_base variable exists. It search for the
> correct PAGE_OFFSET value by looking at the loaded memory section and
> find the lowest aligned on PUD (the randomization level).
> 
> Related commits on linux-next:
>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET

Seems above two commits have been inside Linus's tree, while vmemmap
not yet.

> 
> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> ---
>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index bbc0f35..ab833d4 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>  	return -1;
>  }
>  
> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
> -static unsigned long long get_kernel_stext_sym(void)
> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
> +static unsigned long long get_kernel_sym(const char *symbol)
>  {
>  	const char *kallsyms = "/proc/kallsyms";
> -	const char *stext = "_stext";
>  	char sym[128];
>  	char line[128];
>  	FILE *fp;
> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>  	while(fgets(line, sizeof(line), fp) != NULL) {
>  		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>  			continue;
> -		if (strcmp(sym, stext) == 0) {
> -			dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
> +		if (strcmp(sym, symbol) == 0) {
> +			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>  			return vaddr;
>  		}
>  	}
>  
> -	fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
> +	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>  	return 0;
>  }
>  
> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  	off_t size;
>  	uint32_t elf_flags = 0;
>  	uint64_t stext_sym;
> +	const unsigned long long pud_mask = ~((1 << 30) - 1);
> +	unsigned long long vaddr, lowest_vaddr = 0;
>  
>  	if (elf_info->machine != EM_X86_64)
>  		return 0;
> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  
>  	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>  
> +	/* Search for the real PAGE_OFFSET when KASLR memory randomization
> +	 * is enabled */

Yeah, this is necessary. That would be great if it can be put into
get_kernel_page_offset. But then it need parse kcore elf file again,
seems no better way.

> +	if (get_kernel_sym("page_offset_base") != 0) {
> +		for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
> +			if (phdr->p_type == PT_LOAD) {
> +				vaddr = phdr->p_vaddr & pud_mask;
> +				if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
> +					lowest_vaddr = vaddr;
> +			}
> +		}
> +		if (lowest_vaddr != 0)
> +			elf_info->page_offset = lowest_vaddr;
> +	}
> +
>  	/* Traverse through the Elf headers and find the region where
>  	 * _stext symbol is located in. That's where kernel is mapped */
> -	stext_sym = get_kernel_stext_sym();
> +	stext_sym = get_kernel_sym("_stext");
>  	for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>  		if (phdr->p_type == PT_LOAD) {
>  			unsigned long long saddr = phdr->p_vaddr;
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-08-18  4:59   ` Baoquan He
  0 siblings, 0 replies; 15+ messages in thread
From: Baoquan He @ 2016-08-18  4:59 UTC (permalink / raw)
  To: Thomas Garnier; +Cc: horms, kexec, keescook, kernel-hardening

On 08/17/16 at 09:47am, Thomas Garnier wrote:
> Multiple changes were made on KASLR (right now in linux-next). One of
> them is randomizing the virtual address of the physical mapping, vmalloc
> and vmemmap memory sections. It breaks kdump ability to read physical
> memory.
> 
> This change identifies if KASLR memories randomization is used by
> checking if the page_offset_base variable exists. It search for the
> correct PAGE_OFFSET value by looking at the loaded memory section and
> find the lowest aligned on PUD (the randomization level).
> 
> Related commits on linux-next:
>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET

Seems above two commits have been inside Linus's tree, while vmemmap
not yet.

> 
> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> ---
>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index bbc0f35..ab833d4 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>  	return -1;
>  }
>  
> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
> -static unsigned long long get_kernel_stext_sym(void)
> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
> +static unsigned long long get_kernel_sym(const char *symbol)
>  {
>  	const char *kallsyms = "/proc/kallsyms";
> -	const char *stext = "_stext";
>  	char sym[128];
>  	char line[128];
>  	FILE *fp;
> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>  	while(fgets(line, sizeof(line), fp) != NULL) {
>  		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>  			continue;
> -		if (strcmp(sym, stext) == 0) {
> -			dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
> +		if (strcmp(sym, symbol) == 0) {
> +			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>  			return vaddr;
>  		}
>  	}
>  
> -	fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
> +	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>  	return 0;
>  }
>  
> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  	off_t size;
>  	uint32_t elf_flags = 0;
>  	uint64_t stext_sym;
> +	const unsigned long long pud_mask = ~((1 << 30) - 1);
> +	unsigned long long vaddr, lowest_vaddr = 0;
>  
>  	if (elf_info->machine != EM_X86_64)
>  		return 0;
> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  
>  	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>  
> +	/* Search for the real PAGE_OFFSET when KASLR memory randomization
> +	 * is enabled */

Yeah, this is necessary. That would be great if it can be put into
get_kernel_page_offset. But then it need parse kcore elf file again,
seems no better way.

> +	if (get_kernel_sym("page_offset_base") != 0) {
> +		for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
> +			if (phdr->p_type == PT_LOAD) {
> +				vaddr = phdr->p_vaddr & pud_mask;
> +				if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
> +					lowest_vaddr = vaddr;
> +			}
> +		}
> +		if (lowest_vaddr != 0)
> +			elf_info->page_offset = lowest_vaddr;
> +	}
> +
>  	/* Traverse through the Elf headers and find the region where
>  	 * _stext symbol is located in. That's where kernel is mapped */
> -	stext_sym = get_kernel_stext_sym();
> +	stext_sym = get_kernel_sym("_stext");
>  	for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>  		if (phdr->p_type == PT_LOAD) {
>  			unsigned long long saddr = phdr->p_vaddr;
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-08-18  4:59   ` Baoquan He
@ 2016-08-23 15:38     ` Thomas Garnier
  -1 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-08-23 15:38 UTC (permalink / raw)
  To: Baoquan He; +Cc: kexec, Simon Horman, Kees Cook, Kernel Hardening

On Wed, Aug 17, 2016 at 9:59 PM, Baoquan He <bhe@redhat.com> wrote:
> On 08/17/16 at 09:47am, Thomas Garnier wrote:
>> Multiple changes were made on KASLR (right now in linux-next). One of
>> them is randomizing the virtual address of the physical mapping, vmalloc
>> and vmemmap memory sections. It breaks kdump ability to read physical
>> memory.
>>
>> This change identifies if KASLR memories randomization is used by
>> checking if the page_offset_base variable exists. It search for the
>> correct PAGE_OFFSET value by looking at the loaded memory section and
>> find the lowest aligned on PUD (the randomization level).
>>
>> Related commits on linux-next:
>>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
>
> Seems above two commits have been inside Linus's tree, while vmemmap
> not yet.
>
>>
>> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> ---
>>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>>  1 file changed, 22 insertions(+), 7 deletions(-)
>>
>> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
>> index bbc0f35..ab833d4 100644
>> --- a/kexec/arch/i386/crashdump-x86.c
>> +++ b/kexec/arch/i386/crashdump-x86.c
>> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>>       return -1;
>>  }
>>
>> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
>> -static unsigned long long get_kernel_stext_sym(void)
>> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
>> +static unsigned long long get_kernel_sym(const char *symbol)
>>  {
>>       const char *kallsyms = "/proc/kallsyms";
>> -     const char *stext = "_stext";
>>       char sym[128];
>>       char line[128];
>>       FILE *fp;
>> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>>       while(fgets(line, sizeof(line), fp) != NULL) {
>>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>>                       continue;
>> -             if (strcmp(sym, stext) == 0) {
>> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
>> +             if (strcmp(sym, symbol) == 0) {
>> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>>                       return vaddr;
>>               }
>>       }
>>
>> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
>> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>>       return 0;
>>  }
>>
>> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>       off_t size;
>>       uint32_t elf_flags = 0;
>>       uint64_t stext_sym;
>> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
>> +     unsigned long long vaddr, lowest_vaddr = 0;
>>
>>       if (elf_info->machine != EM_X86_64)
>>               return 0;
>> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>
>>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>>
>> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
>> +      * is enabled */
>
> Yeah, this is necessary. That would be great if it can be put into
> get_kernel_page_offset. But then it need parse kcore elf file again,
> seems no better way.
>

I agree.

Simon: Do you have any comments?

>> +     if (get_kernel_sym("page_offset_base") != 0) {
>> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
>> +                     if (phdr->p_type == PT_LOAD) {
>> +                             vaddr = phdr->p_vaddr & pud_mask;
>> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
>> +                                     lowest_vaddr = vaddr;
>> +                     }
>> +             }
>> +             if (lowest_vaddr != 0)
>> +                     elf_info->page_offset = lowest_vaddr;
>> +     }
>> +
>>       /* Traverse through the Elf headers and find the region where
>>        * _stext symbol is located in. That's where kernel is mapped */
>> -     stext_sym = get_kernel_stext_sym();
>> +     stext_sym = get_kernel_sym("_stext");
>>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>>               if (phdr->p_type == PT_LOAD) {
>>                       unsigned long long saddr = phdr->p_vaddr;
>> --
>> 2.8.0.rc3.226.g39d4020
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-08-23 15:38     ` Thomas Garnier
  0 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-08-23 15:38 UTC (permalink / raw)
  To: Baoquan He; +Cc: Simon Horman, kexec, Kees Cook, Kernel Hardening

On Wed, Aug 17, 2016 at 9:59 PM, Baoquan He <bhe@redhat.com> wrote:
> On 08/17/16 at 09:47am, Thomas Garnier wrote:
>> Multiple changes were made on KASLR (right now in linux-next). One of
>> them is randomizing the virtual address of the physical mapping, vmalloc
>> and vmemmap memory sections. It breaks kdump ability to read physical
>> memory.
>>
>> This change identifies if KASLR memories randomization is used by
>> checking if the page_offset_base variable exists. It search for the
>> correct PAGE_OFFSET value by looking at the loaded memory section and
>> find the lowest aligned on PUD (the randomization level).
>>
>> Related commits on linux-next:
>>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
>
> Seems above two commits have been inside Linus's tree, while vmemmap
> not yet.
>
>>
>> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> ---
>>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>>  1 file changed, 22 insertions(+), 7 deletions(-)
>>
>> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
>> index bbc0f35..ab833d4 100644
>> --- a/kexec/arch/i386/crashdump-x86.c
>> +++ b/kexec/arch/i386/crashdump-x86.c
>> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>>       return -1;
>>  }
>>
>> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
>> -static unsigned long long get_kernel_stext_sym(void)
>> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
>> +static unsigned long long get_kernel_sym(const char *symbol)
>>  {
>>       const char *kallsyms = "/proc/kallsyms";
>> -     const char *stext = "_stext";
>>       char sym[128];
>>       char line[128];
>>       FILE *fp;
>> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>>       while(fgets(line, sizeof(line), fp) != NULL) {
>>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>>                       continue;
>> -             if (strcmp(sym, stext) == 0) {
>> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
>> +             if (strcmp(sym, symbol) == 0) {
>> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>>                       return vaddr;
>>               }
>>       }
>>
>> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
>> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>>       return 0;
>>  }
>>
>> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>       off_t size;
>>       uint32_t elf_flags = 0;
>>       uint64_t stext_sym;
>> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
>> +     unsigned long long vaddr, lowest_vaddr = 0;
>>
>>       if (elf_info->machine != EM_X86_64)
>>               return 0;
>> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>
>>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>>
>> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
>> +      * is enabled */
>
> Yeah, this is necessary. That would be great if it can be put into
> get_kernel_page_offset. But then it need parse kcore elf file again,
> seems no better way.
>

I agree.

Simon: Do you have any comments?

>> +     if (get_kernel_sym("page_offset_base") != 0) {
>> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
>> +                     if (phdr->p_type == PT_LOAD) {
>> +                             vaddr = phdr->p_vaddr & pud_mask;
>> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
>> +                                     lowest_vaddr = vaddr;
>> +                     }
>> +             }
>> +             if (lowest_vaddr != 0)
>> +                     elf_info->page_offset = lowest_vaddr;
>> +     }
>> +
>>       /* Traverse through the Elf headers and find the region where
>>        * _stext symbol is located in. That's where kernel is mapped */
>> -     stext_sym = get_kernel_stext_sym();
>> +     stext_sym = get_kernel_sym("_stext");
>>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>>               if (phdr->p_type == PT_LOAD) {
>>                       unsigned long long saddr = phdr->p_vaddr;
>> --
>> 2.8.0.rc3.226.g39d4020
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-08-17 16:47 ` Thomas Garnier
@ 2016-09-22  8:41   ` Dave Young
  -1 siblings, 0 replies; 15+ messages in thread
From: Dave Young @ 2016-09-22  8:41 UTC (permalink / raw)
  To: Thomas Garnier; +Cc: kexec, horms, keescook, kernel-hardening

Hi, Thomas

On 08/17/16 at 09:47am, Thomas Garnier wrote:
> Multiple changes were made on KASLR (right now in linux-next). One of
> them is randomizing the virtual address of the physical mapping, vmalloc
> and vmemmap memory sections. It breaks kdump ability to read physical
> memory.

What is the user visible behavior without this patch? Could you add more
in the patch log?

During my testing seems with or without this patch kdump kernel boot
both fine.

My kernel config options is like below, is it enough to test this patch?
CONFIG_RANDOMIZE_BASE=y
CONFIG_X86_NEED_RELOCS=y
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_RANDOMIZE_MEMORY=y
CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0

> 
> This change identifies if KASLR memories randomization is used by
> checking if the page_offset_base variable exists. It search for the
> correct PAGE_OFFSET value by looking at the loaded memory section and
> find the lowest aligned on PUD (the randomization level).
> 
> Related commits on linux-next:
>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
> 
> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> ---
>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index bbc0f35..ab833d4 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>  	return -1;
>  }
>  
> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
> -static unsigned long long get_kernel_stext_sym(void)
> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
> +static unsigned long long get_kernel_sym(const char *symbol)

It sounds better to split this to another patch.

>  {
>  	const char *kallsyms = "/proc/kallsyms";
> -	const char *stext = "_stext";
>  	char sym[128];
>  	char line[128];
>  	FILE *fp;
> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>  	while(fgets(line, sizeof(line), fp) != NULL) {
>  		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>  			continue;
> -		if (strcmp(sym, stext) == 0) {
> -			dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
> +		if (strcmp(sym, symbol) == 0) {
> +			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>  			return vaddr;
>  		}
>  	}
>  
> -	fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
> +	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>  	return 0;
>  }
>  
> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  	off_t size;
>  	uint32_t elf_flags = 0;
>  	uint64_t stext_sym;
> +	const unsigned long long pud_mask = ~((1 << 30) - 1);
> +	unsigned long long vaddr, lowest_vaddr = 0;
>  
>  	if (elf_info->machine != EM_X86_64)
>  		return 0;
> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  
>  	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>  
> +	/* Search for the real PAGE_OFFSET when KASLR memory randomization
> +	 * is enabled */
> +	if (get_kernel_sym("page_offset_base") != 0) {
> +		for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
> +			if (phdr->p_type == PT_LOAD) {
> +				vaddr = phdr->p_vaddr & pud_mask;
> +				if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
> +					lowest_vaddr = vaddr;
> +			}
> +		}
> +		if (lowest_vaddr != 0)
> +			elf_info->page_offset = lowest_vaddr;
> +	}
> +
>  	/* Traverse through the Elf headers and find the region where
>  	 * _stext symbol is located in. That's where kernel is mapped */
> -	stext_sym = get_kernel_stext_sym();
> +	stext_sym = get_kernel_sym("_stext");
>  	for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>  		if (phdr->p_type == PT_LOAD) {
>  			unsigned long long saddr = phdr->p_vaddr;
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

Thanks
Dave

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-09-22  8:41   ` Dave Young
  0 siblings, 0 replies; 15+ messages in thread
From: Dave Young @ 2016-09-22  8:41 UTC (permalink / raw)
  To: Thomas Garnier; +Cc: horms, kexec, keescook, kernel-hardening

Hi, Thomas

On 08/17/16 at 09:47am, Thomas Garnier wrote:
> Multiple changes were made on KASLR (right now in linux-next). One of
> them is randomizing the virtual address of the physical mapping, vmalloc
> and vmemmap memory sections. It breaks kdump ability to read physical
> memory.

What is the user visible behavior without this patch? Could you add more
in the patch log?

During my testing seems with or without this patch kdump kernel boot
both fine.

My kernel config options is like below, is it enough to test this patch?
CONFIG_RANDOMIZE_BASE=y
CONFIG_X86_NEED_RELOCS=y
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_RANDOMIZE_MEMORY=y
CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0

> 
> This change identifies if KASLR memories randomization is used by
> checking if the page_offset_base variable exists. It search for the
> correct PAGE_OFFSET value by looking at the loaded memory section and
> find the lowest aligned on PUD (the randomization level).
> 
> Related commits on linux-next:
>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
> 
> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> ---
>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index bbc0f35..ab833d4 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>  	return -1;
>  }
>  
> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
> -static unsigned long long get_kernel_stext_sym(void)
> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
> +static unsigned long long get_kernel_sym(const char *symbol)

It sounds better to split this to another patch.

>  {
>  	const char *kallsyms = "/proc/kallsyms";
> -	const char *stext = "_stext";
>  	char sym[128];
>  	char line[128];
>  	FILE *fp;
> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>  	while(fgets(line, sizeof(line), fp) != NULL) {
>  		if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>  			continue;
> -		if (strcmp(sym, stext) == 0) {
> -			dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
> +		if (strcmp(sym, symbol) == 0) {
> +			dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>  			return vaddr;
>  		}
>  	}
>  
> -	fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
> +	fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>  	return 0;
>  }
>  
> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  	off_t size;
>  	uint32_t elf_flags = 0;
>  	uint64_t stext_sym;
> +	const unsigned long long pud_mask = ~((1 << 30) - 1);
> +	unsigned long long vaddr, lowest_vaddr = 0;
>  
>  	if (elf_info->machine != EM_X86_64)
>  		return 0;
> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>  
>  	end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>  
> +	/* Search for the real PAGE_OFFSET when KASLR memory randomization
> +	 * is enabled */
> +	if (get_kernel_sym("page_offset_base") != 0) {
> +		for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
> +			if (phdr->p_type == PT_LOAD) {
> +				vaddr = phdr->p_vaddr & pud_mask;
> +				if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
> +					lowest_vaddr = vaddr;
> +			}
> +		}
> +		if (lowest_vaddr != 0)
> +			elf_info->page_offset = lowest_vaddr;
> +	}
> +
>  	/* Traverse through the Elf headers and find the region where
>  	 * _stext symbol is located in. That's where kernel is mapped */
> -	stext_sym = get_kernel_stext_sym();
> +	stext_sym = get_kernel_sym("_stext");
>  	for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>  		if (phdr->p_type == PT_LOAD) {
>  			unsigned long long saddr = phdr->p_vaddr;
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

Thanks
Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-09-22  8:41   ` Dave Young
@ 2016-09-23 16:33     ` Thomas Garnier
  -1 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-09-23 16:33 UTC (permalink / raw)
  To: Dave Young; +Cc: kexec, Simon Horman, Kees Cook, Kernel Hardening

On Thu, Sep 22, 2016 at 1:41 AM, Dave Young <dyoung@redhat.com> wrote:
> Hi, Thomas
>
> On 08/17/16 at 09:47am, Thomas Garnier wrote:
>> Multiple changes were made on KASLR (right now in linux-next). One of
>> them is randomizing the virtual address of the physical mapping, vmalloc
>> and vmemmap memory sections. It breaks kdump ability to read physical
>> memory.
>
> What is the user visible behavior without this patch? Could you add more
> in the patch log?
>
> During my testing seems with or without this patch kdump kernel boot
> both fine.

Without this patch, you can't access memory on the generated crash dumps.

>
> My kernel config options is like below, is it enough to test this patch?
> CONFIG_RANDOMIZE_BASE=y
> CONFIG_X86_NEED_RELOCS=y
> CONFIG_PHYSICAL_ALIGN=0x1000000
> CONFIG_RANDOMIZE_MEMORY=y
> CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0
>

Should be good enough.

>>
>> This change identifies if KASLR memories randomization is used by
>> checking if the page_offset_base variable exists. It search for the
>> correct PAGE_OFFSET value by looking at the loaded memory section and
>> find the lowest aligned on PUD (the randomization level).
>>
>> Related commits on linux-next:
>>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
>>
>> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> ---
>>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>>  1 file changed, 22 insertions(+), 7 deletions(-)
>>
>> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
>> index bbc0f35..ab833d4 100644
>> --- a/kexec/arch/i386/crashdump-x86.c
>> +++ b/kexec/arch/i386/crashdump-x86.c
>> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>>       return -1;
>>  }
>>
>> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
>> -static unsigned long long get_kernel_stext_sym(void)
>> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
>> +static unsigned long long get_kernel_sym(const char *symbol)
>
> It sounds better to split this to another patch.
>

Why not, that's a very small change though.

>>  {
>>       const char *kallsyms = "/proc/kallsyms";
>> -     const char *stext = "_stext";
>>       char sym[128];
>>       char line[128];
>>       FILE *fp;
>> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>>       while(fgets(line, sizeof(line), fp) != NULL) {
>>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>>                       continue;
>> -             if (strcmp(sym, stext) == 0) {
>> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
>> +             if (strcmp(sym, symbol) == 0) {
>> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>>                       return vaddr;
>>               }
>>       }
>>
>> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
>> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>>       return 0;
>>  }
>>
>> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>       off_t size;
>>       uint32_t elf_flags = 0;
>>       uint64_t stext_sym;
>> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
>> +     unsigned long long vaddr, lowest_vaddr = 0;
>>
>>       if (elf_info->machine != EM_X86_64)
>>               return 0;
>> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>
>>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>>
>> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
>> +      * is enabled */
>> +     if (get_kernel_sym("page_offset_base") != 0) {
>> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
>> +                     if (phdr->p_type == PT_LOAD) {
>> +                             vaddr = phdr->p_vaddr & pud_mask;
>> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
>> +                                     lowest_vaddr = vaddr;
>> +                     }
>> +             }
>> +             if (lowest_vaddr != 0)
>> +                     elf_info->page_offset = lowest_vaddr;
>> +     }
>> +
>>       /* Traverse through the Elf headers and find the region where
>>        * _stext symbol is located in. That's where kernel is mapped */
>> -     stext_sym = get_kernel_stext_sym();
>> +     stext_sym = get_kernel_sym("_stext");
>>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>>               if (phdr->p_type == PT_LOAD) {
>>                       unsigned long long saddr = phdr->p_vaddr;
>> --
>> 2.8.0.rc3.226.g39d4020
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
>
> Thanks
> Dave

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-09-23 16:33     ` Thomas Garnier
  0 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-09-23 16:33 UTC (permalink / raw)
  To: Dave Young; +Cc: Simon Horman, kexec, Kees Cook, Kernel Hardening

On Thu, Sep 22, 2016 at 1:41 AM, Dave Young <dyoung@redhat.com> wrote:
> Hi, Thomas
>
> On 08/17/16 at 09:47am, Thomas Garnier wrote:
>> Multiple changes were made on KASLR (right now in linux-next). One of
>> them is randomizing the virtual address of the physical mapping, vmalloc
>> and vmemmap memory sections. It breaks kdump ability to read physical
>> memory.
>
> What is the user visible behavior without this patch? Could you add more
> in the patch log?
>
> During my testing seems with or without this patch kdump kernel boot
> both fine.

Without this patch, you can't access memory on the generated crash dumps.

>
> My kernel config options is like below, is it enough to test this patch?
> CONFIG_RANDOMIZE_BASE=y
> CONFIG_X86_NEED_RELOCS=y
> CONFIG_PHYSICAL_ALIGN=0x1000000
> CONFIG_RANDOMIZE_MEMORY=y
> CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0
>

Should be good enough.

>>
>> This change identifies if KASLR memories randomization is used by
>> checking if the page_offset_base variable exists. It search for the
>> correct PAGE_OFFSET value by looking at the loaded memory section and
>> find the lowest aligned on PUD (the randomization level).
>>
>> Related commits on linux-next:
>>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
>>
>> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> ---
>>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>>  1 file changed, 22 insertions(+), 7 deletions(-)
>>
>> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
>> index bbc0f35..ab833d4 100644
>> --- a/kexec/arch/i386/crashdump-x86.c
>> +++ b/kexec/arch/i386/crashdump-x86.c
>> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>>       return -1;
>>  }
>>
>> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
>> -static unsigned long long get_kernel_stext_sym(void)
>> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
>> +static unsigned long long get_kernel_sym(const char *symbol)
>
> It sounds better to split this to another patch.
>

Why not, that's a very small change though.

>>  {
>>       const char *kallsyms = "/proc/kallsyms";
>> -     const char *stext = "_stext";
>>       char sym[128];
>>       char line[128];
>>       FILE *fp;
>> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>>       while(fgets(line, sizeof(line), fp) != NULL) {
>>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>>                       continue;
>> -             if (strcmp(sym, stext) == 0) {
>> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
>> +             if (strcmp(sym, symbol) == 0) {
>> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>>                       return vaddr;
>>               }
>>       }
>>
>> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
>> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>>       return 0;
>>  }
>>
>> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>       off_t size;
>>       uint32_t elf_flags = 0;
>>       uint64_t stext_sym;
>> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
>> +     unsigned long long vaddr, lowest_vaddr = 0;
>>
>>       if (elf_info->machine != EM_X86_64)
>>               return 0;
>> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>>
>>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>>
>> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
>> +      * is enabled */
>> +     if (get_kernel_sym("page_offset_base") != 0) {
>> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
>> +                     if (phdr->p_type == PT_LOAD) {
>> +                             vaddr = phdr->p_vaddr & pud_mask;
>> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
>> +                                     lowest_vaddr = vaddr;
>> +                     }
>> +             }
>> +             if (lowest_vaddr != 0)
>> +                     elf_info->page_offset = lowest_vaddr;
>> +     }
>> +
>>       /* Traverse through the Elf headers and find the region where
>>        * _stext symbol is located in. That's where kernel is mapped */
>> -     stext_sym = get_kernel_stext_sym();
>> +     stext_sym = get_kernel_sym("_stext");
>>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>>               if (phdr->p_type == PT_LOAD) {
>>                       unsigned long long saddr = phdr->p_vaddr;
>> --
>> 2.8.0.rc3.226.g39d4020
>>
>>
>> _______________________________________________
>> kexec mailing list
>> kexec@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
>
> Thanks
> Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-09-23 16:33     ` Thomas Garnier
@ 2016-09-26 12:52       ` Dave Young
  -1 siblings, 0 replies; 15+ messages in thread
From: Dave Young @ 2016-09-26 12:52 UTC (permalink / raw)
  To: Thomas Garnier; +Cc: kexec, Simon Horman, Kees Cook, Kernel Hardening

On 09/23/16 at 09:33am, Thomas Garnier wrote:
> On Thu, Sep 22, 2016 at 1:41 AM, Dave Young <dyoung@redhat.com> wrote:
> > Hi, Thomas
> >
> > On 08/17/16 at 09:47am, Thomas Garnier wrote:
> >> Multiple changes were made on KASLR (right now in linux-next). One of
> >> them is randomizing the virtual address of the physical mapping, vmalloc
> >> and vmemmap memory sections. It breaks kdump ability to read physical
> >> memory.
> >
> > What is the user visible behavior without this patch? Could you add more
> > in the patch log?
> >
> > During my testing seems with or without this patch kdump kernel boot
> > both fine.
> 
> Without this patch, you can't access memory on the generated crash dumps.

Ok, makedumpfile saving /proc/vmcore works fine without this patch, but
gdb will give error when accessing the old memory.

> 
> >
> > My kernel config options is like below, is it enough to test this patch?
> > CONFIG_RANDOMIZE_BASE=y
> > CONFIG_X86_NEED_RELOCS=y
> > CONFIG_PHYSICAL_ALIGN=0x1000000
> > CONFIG_RANDOMIZE_MEMORY=y
> > CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0
> >
> 
> Should be good enough.
> 
> >>
> >> This change identifies if KASLR memories randomization is used by
> >> checking if the page_offset_base variable exists. It search for the
> >> correct PAGE_OFFSET value by looking at the loaded memory section and
> >> find the lowest aligned on PUD (the randomization level).
> >>
> >> Related commits on linux-next:
> >>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
> >>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
> >>
> >> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> >> ---
> >>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
> >>  1 file changed, 22 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> >> index bbc0f35..ab833d4 100644
> >> --- a/kexec/arch/i386/crashdump-x86.c
> >> +++ b/kexec/arch/i386/crashdump-x86.c
> >> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
> >>       return -1;
> >>  }
> >>
> >> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
> >> -static unsigned long long get_kernel_stext_sym(void)
> >> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
> >> +static unsigned long long get_kernel_sym(const char *symbol)
> >
> > It sounds better to split this to another patch.
> >
> 
> Why not, that's a very small change though.
> 
> >>  {
> >>       const char *kallsyms = "/proc/kallsyms";
> >> -     const char *stext = "_stext";
> >>       char sym[128];
> >>       char line[128];
> >>       FILE *fp;
> >> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
> >>       while(fgets(line, sizeof(line), fp) != NULL) {
> >>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
> >>                       continue;
> >> -             if (strcmp(sym, stext) == 0) {
> >> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
> >> +             if (strcmp(sym, symbol) == 0) {
> >> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
> >>                       return vaddr;
> >>               }
> >>       }
> >>
> >> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
> >> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);

For page_offset_base it should only print the error message when
the kernel supports it.


> >>       return 0;
> >>  }
> >>
> >> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
> >>       off_t size;
> >>       uint32_t elf_flags = 0;
> >>       uint64_t stext_sym;
> >> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
> >> +     unsigned long long vaddr, lowest_vaddr = 0;
> >>
> >>       if (elf_info->machine != EM_X86_64)
> >>               return 0;
> >> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
> >>
> >>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
> >>
> >> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
> >> +      * is enabled */
> >> +     if (get_kernel_sym("page_offset_base") != 0) {
> >> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
> >> +                     if (phdr->p_type == PT_LOAD) {
> >> +                             vaddr = phdr->p_vaddr & pud_mask;
> >> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
> >> +                                     lowest_vaddr = vaddr;
> >> +                     }
> >> +             }
> >> +             if (lowest_vaddr != 0)
> >> +                     elf_info->page_offset = lowest_vaddr;
> >> +     }
> >> +
> >>       /* Traverse through the Elf headers and find the region where
> >>        * _stext symbol is located in. That's where kernel is mapped */
> >> -     stext_sym = get_kernel_stext_sym();
> >> +     stext_sym = get_kernel_sym("_stext");
> >>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
> >>               if (phdr->p_type == PT_LOAD) {
> >>                       unsigned long long saddr = phdr->p_vaddr;
> >> --

Thanks
Dave

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-09-26 12:52       ` Dave Young
  0 siblings, 0 replies; 15+ messages in thread
From: Dave Young @ 2016-09-26 12:52 UTC (permalink / raw)
  To: Thomas Garnier; +Cc: Simon Horman, kexec, Kees Cook, Kernel Hardening

On 09/23/16 at 09:33am, Thomas Garnier wrote:
> On Thu, Sep 22, 2016 at 1:41 AM, Dave Young <dyoung@redhat.com> wrote:
> > Hi, Thomas
> >
> > On 08/17/16 at 09:47am, Thomas Garnier wrote:
> >> Multiple changes were made on KASLR (right now in linux-next). One of
> >> them is randomizing the virtual address of the physical mapping, vmalloc
> >> and vmemmap memory sections. It breaks kdump ability to read physical
> >> memory.
> >
> > What is the user visible behavior without this patch? Could you add more
> > in the patch log?
> >
> > During my testing seems with or without this patch kdump kernel boot
> > both fine.
> 
> Without this patch, you can't access memory on the generated crash dumps.

Ok, makedumpfile saving /proc/vmcore works fine without this patch, but
gdb will give error when accessing the old memory.

> 
> >
> > My kernel config options is like below, is it enough to test this patch?
> > CONFIG_RANDOMIZE_BASE=y
> > CONFIG_X86_NEED_RELOCS=y
> > CONFIG_PHYSICAL_ALIGN=0x1000000
> > CONFIG_RANDOMIZE_MEMORY=y
> > CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0
> >
> 
> Should be good enough.
> 
> >>
> >> This change identifies if KASLR memories randomization is used by
> >> checking if the page_offset_base variable exists. It search for the
> >> correct PAGE_OFFSET value by looking at the loaded memory section and
> >> find the lowest aligned on PUD (the randomization level).
> >>
> >> Related commits on linux-next:
> >>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
> >>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
> >>
> >> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> >> ---
> >>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
> >>  1 file changed, 22 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> >> index bbc0f35..ab833d4 100644
> >> --- a/kexec/arch/i386/crashdump-x86.c
> >> +++ b/kexec/arch/i386/crashdump-x86.c
> >> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
> >>       return -1;
> >>  }
> >>
> >> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
> >> -static unsigned long long get_kernel_stext_sym(void)
> >> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
> >> +static unsigned long long get_kernel_sym(const char *symbol)
> >
> > It sounds better to split this to another patch.
> >
> 
> Why not, that's a very small change though.
> 
> >>  {
> >>       const char *kallsyms = "/proc/kallsyms";
> >> -     const char *stext = "_stext";
> >>       char sym[128];
> >>       char line[128];
> >>       FILE *fp;
> >> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
> >>       while(fgets(line, sizeof(line), fp) != NULL) {
> >>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
> >>                       continue;
> >> -             if (strcmp(sym, stext) == 0) {
> >> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
> >> +             if (strcmp(sym, symbol) == 0) {
> >> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
> >>                       return vaddr;
> >>               }
> >>       }
> >>
> >> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
> >> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);

For page_offset_base it should only print the error message when
the kernel supports it.


> >>       return 0;
> >>  }
> >>
> >> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
> >>       off_t size;
> >>       uint32_t elf_flags = 0;
> >>       uint64_t stext_sym;
> >> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
> >> +     unsigned long long vaddr, lowest_vaddr = 0;
> >>
> >>       if (elf_info->machine != EM_X86_64)
> >>               return 0;
> >> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
> >>
> >>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
> >>
> >> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
> >> +      * is enabled */
> >> +     if (get_kernel_sym("page_offset_base") != 0) {
> >> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
> >> +                     if (phdr->p_type == PT_LOAD) {
> >> +                             vaddr = phdr->p_vaddr & pud_mask;
> >> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
> >> +                                     lowest_vaddr = vaddr;
> >> +                     }
> >> +             }
> >> +             if (lowest_vaddr != 0)
> >> +                     elf_info->page_offset = lowest_vaddr;
> >> +     }
> >> +
> >>       /* Traverse through the Elf headers and find the region where
> >>        * _stext symbol is located in. That's where kernel is mapped */
> >> -     stext_sym = get_kernel_stext_sym();
> >> +     stext_sym = get_kernel_sym("_stext");
> >>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
> >>               if (phdr->p_type == PT_LOAD) {
> >>                       unsigned long long saddr = phdr->p_vaddr;
> >> --

Thanks
Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-09-26 12:52       ` Dave Young
@ 2016-09-26 16:53         ` Thomas Garnier
  -1 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-09-26 16:53 UTC (permalink / raw)
  To: Dave Young; +Cc: kexec, Simon Horman, Kees Cook, Kernel Hardening

On Mon, Sep 26, 2016 at 5:52 AM, Dave Young <dyoung@redhat.com> wrote:
> On 09/23/16 at 09:33am, Thomas Garnier wrote:
>> On Thu, Sep 22, 2016 at 1:41 AM, Dave Young <dyoung@redhat.com> wrote:
>> > Hi, Thomas
>> >
>> > On 08/17/16 at 09:47am, Thomas Garnier wrote:
>> >> Multiple changes were made on KASLR (right now in linux-next). One of
>> >> them is randomizing the virtual address of the physical mapping, vmalloc
>> >> and vmemmap memory sections. It breaks kdump ability to read physical
>> >> memory.
>> >
>> > What is the user visible behavior without this patch? Could you add more
>> > in the patch log?
>> >
>> > During my testing seems with or without this patch kdump kernel boot
>> > both fine.
>>
>> Without this patch, you can't access memory on the generated crash dumps.
>
> Ok, makedumpfile saving /proc/vmcore works fine without this patch, but
> gdb will give error when accessing the old memory.
>

Yes, that's correct.

>>
>> >
>> > My kernel config options is like below, is it enough to test this patch?
>> > CONFIG_RANDOMIZE_BASE=y
>> > CONFIG_X86_NEED_RELOCS=y
>> > CONFIG_PHYSICAL_ALIGN=0x1000000
>> > CONFIG_RANDOMIZE_MEMORY=y
>> > CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0
>> >
>>
>> Should be good enough.
>>
>> >>
>> >> This change identifies if KASLR memories randomization is used by
>> >> checking if the page_offset_base variable exists. It search for the
>> >> correct PAGE_OFFSET value by looking at the loaded memory section and
>> >> find the lowest aligned on PUD (the randomization level).
>> >>
>> >> Related commits on linux-next:
>> >>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>> >>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
>> >>
>> >> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> >> ---
>> >>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>> >>  1 file changed, 22 insertions(+), 7 deletions(-)
>> >>
>> >> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
>> >> index bbc0f35..ab833d4 100644
>> >> --- a/kexec/arch/i386/crashdump-x86.c
>> >> +++ b/kexec/arch/i386/crashdump-x86.c
>> >> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>> >>       return -1;
>> >>  }
>> >>
>> >> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
>> >> -static unsigned long long get_kernel_stext_sym(void)
>> >> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
>> >> +static unsigned long long get_kernel_sym(const char *symbol)
>> >
>> > It sounds better to split this to another patch.
>> >
>>
>> Why not, that's a very small change though.
>>
>> >>  {
>> >>       const char *kallsyms = "/proc/kallsyms";
>> >> -     const char *stext = "_stext";
>> >>       char sym[128];
>> >>       char line[128];
>> >>       FILE *fp;
>> >> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>> >>       while(fgets(line, sizeof(line), fp) != NULL) {
>> >>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>> >>                       continue;
>> >> -             if (strcmp(sym, stext) == 0) {
>> >> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
>> >> +             if (strcmp(sym, symbol) == 0) {
>> >> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>> >>                       return vaddr;
>> >>               }
>> >>       }
>> >>
>> >> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
>> >> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>
> For page_offset_base it should only print the error message when
> the kernel supports it.
>

I agree that would be better. How do we know if the kernel supports it though?

I can't think of a reliable way to detect if KASLR is enabled. I think
Kees told me there was no official way on purpose.

>
>> >>       return 0;
>> >>  }
>> >>
>> >> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>> >>       off_t size;
>> >>       uint32_t elf_flags = 0;
>> >>       uint64_t stext_sym;
>> >> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
>> >> +     unsigned long long vaddr, lowest_vaddr = 0;
>> >>
>> >>       if (elf_info->machine != EM_X86_64)
>> >>               return 0;
>> >> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>> >>
>> >>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>> >>
>> >> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
>> >> +      * is enabled */
>> >> +     if (get_kernel_sym("page_offset_base") != 0) {
>> >> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
>> >> +                     if (phdr->p_type == PT_LOAD) {
>> >> +                             vaddr = phdr->p_vaddr & pud_mask;
>> >> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
>> >> +                                     lowest_vaddr = vaddr;
>> >> +                     }
>> >> +             }
>> >> +             if (lowest_vaddr != 0)
>> >> +                     elf_info->page_offset = lowest_vaddr;
>> >> +     }
>> >> +
>> >>       /* Traverse through the Elf headers and find the region where
>> >>        * _stext symbol is located in. That's where kernel is mapped */
>> >> -     stext_sym = get_kernel_stext_sym();
>> >> +     stext_sym = get_kernel_sym("_stext");
>> >>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>> >>               if (phdr->p_type == PT_LOAD) {
>> >>                       unsigned long long saddr = phdr->p_vaddr;
>> >> --
>
> Thanks
> Dave

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
@ 2016-09-26 16:53         ` Thomas Garnier
  0 siblings, 0 replies; 15+ messages in thread
From: Thomas Garnier @ 2016-09-26 16:53 UTC (permalink / raw)
  To: Dave Young; +Cc: Simon Horman, kexec, Kees Cook, Kernel Hardening

On Mon, Sep 26, 2016 at 5:52 AM, Dave Young <dyoung@redhat.com> wrote:
> On 09/23/16 at 09:33am, Thomas Garnier wrote:
>> On Thu, Sep 22, 2016 at 1:41 AM, Dave Young <dyoung@redhat.com> wrote:
>> > Hi, Thomas
>> >
>> > On 08/17/16 at 09:47am, Thomas Garnier wrote:
>> >> Multiple changes were made on KASLR (right now in linux-next). One of
>> >> them is randomizing the virtual address of the physical mapping, vmalloc
>> >> and vmemmap memory sections. It breaks kdump ability to read physical
>> >> memory.
>> >
>> > What is the user visible behavior without this patch? Could you add more
>> > in the patch log?
>> >
>> > During my testing seems with or without this patch kdump kernel boot
>> > both fine.
>>
>> Without this patch, you can't access memory on the generated crash dumps.
>
> Ok, makedumpfile saving /proc/vmcore works fine without this patch, but
> gdb will give error when accessing the old memory.
>

Yes, that's correct.

>>
>> >
>> > My kernel config options is like below, is it enough to test this patch?
>> > CONFIG_RANDOMIZE_BASE=y
>> > CONFIG_X86_NEED_RELOCS=y
>> > CONFIG_PHYSICAL_ALIGN=0x1000000
>> > CONFIG_RANDOMIZE_MEMORY=y
>> > CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING=0x0
>> >
>>
>> Should be good enough.
>>
>> >>
>> >> This change identifies if KASLR memories randomization is used by
>> >> checking if the page_offset_base variable exists. It search for the
>> >> correct PAGE_OFFSET value by looking at the loaded memory section and
>> >> find the lowest aligned on PUD (the randomization level).
>> >>
>> >> Related commits on linux-next:
>> >>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>> >>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
>> >>
>> >> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> >> ---
>> >>  kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
>> >>  1 file changed, 22 insertions(+), 7 deletions(-)
>> >>
>> >> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
>> >> index bbc0f35..ab833d4 100644
>> >> --- a/kexec/arch/i386/crashdump-x86.c
>> >> +++ b/kexec/arch/i386/crashdump-x86.c
>> >> @@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
>> >>       return -1;
>> >>  }
>> >>
>> >> -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
>> >> -static unsigned long long get_kernel_stext_sym(void)
>> >> +/* Retrieve kernel symbol virtual address from /proc/kallsyms */
>> >> +static unsigned long long get_kernel_sym(const char *symbol)
>> >
>> > It sounds better to split this to another patch.
>> >
>>
>> Why not, that's a very small change though.
>>
>> >>  {
>> >>       const char *kallsyms = "/proc/kallsyms";
>> >> -     const char *stext = "_stext";
>> >>       char sym[128];
>> >>       char line[128];
>> >>       FILE *fp;
>> >> @@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
>> >>       while(fgets(line, sizeof(line), fp) != NULL) {
>> >>               if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
>> >>                       continue;
>> >> -             if (strcmp(sym, stext) == 0) {
>> >> -                     dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
>> >> +             if (strcmp(sym, symbol) == 0) {
>> >> +                     dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
>> >>                       return vaddr;
>> >>               }
>> >>       }
>> >>
>> >> -     fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
>> >> +     fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
>
> For page_offset_base it should only print the error message when
> the kernel supports it.
>

I agree that would be better. How do we know if the kernel supports it though?

I can't think of a reliable way to detect if KASLR is enabled. I think
Kees told me there was no official way on purpose.

>
>> >>       return 0;
>> >>  }
>> >>
>> >> @@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>> >>       off_t size;
>> >>       uint32_t elf_flags = 0;
>> >>       uint64_t stext_sym;
>> >> +     const unsigned long long pud_mask = ~((1 << 30) - 1);
>> >> +     unsigned long long vaddr, lowest_vaddr = 0;
>> >>
>> >>       if (elf_info->machine != EM_X86_64)
>> >>               return 0;
>> >> @@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
>> >>
>> >>       end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
>> >>
>> >> +     /* Search for the real PAGE_OFFSET when KASLR memory randomization
>> >> +      * is enabled */
>> >> +     if (get_kernel_sym("page_offset_base") != 0) {
>> >> +             for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
>> >> +                     if (phdr->p_type == PT_LOAD) {
>> >> +                             vaddr = phdr->p_vaddr & pud_mask;
>> >> +                             if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
>> >> +                                     lowest_vaddr = vaddr;
>> >> +                     }
>> >> +             }
>> >> +             if (lowest_vaddr != 0)
>> >> +                     elf_info->page_offset = lowest_vaddr;
>> >> +     }
>> >> +
>> >>       /* Traverse through the Elf headers and find the region where
>> >>        * _stext symbol is located in. That's where kernel is mapped */
>> >> -     stext_sym = get_kernel_stext_sym();
>> >> +     stext_sym = get_kernel_sym("_stext");
>> >>       for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
>> >>               if (phdr->p_type == PT_LOAD) {
>> >>                       unsigned long long saddr = phdr->p_vaddr;
>> >> --
>
> Thanks
> Dave

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [kernel-hardening] Re: [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization
  2016-09-13  7:10 [kernel-hardening] " Baoquan He
@ 2016-09-29  7:43 ` Simon Horman
  0 siblings, 0 replies; 15+ messages in thread
From: Simon Horman @ 2016-09-29  7:43 UTC (permalink / raw)
  To: Baoquan He; +Cc: tonli, kexec, Thomas Garnier, keescook, kernel-hardening

On Tue, Sep 13, 2016 at 03:10:05PM +0800, Baoquan He wrote:
> From: Thomas Garnier <thgarnie@google.com>
> 
> Multiple changes were made on KASLR (right now in linux-next). One of
> them is randomizing the virtual address of the physical mapping, vmalloc
> and vmemmap memory sections. It breaks kdump ability to read physical
> memory.
> 
> This change identifies if KASLR memories randomization is used by
> checking if the page_offset_base variable exists. It search for the
> correct PAGE_OFFSET value by looking at the loaded memory section and
> find the lowest aligned on PUD (the randomization level).
> 
> Related commits on linux-next:
>  - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
>  - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
> 
> Signed-off-by: Thomas Garnier <thgarnie@google.com>

Thanks, applied.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2016-09-29  7:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-17 16:47 [kernel-hardening] [PATCH v1] kexec/arch/i386: Add support for KASLR memory randomization Thomas Garnier
2016-08-17 16:47 ` Thomas Garnier
2016-08-18  4:59 ` [kernel-hardening] " Baoquan He
2016-08-18  4:59   ` Baoquan He
2016-08-23 15:38   ` [kernel-hardening] " Thomas Garnier
2016-08-23 15:38     ` Thomas Garnier
2016-09-22  8:41 ` [kernel-hardening] " Dave Young
2016-09-22  8:41   ` Dave Young
2016-09-23 16:33   ` [kernel-hardening] " Thomas Garnier
2016-09-23 16:33     ` Thomas Garnier
2016-09-26 12:52     ` [kernel-hardening] " Dave Young
2016-09-26 12:52       ` Dave Young
2016-09-26 16:53       ` [kernel-hardening] " Thomas Garnier
2016-09-26 16:53         ` Thomas Garnier
2016-09-13  7:10 [kernel-hardening] " Baoquan He
2016-09-29  7:43 ` [kernel-hardening] " Simon Horman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.