Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Chao Fan
Hi Boris, Masa, and Baoquan,

On Tue, Nov 13, 2018 at 10:51:56PM +0100, Borislav Petkov wrote:
>On Tue, Nov 13, 2018 at 03:06:16PM -0500, Masayoshi Mizuma wrote:
>> I just felt the BOOT_STRING thing in lib/kstrtox.c confuses...
>> I'm OK for now if it's applied your below comment.
>
>Well, actually, upon a second look, I don't think that including a .c
>file into a header is ok:
>
>diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
>index 3d78e27077f4..0ff3edb888e4 100644
>--- a/arch/x86/boot/string.h
>+++ b/arch/x86/boot/string.h
>@@ -30,3 +30,7 @@ extern unsigned long long simple_strtoull(const char *cp, 
>char **endp,
>  unsigned int base);
>
> #endif /* BOOT_STRING_H */
>+
>+#ifdef BOOT_STRING
>+#include "../../../lib/kstrtox.c"
>+#endif
>
>Chao, why isn't this part of arch/x86/boot/compressed/misc.c ?
>

Fine, I have put it to misc.c:

diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 8dd1d5ccae58..714b05b65a33 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -426,3 +426,7 @@ void fortify_panic(const char *name)
 {
error("detected buffer overflow");
 }
+
+#ifdef BOOT_STRING
+#include "../../../../lib/kstrtox.c"
+#endif

And define it in misc.h:

diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 4a3645fda0ed..98e28c4281ee 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -131,3 +131,5 @@ int num_immovable_mem;
 void get_immovable_mem(void);
 #endif
 #endif
+#define BOOT_STRING
+extern int kstrtoull(const char *s, unsigned int base, unsigned long long 
*res);

But isdigit() would be redefine, so:

diff --git a/include/linux/ctype.h b/include/linux/ctype.h
index 363b004426db..aba01c385232 100644
--- a/include/linux/ctype.h
+++ b/include/linux/ctype.h
@@ -23,10 +23,12 @@ extern const unsigned char _ctype[];
 #define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
 #define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
 #define iscntrl(c) ((__ismask(c)&(_C)) != 0)
+#ifndef BOOT_STRING
 static inline int isdigit(int c)
 {
return '0' <= c && c <= '9';
 }
+#endif
 #define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
 #define islower(c) ((__ismask(c)&(_L)) != 0)
 #define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)

Now I can make it.
I wonder whether this is OK to cover isdigit() with 'BOOT_STRING' tag.

Thanks,
Chao Fan

>-- 
>Regards/Gruss,
>Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>




Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Chao Fan
On Wed, Nov 14, 2018 at 09:54:50AM +0800, Chao Fan wrote:
>On Tue, Nov 13, 2018 at 06:51:50PM +0100, Borislav Petkov wrote:
>>On Mon, Nov 12, 2018 at 05:46:43PM +0800, Chao Fan wrote:
>>> Imitate setup_acpi_rsdp() for the early_param of 'acpi_rsdp'.
>>> KEXEC writes the RSDP pointer to cmdline for EFI booting.
>>> So if 'acpi_rsdp' found in cmdline, use it directely.
>>> 
>>> Since function kstrtoull() is needed, include it in
>>> arch/x86/boot/string.h. To solve the definition conflict
>>> problem, set BOOT_STRING tag to expose only kstrtoull() and
>>> functions used by it. Other functions in lib/kstrtox.c will
>>> be covered.
>>> 
>>> Signed-off-by: Chao Fan 
>>> ---
>>>  arch/x86/boot/compressed/acpitb.c | 26 ++
>>>  arch/x86/boot/string.h|  4 
>>>  lib/kstrtox.c |  4 
>>>  3 files changed, 34 insertions(+)
>>> 
>>> diff --git a/arch/x86/boot/compressed/acpitb.c 
>>> b/arch/x86/boot/compressed/acpitb.c
>>> index 50fa65cf824d..5cfb4efa5a19 100644
>>> --- a/arch/x86/boot/compressed/acpitb.c
>>> +++ b/arch/x86/boot/compressed/acpitb.c
>>> @@ -8,6 +8,12 @@
>>>  #include 
>>>  #include 
>>>  
>>> +#define STATIC
>>> +#include 
>>> +
>>> +#define BOOT_STRING
>>> +#include "../string.h"
>>> +
>>>  /* Search EFI table for RSDP table. */
>>>  static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr)
>>>  {
>>> @@ -200,3 +206,23 @@ static void bios_get_rsdp_addr(acpi_physical_address 
>>> *rsdp_addr)
>>> *rsdp_addr = (acpi_physical_address)address;
>>> }
>>>  }
>>> +
>>> +static void get_acpi_rsdp(acpi_physical_address *rsdp_addr)
>>> +{
>>> +#ifdef CONFIG_KEXEC
>>
>>Ok, why is that CONFIG_KEXEC dependency needed now too?
>>
>
>CONFIG_KEXEC is only needed in this function.
>
>When searching RSDP, there are three methods in order:
>1. When booting from KEXEC, 'acpi_rsdp' is added to cmdline by KEXEC,
>   so it can be parsed and used. CONFIG_KEXEC is needed here.
>2. When booting from EFI, parse EFI table and find RSDP.
>3. When booting from BIOS, search memory for RSDP just like
>   acpi_find_root_pointer() in drivers/acpi/acpica/tbxfroot.c did.
>
>So, CONFIG_KEXEC is only needed in 1, exactly in this function
>get_acpi_rsdp() of my PATCH.
>
>Thanks,
>Chao Fan
>

That means, CONFIG_KEXEC is needed by a little part of the whole PATCHSET.
Without CONFIG_KEXEC, RSDP can only be found in other methods.

Thanks,
Chao Fan

>>Ok, let's recap: so far, for your use case you need:
>>
>>CONFIG_MEMORY_HOTREMOVE
>>CONFIG_RANDOMIZE_BASE
>>and now
>>CONFIG_KEXEC
>>
>>So, you can clean up all that ifdeffery by defining a new config item
>>CONFIG_EARLY_PARSE_RSDP or so which depends on all those three items and
>>then you can do
>>
>>vmlinux-objs-$(CONFIG_EARLY_PARSE_RSDP) += $(obj)/acpitb.o
>>
>>and get rid of the most of the ifdeffery.
>>
>>Yes?
>>
>>> +   unsigned long long res;
>>> +   int len = 0;
>>> +   char *val;
>>> +
>>> +   val = malloc(19);
>>> +   len = cmdline_find_option("acpi_rsdp", val, 19);
>>> +
>>
>>^ Superfluous newline.
>>
>>> +   if (len == -1)
>>> +   return;
>>
>>That check is not needed since you do > 0 below.
>>
>>> +
>>> +   if (len > 0) {
>>> +   val[len] = 0;
>>> +   *rsdp_addr = (acpi_physical_address)kstrtoull(val, 16, );
>>> +   }
>>> +#endif
>>> +}
>>> diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
>>> index 3d78e27077f4..0ff3edb888e4 100644
>>> --- a/arch/x86/boot/string.h
>>> +++ b/arch/x86/boot/string.h
>>> @@ -30,3 +30,7 @@ extern unsigned long long simple_strtoull(const char *cp, 
>>> char **endp,
>>>   unsigned int base);
>>>  
>>>  #endif /* BOOT_STRING_H */
>>> +
>>> +#ifdef BOOT_STRING
>>> +#include "../../../lib/kstrtox.c"
>>> +#endif
>>> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
>>> index 1006bf70bf74..3804db9eed56 100644
>>> --- a/lib/kstrtox.c
>>> +++ b/lib/kstrtox.c
>>> @@ -126,6 +126,8 @@ int kstrtoull(const char *s, unsigned int base, 
>>> unsigned long long *res)
>>>  }
>>>  EXPORT_SYMBOL(kstrtoull);
>>
>>This needs a comment to explain what is that guard used for.
>>
>>> +#ifndef BOOT_STRING
>>> +
>>>  /**
>>>   * kstrtoll - convert a string to a long long
>>>   * @s: The start of the string. The string must be null-terminated, and 
>>> may also
>>> @@ -408,3 +410,5 @@ kstrto_from_user(kstrtou16_from_user,   kstrtou16,  
>>> u16);
>>>  kstrto_from_user(kstrtos16_from_user,  kstrtos16,  s16);
>>>  kstrto_from_user(kstrtou8_from_user,   kstrtou8,   u8);
>>>  kstrto_from_user(kstrtos8_from_user,   kstrtos8,   s8);
>>> +
>>> +#endif
>>
>>#endif /* BOOT_STRING */
>>
>>-- 
>>Regards/Gruss,
>>Boris.
>>
>>Good mailing practices for 400: avoid top-posting and trim the reply.
>>
>>




Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Chao Fan
On Tue, Nov 13, 2018 at 06:51:50PM +0100, Borislav Petkov wrote:
>On Mon, Nov 12, 2018 at 05:46:43PM +0800, Chao Fan wrote:
>> Imitate setup_acpi_rsdp() for the early_param of 'acpi_rsdp'.
>> KEXEC writes the RSDP pointer to cmdline for EFI booting.
>> So if 'acpi_rsdp' found in cmdline, use it directely.
>> 
>> Since function kstrtoull() is needed, include it in
>> arch/x86/boot/string.h. To solve the definition conflict
>> problem, set BOOT_STRING tag to expose only kstrtoull() and
>> functions used by it. Other functions in lib/kstrtox.c will
>> be covered.
>> 
>> Signed-off-by: Chao Fan 
>> ---
>>  arch/x86/boot/compressed/acpitb.c | 26 ++
>>  arch/x86/boot/string.h|  4 
>>  lib/kstrtox.c |  4 
>>  3 files changed, 34 insertions(+)
>> 
>> diff --git a/arch/x86/boot/compressed/acpitb.c 
>> b/arch/x86/boot/compressed/acpitb.c
>> index 50fa65cf824d..5cfb4efa5a19 100644
>> --- a/arch/x86/boot/compressed/acpitb.c
>> +++ b/arch/x86/boot/compressed/acpitb.c
>> @@ -8,6 +8,12 @@
>>  #include 
>>  #include 
>>  
>> +#define STATIC
>> +#include 
>> +
>> +#define BOOT_STRING
>> +#include "../string.h"
>> +
>>  /* Search EFI table for RSDP table. */
>>  static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr)
>>  {
>> @@ -200,3 +206,23 @@ static void bios_get_rsdp_addr(acpi_physical_address 
>> *rsdp_addr)
>>  *rsdp_addr = (acpi_physical_address)address;
>>  }
>>  }
>> +
>> +static void get_acpi_rsdp(acpi_physical_address *rsdp_addr)
>> +{
>> +#ifdef CONFIG_KEXEC
>
>Ok, why is that CONFIG_KEXEC dependency needed now too?
>

CONFIG_KEXEC is only needed in this function.

When searching RSDP, there are three methods in order:
1. When booting from KEXEC, 'acpi_rsdp' is added to cmdline by KEXEC,
   so it can be parsed and used. CONFIG_KEXEC is needed here.
2. When booting from EFI, parse EFI table and find RSDP.
3. When booting from BIOS, search memory for RSDP just like
   acpi_find_root_pointer() in drivers/acpi/acpica/tbxfroot.c did.

So, CONFIG_KEXEC is only needed in 1, exactly in this function
get_acpi_rsdp() of my PATCH.

Thanks,
Chao Fan

>Ok, let's recap: so far, for your use case you need:
>
>CONFIG_MEMORY_HOTREMOVE
>CONFIG_RANDOMIZE_BASE
>and now
>CONFIG_KEXEC
>
>So, you can clean up all that ifdeffery by defining a new config item
>CONFIG_EARLY_PARSE_RSDP or so which depends on all those three items and
>then you can do
>
>vmlinux-objs-$(CONFIG_EARLY_PARSE_RSDP) += $(obj)/acpitb.o
>
>and get rid of the most of the ifdeffery.
>
>Yes?
>
>> +unsigned long long res;
>> +int len = 0;
>> +char *val;
>> +
>> +val = malloc(19);
>> +len = cmdline_find_option("acpi_rsdp", val, 19);
>> +
>
>^ Superfluous newline.
>
>> +if (len == -1)
>> +return;
>
>That check is not needed since you do > 0 below.
>
>> +
>> +if (len > 0) {
>> +val[len] = 0;
>> +*rsdp_addr = (acpi_physical_address)kstrtoull(val, 16, );
>> +}
>> +#endif
>> +}
>> diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
>> index 3d78e27077f4..0ff3edb888e4 100644
>> --- a/arch/x86/boot/string.h
>> +++ b/arch/x86/boot/string.h
>> @@ -30,3 +30,7 @@ extern unsigned long long simple_strtoull(const char *cp, 
>> char **endp,
>>unsigned int base);
>>  
>>  #endif /* BOOT_STRING_H */
>> +
>> +#ifdef BOOT_STRING
>> +#include "../../../lib/kstrtox.c"
>> +#endif
>> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
>> index 1006bf70bf74..3804db9eed56 100644
>> --- a/lib/kstrtox.c
>> +++ b/lib/kstrtox.c
>> @@ -126,6 +126,8 @@ int kstrtoull(const char *s, unsigned int base, unsigned 
>> long long *res)
>>  }
>>  EXPORT_SYMBOL(kstrtoull);
>
>This needs a comment to explain what is that guard used for.
>
>> +#ifndef BOOT_STRING
>> +
>>  /**
>>   * kstrtoll - convert a string to a long long
>>   * @s: The start of the string. The string must be null-terminated, and may 
>> also
>> @@ -408,3 +410,5 @@ kstrto_from_user(kstrtou16_from_user,kstrtou16,  
>> u16);
>>  kstrto_from_user(kstrtos16_from_user,   kstrtos16,  s16);
>>  kstrto_from_user(kstrtou8_from_user,kstrtou8,   u8);
>>  kstrto_from_user(kstrtos8_from_user,kstrtos8,   s8);
>> +
>> +#endif
>
>#endif /* BOOT_STRING */
>
>-- 
>Regards/Gruss,
>Boris.
>
>Good mailing practices for 400: avoid top-posting and trim the reply.
>
>




Re: [PATCH] firmware: efi: add NULL pointer checks in efivars api functions

2018-11-13 Thread Arend van Spriel

On 11/13/2018 11:50 PM, Ard Biesheuvel wrote:

Hi Arend,

On Tue, 13 Nov 2018 at 12:51, Arend van Spriel
 wrote:


Since commit ce2e6db554fa ("brcmfmac: Add support for getting nvram
contents from EFI variables") we have a device driver accessing the
efivars api (since next-20181107). Several functions in efivars api
assume __efivars is set, ie. will be accessed after efivars_register()
has been called. However, following NULL pointer access was reported
calling efivar_entry_size() from the brcmfmac device driver.

[   14.177769] Unable to handle kernel NULL pointer dereference at
virtual address 0008
[   14.197303] pgd = 60bfa5f1
[   14.211842] [0008] *pgd=
[   14.227373] Internal error: Oops: 5 [#1] SMP ARM
[   14.244244] Modules linked in: brcmfmac sha256_generic sha256_arm snd 
cfg80211 brcmutil soundcore snd_soc_tegra30_ahub tegra_wdt
[   14.269109] CPU: 1 PID: 114 Comm: kworker/1:2 Not tainted 
4.20.0-rc1-next-20181107-gd881de3 #1
[   14.269114] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[   14.269154] Workqueue: events request_firmware_work_func
[   14.269177] PC is at efivar_entry_size+0x28/0x90
[   14.269362] LR is at brcmf_fw_complete_request+0x3f8/0x8d4 [brcmfmac]
[   14.269369] pc : []lr : []psr: a00d0113
[   14.269374] sp : ede7fe28  ip : ee983410  fp : c1787f30
[   14.269378] r10:   r9 :   r8 : bf2b2258
[   14.269384] r7 : ee983000  r6 : c1604c48  r5 : ede7fe88  r4 : edf337c0
[   14.269389] r3 :   r2 :   r1 : ede7fe88  r0 : c17712c8
[   14.269398] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   14.269404] Control: 10c5387d  Table: ad16804a  DAC: 0051

Disassembly showed that the local static variable __efivars is NULL. Likely
because efivars_register() is not called on this Tegra platform. So adding
a NULL pointer check in efivar_entry_size() and similar functions while at
it. In efivars_register() a couple of sanity checks have been added.

Cc: Hans de Goede 
Reported-by: Jon Hunter 
Signed-off-by: Arend van Spriel 
---
 drivers/firmware/efi/vars.c | 108 +++-
 1 file changed, 87 insertions(+), 21 deletions(-)

diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 9336ffd..5fbd8e7 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -318,7 +318,12 @@ struct variable_validate {
 static efi_status_t
 check_var_size(u32 attributes, unsigned long size)
 {
-   const struct efivar_operations *fops = __efivars->ops;
+   const struct efivar_operations *fops;
+
+   if (!__efivars)
+   return EFI_UNSUPPORTED;
+
+   fops = __efivars->ops;

if (!fops->query_variable_store)
return EFI_UNSUPPORTED;
@@ -329,7 +334,12 @@ struct variable_validate {
 static efi_status_t
 check_var_size_nonblocking(u32 attributes, unsigned long size)
 {
-   const struct efivar_operations *fops = __efivars->ops;
+   const struct efivar_operations *fops;
+
+   if (!__efivars)
+   return EFI_UNSUPPORTED;
+
+   fops = __efivars->ops;

if (!fops->query_variable_store)
return EFI_UNSUPPORTED;
@@ -429,13 +439,18 @@ static void dup_variable_bug(efi_char16_t *str16, 
efi_guid_t *vendor_guid,
 int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
void *data, bool duplicates, struct list_head *head)
 {
-   const struct efivar_operations *ops = __efivars->ops;
+   const struct efivar_operations *ops;
unsigned long variable_name_size = 1024;
efi_char16_t *variable_name;
efi_status_t status;
efi_guid_t vendor_guid;
int err = 0;

+   if (!__efivars)
+   return -EFAULT;
+
+   ops = __efivars->ops;
+
variable_name = kzalloc(variable_name_size, GFP_KERNEL);
if (!variable_name) {
printk(KERN_ERR "efivars: Memory allocation failed.\n");
@@ -583,12 +598,14 @@ static void efivar_entry_list_del_unlock(struct 
efivar_entry *entry)
  */
 int __efivar_entry_delete(struct efivar_entry *entry)
 {
-   const struct efivar_operations *ops = __efivars->ops;
efi_status_t status;

-   status = ops->set_variable(entry->var.VariableName,
-  >var.VendorGuid,
-  0, 0, NULL);
+   if (!__efivars)
+   return -EINVAL;
+
+   status = __efivars->ops->set_variable(entry->var.VariableName,
+ >var.VendorGuid,
+ 0, 0, NULL);

return efi_status_to_err(status);
 }
@@ -607,12 +624,17 @@ int __efivar_entry_delete(struct efivar_entry *entry)
  */
 int efivar_entry_delete(struct efivar_entry *entry)
 {
-   const struct efivar_operations *ops = __efivars->ops;
+   const struct efivar_operations *ops;
efi_status_t status;

if 

Re: [PATCH] firmware: efi: add NULL pointer checks in efivars api functions

2018-11-13 Thread Ard Biesheuvel
Hi Arend,

On Tue, 13 Nov 2018 at 12:51, Arend van Spriel
 wrote:
>
> Since commit ce2e6db554fa ("brcmfmac: Add support for getting nvram
> contents from EFI variables") we have a device driver accessing the
> efivars api (since next-20181107). Several functions in efivars api
> assume __efivars is set, ie. will be accessed after efivars_register()
> has been called. However, following NULL pointer access was reported
> calling efivar_entry_size() from the brcmfmac device driver.
>
> [   14.177769] Unable to handle kernel NULL pointer dereference at
> virtual address 0008
> [   14.197303] pgd = 60bfa5f1
> [   14.211842] [0008] *pgd=
> [   14.227373] Internal error: Oops: 5 [#1] SMP ARM
> [   14.244244] Modules linked in: brcmfmac sha256_generic sha256_arm snd 
> cfg80211 brcmutil soundcore snd_soc_tegra30_ahub tegra_wdt
> [   14.269109] CPU: 1 PID: 114 Comm: kworker/1:2 Not tainted 
> 4.20.0-rc1-next-20181107-gd881de3 #1
> [   14.269114] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
> [   14.269154] Workqueue: events request_firmware_work_func
> [   14.269177] PC is at efivar_entry_size+0x28/0x90
> [   14.269362] LR is at brcmf_fw_complete_request+0x3f8/0x8d4 [brcmfmac]
> [   14.269369] pc : []lr : []psr: a00d0113
> [   14.269374] sp : ede7fe28  ip : ee983410  fp : c1787f30
> [   14.269378] r10:   r9 :   r8 : bf2b2258
> [   14.269384] r7 : ee983000  r6 : c1604c48  r5 : ede7fe88  r4 : edf337c0
> [   14.269389] r3 :   r2 :   r1 : ede7fe88  r0 : c17712c8
> [   14.269398] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
> none
> [   14.269404] Control: 10c5387d  Table: ad16804a  DAC: 0051
>
> Disassembly showed that the local static variable __efivars is NULL. Likely
> because efivars_register() is not called on this Tegra platform. So adding
> a NULL pointer check in efivar_entry_size() and similar functions while at
> it. In efivars_register() a couple of sanity checks have been added.
>
> Cc: Hans de Goede 
> Reported-by: Jon Hunter 
> Signed-off-by: Arend van Spriel 
> ---
>  drivers/firmware/efi/vars.c | 108 
> +++-
>  1 file changed, 87 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
> index 9336ffd..5fbd8e7 100644
> --- a/drivers/firmware/efi/vars.c
> +++ b/drivers/firmware/efi/vars.c
> @@ -318,7 +318,12 @@ struct variable_validate {
>  static efi_status_t
>  check_var_size(u32 attributes, unsigned long size)
>  {
> -   const struct efivar_operations *fops = __efivars->ops;
> +   const struct efivar_operations *fops;
> +
> +   if (!__efivars)
> +   return EFI_UNSUPPORTED;
> +
> +   fops = __efivars->ops;
>
> if (!fops->query_variable_store)
> return EFI_UNSUPPORTED;
> @@ -329,7 +334,12 @@ struct variable_validate {
>  static efi_status_t
>  check_var_size_nonblocking(u32 attributes, unsigned long size)
>  {
> -   const struct efivar_operations *fops = __efivars->ops;
> +   const struct efivar_operations *fops;
> +
> +   if (!__efivars)
> +   return EFI_UNSUPPORTED;
> +
> +   fops = __efivars->ops;
>
> if (!fops->query_variable_store)
> return EFI_UNSUPPORTED;
> @@ -429,13 +439,18 @@ static void dup_variable_bug(efi_char16_t *str16, 
> efi_guid_t *vendor_guid,
>  int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void 
> *),
> void *data, bool duplicates, struct list_head *head)
>  {
> -   const struct efivar_operations *ops = __efivars->ops;
> +   const struct efivar_operations *ops;
> unsigned long variable_name_size = 1024;
> efi_char16_t *variable_name;
> efi_status_t status;
> efi_guid_t vendor_guid;
> int err = 0;
>
> +   if (!__efivars)
> +   return -EFAULT;
> +
> +   ops = __efivars->ops;
> +
> variable_name = kzalloc(variable_name_size, GFP_KERNEL);
> if (!variable_name) {
> printk(KERN_ERR "efivars: Memory allocation failed.\n");
> @@ -583,12 +598,14 @@ static void efivar_entry_list_del_unlock(struct 
> efivar_entry *entry)
>   */
>  int __efivar_entry_delete(struct efivar_entry *entry)
>  {
> -   const struct efivar_operations *ops = __efivars->ops;
> efi_status_t status;
>
> -   status = ops->set_variable(entry->var.VariableName,
> -  >var.VendorGuid,
> -  0, 0, NULL);
> +   if (!__efivars)
> +   return -EINVAL;
> +
> +   status = __efivars->ops->set_variable(entry->var.VariableName,
> + >var.VendorGuid,
> + 0, 0, NULL);
>
> return efi_status_to_err(status);
>  }
> @@ -607,12 +624,17 @@ int __efivar_entry_delete(struct efivar_entry *entry)
>   */
>  int 

Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Borislav Petkov
On Tue, Nov 13, 2018 at 03:06:16PM -0500, Masayoshi Mizuma wrote:
> I just felt the BOOT_STRING thing in lib/kstrtox.c confuses...
> I'm OK for now if it's applied your below comment.

Well, actually, upon a second look, I don't think that including a .c
file into a header is ok:

diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
index 3d78e27077f4..0ff3edb888e4 100644
--- a/arch/x86/boot/string.h
+++ b/arch/x86/boot/string.h
@@ -30,3 +30,7 @@ extern unsigned long long simple_strtoull(const char *cp, 
char **endp,
  unsigned int base);

 #endif /* BOOT_STRING_H */
+
+#ifdef BOOT_STRING
+#include "../../../lib/kstrtox.c"
+#endif

Chao, why isn't this part of arch/x86/boot/compressed/misc.c ?

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


[PATCH] firmware: efi: add NULL pointer checks in efivars api functions

2018-11-13 Thread Arend van Spriel
Since commit ce2e6db554fa ("brcmfmac: Add support for getting nvram
contents from EFI variables") we have a device driver accessing the
efivars api (since next-20181107). Several functions in efivars api
assume __efivars is set, ie. will be accessed after efivars_register()
has been called. However, following NULL pointer access was reported
calling efivar_entry_size() from the brcmfmac device driver.

[   14.177769] Unable to handle kernel NULL pointer dereference at
virtual address 0008
[   14.197303] pgd = 60bfa5f1
[   14.211842] [0008] *pgd=
[   14.227373] Internal error: Oops: 5 [#1] SMP ARM
[   14.244244] Modules linked in: brcmfmac sha256_generic sha256_arm snd 
cfg80211 brcmutil soundcore snd_soc_tegra30_ahub tegra_wdt
[   14.269109] CPU: 1 PID: 114 Comm: kworker/1:2 Not tainted 
4.20.0-rc1-next-20181107-gd881de3 #1
[   14.269114] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[   14.269154] Workqueue: events request_firmware_work_func
[   14.269177] PC is at efivar_entry_size+0x28/0x90
[   14.269362] LR is at brcmf_fw_complete_request+0x3f8/0x8d4 [brcmfmac]
[   14.269369] pc : []lr : []psr: a00d0113
[   14.269374] sp : ede7fe28  ip : ee983410  fp : c1787f30
[   14.269378] r10:   r9 :   r8 : bf2b2258
[   14.269384] r7 : ee983000  r6 : c1604c48  r5 : ede7fe88  r4 : edf337c0
[   14.269389] r3 :   r2 :   r1 : ede7fe88  r0 : c17712c8
[   14.269398] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   14.269404] Control: 10c5387d  Table: ad16804a  DAC: 0051

Disassembly showed that the local static variable __efivars is NULL. Likely
because efivars_register() is not called on this Tegra platform. So adding
a NULL pointer check in efivar_entry_size() and similar functions while at
it. In efivars_register() a couple of sanity checks have been added.

Cc: Hans de Goede 
Reported-by: Jon Hunter 
Signed-off-by: Arend van Spriel 
---
 drivers/firmware/efi/vars.c | 108 +++-
 1 file changed, 87 insertions(+), 21 deletions(-)

diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 9336ffd..5fbd8e7 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -318,7 +318,12 @@ struct variable_validate {
 static efi_status_t
 check_var_size(u32 attributes, unsigned long size)
 {
-   const struct efivar_operations *fops = __efivars->ops;
+   const struct efivar_operations *fops;
+
+   if (!__efivars)
+   return EFI_UNSUPPORTED;
+
+   fops = __efivars->ops;
 
if (!fops->query_variable_store)
return EFI_UNSUPPORTED;
@@ -329,7 +334,12 @@ struct variable_validate {
 static efi_status_t
 check_var_size_nonblocking(u32 attributes, unsigned long size)
 {
-   const struct efivar_operations *fops = __efivars->ops;
+   const struct efivar_operations *fops;
+
+   if (!__efivars)
+   return EFI_UNSUPPORTED;
+
+   fops = __efivars->ops;
 
if (!fops->query_variable_store)
return EFI_UNSUPPORTED;
@@ -429,13 +439,18 @@ static void dup_variable_bug(efi_char16_t *str16, 
efi_guid_t *vendor_guid,
 int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
void *data, bool duplicates, struct list_head *head)
 {
-   const struct efivar_operations *ops = __efivars->ops;
+   const struct efivar_operations *ops;
unsigned long variable_name_size = 1024;
efi_char16_t *variable_name;
efi_status_t status;
efi_guid_t vendor_guid;
int err = 0;
 
+   if (!__efivars)
+   return -EFAULT;
+
+   ops = __efivars->ops;
+
variable_name = kzalloc(variable_name_size, GFP_KERNEL);
if (!variable_name) {
printk(KERN_ERR "efivars: Memory allocation failed.\n");
@@ -583,12 +598,14 @@ static void efivar_entry_list_del_unlock(struct 
efivar_entry *entry)
  */
 int __efivar_entry_delete(struct efivar_entry *entry)
 {
-   const struct efivar_operations *ops = __efivars->ops;
efi_status_t status;
 
-   status = ops->set_variable(entry->var.VariableName,
-  >var.VendorGuid,
-  0, 0, NULL);
+   if (!__efivars)
+   return -EINVAL;
+
+   status = __efivars->ops->set_variable(entry->var.VariableName,
+ >var.VendorGuid,
+ 0, 0, NULL);
 
return efi_status_to_err(status);
 }
@@ -607,12 +624,17 @@ int __efivar_entry_delete(struct efivar_entry *entry)
  */
 int efivar_entry_delete(struct efivar_entry *entry)
 {
-   const struct efivar_operations *ops = __efivars->ops;
+   const struct efivar_operations *ops;
efi_status_t status;
 
if (down_interruptible(_lock))
return -EINTR;
 
+   if (!__efivars) {
+   

Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Masayoshi Mizuma
On Tue, Nov 13, 2018 at 06:54:13PM +0100, Borislav Petkov wrote:
> On Tue, Nov 13, 2018 at 11:11:11AM -0500, Masayoshi Mizuma wrote:
> > I think it's not very good idea to use kstrtoull() in
> > arch/x86/boot/compressed/* because some tricks are needed to
> > use the function, looks like Chao is trying...
> 
> Ok, I had a look at the patch. And frankly, I don't see anything wrong
> with the aspect of using kstrtoull() in the compressed stage too and
> getting rid of simple_strtoull().
> 
> So what are your reservations?

Thank you for your checking.
I just felt the BOOT_STRING thing in lib/kstrtox.c confuses...
I'm OK for now if it's applied your below comment.

> > @@ -126,6 +126,8 @@ int kstrtoull(const char *s, unsigned int base, 
> > unsigned long long *res)
> >  }
> >  EXPORT_SYMBOL(kstrtoull);
> 
> This needs a comment to explain what is that guard used for.

Thanks,
Masa


Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Borislav Petkov
On Tue, Nov 13, 2018 at 11:11:11AM -0500, Masayoshi Mizuma wrote:
> I think it's not very good idea to use kstrtoull() in
> arch/x86/boot/compressed/* because some tricks are needed to
> use the function, looks like Chao is trying...

Ok, I had a look at the patch. And frankly, I don't see anything wrong
with the aspect of using kstrtoull() in the compressed stage too and
getting rid of simple_strtoull().

So what are your reservations?

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Borislav Petkov
On Mon, Nov 12, 2018 at 05:46:43PM +0800, Chao Fan wrote:
> Imitate setup_acpi_rsdp() for the early_param of 'acpi_rsdp'.
> KEXEC writes the RSDP pointer to cmdline for EFI booting.
> So if 'acpi_rsdp' found in cmdline, use it directely.
> 
> Since function kstrtoull() is needed, include it in
> arch/x86/boot/string.h. To solve the definition conflict
> problem, set BOOT_STRING tag to expose only kstrtoull() and
> functions used by it. Other functions in lib/kstrtox.c will
> be covered.
> 
> Signed-off-by: Chao Fan 
> ---
>  arch/x86/boot/compressed/acpitb.c | 26 ++
>  arch/x86/boot/string.h|  4 
>  lib/kstrtox.c |  4 
>  3 files changed, 34 insertions(+)
> 
> diff --git a/arch/x86/boot/compressed/acpitb.c 
> b/arch/x86/boot/compressed/acpitb.c
> index 50fa65cf824d..5cfb4efa5a19 100644
> --- a/arch/x86/boot/compressed/acpitb.c
> +++ b/arch/x86/boot/compressed/acpitb.c
> @@ -8,6 +8,12 @@
>  #include 
>  #include 
>  
> +#define STATIC
> +#include 
> +
> +#define BOOT_STRING
> +#include "../string.h"
> +
>  /* Search EFI table for RSDP table. */
>  static void efi_get_rsdp_addr(acpi_physical_address *rsdp_addr)
>  {
> @@ -200,3 +206,23 @@ static void bios_get_rsdp_addr(acpi_physical_address 
> *rsdp_addr)
>   *rsdp_addr = (acpi_physical_address)address;
>   }
>  }
> +
> +static void get_acpi_rsdp(acpi_physical_address *rsdp_addr)
> +{
> +#ifdef CONFIG_KEXEC

Ok, why is that CONFIG_KEXEC dependency needed now too?

Ok, let's recap: so far, for your use case you need:

CONFIG_MEMORY_HOTREMOVE
CONFIG_RANDOMIZE_BASE
and now
CONFIG_KEXEC

So, you can clean up all that ifdeffery by defining a new config item
CONFIG_EARLY_PARSE_RSDP or so which depends on all those three items and
then you can do

vmlinux-objs-$(CONFIG_EARLY_PARSE_RSDP) += $(obj)/acpitb.o

and get rid of the most of the ifdeffery.

Yes?

> + unsigned long long res;
> + int len = 0;
> + char *val;
> +
> + val = malloc(19);
> + len = cmdline_find_option("acpi_rsdp", val, 19);
> +

^ Superfluous newline.

> + if (len == -1)
> + return;

That check is not needed since you do > 0 below.

> +
> + if (len > 0) {
> + val[len] = 0;
> + *rsdp_addr = (acpi_physical_address)kstrtoull(val, 16, );
> + }
> +#endif
> +}
> diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h
> index 3d78e27077f4..0ff3edb888e4 100644
> --- a/arch/x86/boot/string.h
> +++ b/arch/x86/boot/string.h
> @@ -30,3 +30,7 @@ extern unsigned long long simple_strtoull(const char *cp, 
> char **endp,
> unsigned int base);
>  
>  #endif /* BOOT_STRING_H */
> +
> +#ifdef BOOT_STRING
> +#include "../../../lib/kstrtox.c"
> +#endif
> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
> index 1006bf70bf74..3804db9eed56 100644
> --- a/lib/kstrtox.c
> +++ b/lib/kstrtox.c
> @@ -126,6 +126,8 @@ int kstrtoull(const char *s, unsigned int base, unsigned 
> long long *res)
>  }
>  EXPORT_SYMBOL(kstrtoull);

This needs a comment to explain what is that guard used for.

> +#ifndef BOOT_STRING
> +
>  /**
>   * kstrtoll - convert a string to a long long
>   * @s: The start of the string. The string must be null-terminated, and may 
> also
> @@ -408,3 +410,5 @@ kstrto_from_user(kstrtou16_from_user, kstrtou16,  
> u16);
>  kstrto_from_user(kstrtos16_from_user,kstrtos16,  s16);
>  kstrto_from_user(kstrtou8_from_user, kstrtou8,   u8);
>  kstrto_from_user(kstrtos8_from_user, kstrtos8,   s8);
> +
> +#endif

#endif /* BOOT_STRING */

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Borislav Petkov
On Tue, Nov 13, 2018 at 11:11:11AM -0500, Masayoshi Mizuma wrote:
> I know checkpatch.pl says an warning about simple_strtoull(),
> however, I believe the warning is for simple_strtoull() defined
> in lib/vsprintf.c.

simple_strtoull is deprecated for various reasons. I'll take a look at
Chao's patch soon.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.


Re: [PATCH v11 3/5] x86/boot: Add get_acpi_rsdp() to parse RSDP in cmdlien from kexec

2018-11-13 Thread Masayoshi Mizuma
Hi Chao and Boris,

On Tue, Nov 13, 2018 at 10:12:18AM +0800, Chao Fan wrote:
> On Mon, Nov 12, 2018 at 12:43:44PM -0500, Masayoshi Mizuma wrote:
> >How about the following get_acpi_rsdp()...? It doesn't use kstrtoull().
> >
> >static void get_acpi_rsdp(acpi_physical_address *rsdp_addr)
> >{
> >#ifdef CONFIG_KEXEC
> >unsigned long addr;
> >char val[32];
> >
> >if (cmdline_find_option("acpi_rsdp", val, sizeof(val)) > 0) {
> >char *e;
> >
> >if (!strncmp(val, "0x", 2)) {
> >addr = simple_strtoull(val + 2, , 16);
> >if ((addr == 0) || ((val + 2) == e))
> >return;
> >*rsdp_addr = (acpi_physical_address)addr;
> >}
> >}
> >#endif
> >}
> 
> Thanks for the suggestion.
> I used this function. In the old version, Boris said simple_strtoull()
> is the old function and told me use the new kstrtoull().

I think it's not very good idea to use kstrtoull() in
arch/x86/boot/compressed/* because some tricks are needed to
use the function, looks like Chao is trying...
It is the simple way here to use simple_strtoull() defined
in arch/x86/boot/boot.h, I think.

I know checkpatch.pl says an warning about simple_strtoull(),
however, I believe the warning is for simple_strtoull() defined
in lib/vsprintf.c.

Thanks,
Masa


Re: [PATCH v11 2/5] x86/boot: Add bios_get_rsdp_addr() to search RSDP in memory

2018-11-13 Thread Borislav Petkov
On Tue, Nov 13, 2018 at 10:10:16AM +0800, Chao Fan wrote:
> The 'rover' was named as 'mem_rover', but the length of this line is too
> long. So shorten it as 'rever' so that they can keep in one line.

I still have no clue what "rover" or "rever" means...

> This name came from ACPI driver code, acpi_find_root_pointer().
> Used for the loop. If you have a better name, please tell me.

I would if I knew what it meant. If you don't know either, then name it
to something descriptive so that it is clear what it is when reading the
code.

Thx.

-- 
Regards/Gruss,
Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.