Re: [PATCH v2 2/2] x86, kexec_file_load: make it work with efi=noruntime or efi=old_map

2019-01-15 Thread Kairui Song
On Wed, Jan 16, 2019 at 7:10 AM Borislav Petkov  wrote:

> > +#ifdef CONFIG_ACPI
> > + /* Setup ACPI RSDP pointer in case EFI is not available in second 
> > kernel */
> > + if (!acpi_disabled && (!efi_enabled(EFI_RUNTIME_SERVICES) || 
> > efi_enabled(EFI_OLD_MEMMAP))) {
> > + /* Copied from acpi_os_get_root_pointer accordingly */
> > + params->acpi_rsdp_addr = boot_params.acpi_rsdp_addr;
> > + if (!params->acpi_rsdp_addr) {
> > + if (efi_enabled(EFI_CONFIG_TABLES)) {
> > + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
> > + params->acpi_rsdp_addr = efi.acpi20;
> > + else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
> > + params->acpi_rsdp_addr = efi.acpi;
> > + } else if 
> > (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
> > + 
> > acpi_find_root_pointer(>acpi_rsdp_addr);
> > + }
> > + }
> > + if (!params->acpi_rsdp_addr)
> > + pr_warn("RSDP is not available for second kernel\n");
> > + }
> >  #endif
>
> Amazing the amount of ACPI RDSP parsing and fiddling patches flying
> around these days...
>
> In any case, this needs to be synchronized with:
>
> https://lkml.kernel.org/r/20190107032243.25324-1-fanc.f...@cn.fujitsu.com
>
> and checked whether the above can be used instead of sprinkling of ACPI
> parsing code left and right.
>
> Thx.

Hi thanks for the suggestion.

I didn't see a way to reuse things in that patch series, situation is
different, in that patch it needs to get RSDP in very early boot stage
so it did everything from scratch, in this patch kexec_file_load need
to get RSDP too, but everything is well setup so things are a lot
easier, just read from current boot_prams, efi and fallback to
acpi_find_root_pointer should be good.

And that patch series also need to consider boot_params.acpi_rsdp_addr
value, or it won't work if the system is rebooted with kexec, efi is
disabled and acpi_rsdp is provided by boot_params (Xen PVH guests also
need to get acpi_rsdp from boot_params according to commit message of
ae7e1238e68f2a472a125673ab506d49158c1889). Will add some comment and
discuss.

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


Re: [PATCH v2 2/2] x86, kexec_file_load: make it work with efi=noruntime or efi=old_map

2019-01-15 Thread Kairui Song
On Wed, Jan 16, 2019 at 11:32 AM Dave Young  wrote:
>
> On 01/16/19 at 12:10am, Borislav Petkov wrote:
> > On Tue, Jan 15, 2019 at 05:58:34PM +0800, Kairui Song wrote:
> > > When efi=noruntime or efi=oldmap is used, EFI services won't be available
> > > in the second kernel, therefore the second kernel will not be able to get
> > > the ACPI RSDP address from firmware by calling EFI services and won't
> > > boot. Previously we are expecting the user to set the acpi_rsdp=
> > > on kernel command line for second kernel as there was no way to pass RSDP
> > > address to second kernel.
> > >
> > > After commit e6e094e053af ('x86/acpi, x86/boot: Take RSDP address from
> > > boot params if available'), now it's possible to set an acpi_rsdp_addr
> > > parameter in the boot_params passed to second kernel, this commit make
> > > use of it, detect and set the RSDP address when it's required for second
> > > kernel to boot.
> > >
> > > Tested with an EFI enabled KVM VM with efi=noruntime.
> > >
> > > Suggested-by: Dave Young 
> > > Signed-off-by: Kairui Song 
> > > ---
> > >  arch/x86/kernel/kexec-bzimage64.c | 21 +
> > >  drivers/acpi/acpica/tbxfroot.c|  3 +--
> > >  include/acpi/acpixf.h |  2 +-
> > >  3 files changed, 23 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/arch/x86/kernel/kexec-bzimage64.c 
> > > b/arch/x86/kernel/kexec-bzimage64.c
> > > index 53917a3ebf94..0a90dcbd041f 100644
> > > --- a/arch/x86/kernel/kexec-bzimage64.c
> > > +++ b/arch/x86/kernel/kexec-bzimage64.c
> > > @@ -20,6 +20,7 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >
> > >  #include 
> > >  #include 
> > > @@ -255,8 +256,28 @@ setup_boot_parameters(struct kimage *image, struct 
> > > boot_params *params,
> > > /* Setup EFI state */
> > > setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
> > > efi_setup_data_offset);
> > > +
> > > +#ifdef CONFIG_ACPI
> > > +   /* Setup ACPI RSDP pointer in case EFI is not available in second 
> > > kernel */
> > > +   if (!acpi_disabled && (!efi_enabled(EFI_RUNTIME_SERVICES) || 
> > > efi_enabled(EFI_OLD_MEMMAP))) {
> > > +   /* Copied from acpi_os_get_root_pointer accordingly */
> > > +   params->acpi_rsdp_addr = boot_params.acpi_rsdp_addr;
> > > +   if (!params->acpi_rsdp_addr) {
> > > +   if (efi_enabled(EFI_CONFIG_TABLES)) {
> > > +   if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
> > > +   params->acpi_rsdp_addr = efi.acpi20;
> > > +   else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
> > > +   params->acpi_rsdp_addr = efi.acpi;
> > > +   } else if 
> > > (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
> > > +   
> > > acpi_find_root_pointer(>acpi_rsdp_addr);
> > > +   }
> > > +   }
> > > +   if (!params->acpi_rsdp_addr)
> > > +   pr_warn("RSDP is not available for second kernel\n");
> > > +   }
> > >  #endif
> >
> > Amazing the amount of ACPI RDSP parsing and fiddling patches flying
> > around these days...
> >
> > In any case, this needs to be synchronized with:
> >
> > https://lkml.kernel.org/r/20190107032243.25324-1-fanc.f...@cn.fujitsu.com
> >
> > and checked whether the above can be used instead of sprinkling of ACPI
> > parsing code left and right.
>
> Both Baoquan and Chao are cced for comments.
> The above KASLR patches seems some early code to parsing acpi, but I think in 
> this
> patch just call acpi function to get the root pointer no need to add the
> duplicate logic of if/else/else if.
>
> Kairui,  do you have any reason for the checking?  Is there some simple
> acpi function to just return the root pointer?

Hi, I'm afraid that would require moving multiple structure and
function out of .init,
acpi_os_get_root_pointer is an ideal function to do the job, but it's
in .init and (on x86) it will call x86_init.acpi.get_root_pointer (by
calling acpi_arch_get_root_pointer) which will also be freed after
init, unless I change the x86_init, move they out of .init which is
not a good idea.

Maybe I could split acpi_os_get_root_pointer into two, one gets freed
after init, one for later use. But the "acpi_rsdp_addr" trick only
works for x86, and this would change more common acpi driver code so
not sure if a good idea.


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



--
Best Regards,
Kairui Song


Re: [RFC PATCH v2 2/2] kexec, KEYS: Make use of platform keyring for signature verify

2019-01-15 Thread Kairui Song
On Tue, Jan 15, 2019 at 11:47 PM Mimi Zohar  wrote:
>
> On Tue, 2019-01-15 at 17:45 +0800, Kairui Song wrote:
>
> > diff --git a/arch/x86/kernel/kexec-bzimage64.c 
> > b/arch/x86/kernel/kexec-bzimage64.c
> > index 7d97e432cbbc..a06b04065bb1 100644
> > --- a/arch/x86/kernel/kexec-bzimage64.c
> > +++ b/arch/x86/kernel/kexec-bzimage64.c
> > @@ -534,9 +534,18 @@ static int bzImage64_cleanup(void *loader_data)
> >  #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
> >  static int bzImage64_verify_sig(const char *kernel, unsigned long 
> > kernel_len)
> >  {
> > - return verify_pefile_signature(kernel, kernel_len,
> > -VERIFY_USE_SECONDARY_KEYRING,
> > -VERIFYING_KEXEC_PE_SIGNATURE);
> > + int ret;
> > + ret = verify_pefile_signature(kernel, kernel_len,
> > + VERIFY_USE_SECONDARY_KEYRING,
> > + VERIFYING_KEXEC_PE_SIGNATURE);
> > +#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
>
> Consider using IS_ENABLED() or IS_BUILTIN().
>
> Mimi

Thanks for the suggestion, will update the patch later if there are no
other comments.

>
> > + if (ret == -ENOKEY) {
> > + ret = verify_pefile_signature(kernel, kernel_len,
> > + VERIFY_USE_PLATFORM_KEYRING,
> > +     VERIFYING_KEXEC_PE_SIGNATURE);
> > + }
> > +#endif
> > + return ret;
> >  }
> >  #endif
>



--
Best Regards,
Kairui Song


Re: [RFC PATCH v2 1/2] integrity, KEYS: add a reference to platform keyring

2019-01-15 Thread Kairui Song
On Tue, Jan 15, 2019 at 11:34 PM Mimi Zohar  wrote:
>
> On Tue, 2019-01-15 at 17:45 +0800, Kairui Song wrote:
> [snip]
>
> > diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
> > index f45d6edecf99..bfabc2a8111d 100644
> > --- a/security/integrity/digsig.c
> > +++ b/security/integrity/digsig.c
> > @@ -89,6 +89,12 @@ static int __integrity_init_keyring(const unsigned int 
> > id, key_perm_t perm,
> >   keyring[id] = NULL;
> >   }
> >
> > +#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
> > + if (id == INTEGRITY_KEYRING_PLATFORM) {
> > + set_platform_trusted_keys(keyring[id]);
> > + }
> > +#endif
> > +
> >   return err;
> >  }
> >
>
> Any reason for setting it here as opposed to in the caller
> platform_keyring_init()?
>
> Mimi
>

Yes, "keyring" is static so unless I expose it to other files, it is
only accessible here. And I think there should be no problem to put
the set_platform_trusted_keys here.

-- 
Best Regards,
Kairui Song


[PATCH v2 2/2] x86, kexec_file_load: make it work with efi=noruntime or efi=old_map

2019-01-15 Thread Kairui Song
When efi=noruntime or efi=oldmap is used, EFI services won't be available
in the second kernel, therefore the second kernel will not be able to get
the ACPI RSDP address from firmware by calling EFI services and won't
boot. Previously we are expecting the user to set the acpi_rsdp=
on kernel command line for second kernel as there was no way to pass RSDP
address to second kernel.

After commit e6e094e053af ('x86/acpi, x86/boot: Take RSDP address from
boot params if available'), now it's possible to set an acpi_rsdp_addr
parameter in the boot_params passed to second kernel, this commit make
use of it, detect and set the RSDP address when it's required for second
kernel to boot.

Tested with an EFI enabled KVM VM with efi=noruntime.

Suggested-by: Dave Young 
Signed-off-by: Kairui Song 
---
 arch/x86/kernel/kexec-bzimage64.c | 21 +
 drivers/acpi/acpica/tbxfroot.c|  3 +--
 include/acpi/acpixf.h |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index 53917a3ebf94..0a90dcbd041f 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -255,8 +256,28 @@ setup_boot_parameters(struct kimage *image, struct 
boot_params *params,
/* Setup EFI state */
setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
efi_setup_data_offset);
+
+#ifdef CONFIG_ACPI
+   /* Setup ACPI RSDP pointer in case EFI is not available in second 
kernel */
+   if (!acpi_disabled && (!efi_enabled(EFI_RUNTIME_SERVICES) || 
efi_enabled(EFI_OLD_MEMMAP))) {
+   /* Copied from acpi_os_get_root_pointer accordingly */
+   params->acpi_rsdp_addr = boot_params.acpi_rsdp_addr;
+   if (!params->acpi_rsdp_addr) {
+   if (efi_enabled(EFI_CONFIG_TABLES)) {
+   if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
+   params->acpi_rsdp_addr = efi.acpi20;
+   else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
+   params->acpi_rsdp_addr = efi.acpi;
+   } else if 
(IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
+   acpi_find_root_pointer(>acpi_rsdp_addr);
+   }
+   }
+   if (!params->acpi_rsdp_addr)
+   pr_warn("RSDP is not available for second kernel\n");
+   }
 #endif
 
+#endif
/* Setup EDD info */
memcpy(params->eddbuf, boot_params.eddbuf,
EDDMAXNR * sizeof(struct edd_info));
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index 483d0ce5180a..dac1e34a931c 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -108,8 +108,7 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp 
*rsdp)
  *
  
**/
 
-acpi_status ACPI_INIT_FUNCTION
-acpi_find_root_pointer(acpi_physical_address *table_address)
+acpi_status acpi_find_root_pointer(acpi_physical_address *table_address)
 {
u8 *table_ptr;
u8 *mem_rover;
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 7aa38b648564..869d75ecaf7d 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -474,7 +474,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
acpi_reallocate_root_table(void))
 
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_find_root_pointer(acpi_physical_address
   *rsdp_address))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-- 
2.20.1



[PATCH v2 1/2] x86, kexec_file_load: Don't setup EFI info if EFI runtime is not enabled

2019-01-15 Thread Kairui Song
Currently with "efi=noruntime" in kernel command line, calling
kexec_file_load will raise below problem:

[   97.967067] BUG: unable to handle kernel NULL pointer dereference at 

[   97.967894] #PF error: [normal kernel read fault]
...
[   97.980456] Call Trace:
[   97.980724]  efi_runtime_map_copy+0x28/0x30
[   97.981267]  bzImage64_load+0x688/0x872
[   97.981794]  arch_kexec_kernel_image_load+0x6d/0x70
[   97.982441]  kimage_file_alloc_init+0x13e/0x220
[   97.983035]  __x64_sys_kexec_file_load+0x144/0x290
[   97.983586]  do_syscall_64+0x55/0x1a0
[   97.983962]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

When efi runtime is not enabled, efi memmap is not mapped, so just skip
EFI info setup.

Suggested-by: Dave Young 
Signed-off-by: Kairui Song 
---
 arch/x86/kernel/kexec-bzimage64.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index 0d5efa34f359..53917a3ebf94 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -167,6 +167,9 @@ setup_efi_state(struct boot_params *params, unsigned long 
params_load_addr,
struct efi_info *current_ei = _params.efi_info;
struct efi_info *ei = >efi_info;
 
+   if (!efi_enabled(EFI_RUNTIME_SERVICES))
+   return 0;
+
if (!current_ei->efi_memmap_size)
return 0;
 
-- 
2.20.1



[PATCH 0/2] make kexec work with efi=noruntime or efi=old_map

2019-01-15 Thread Kairui Song
This patch series fix the kexec panic on efi=noruntime or efi=old_map
and leverage acpi_rsdp_addr to make the second kernel boot up properly.

Kairui Song (2):
  x86, kexec_file_load: Don't setup EFI info if EFI runtime is not
enabled
  x86, kexec_file_load: make it work with efi=noruntime or efi=old_map

Update from V1:
 - Add a cover letter and fix some type in commit message
 - Previous patches are not sent in a single thread

 arch/x86/kernel/kexec-bzimage64.c | 24 
 drivers/acpi/acpica/tbxfroot.c|  3 +--
 include/acpi/acpixf.h |  2 +-
 3 files changed, 26 insertions(+), 3 deletions(-)

-- 
2.20.1



[RFC PATCH v2 2/2] kexec, KEYS: Make use of platform keyring for signature verify

2019-01-15 Thread Kairui Song
With KEXEC_BZIMAGE_VERIFY_SIG enabled, kexec_file_load will need to
verify the kernel image. The image might be signed with third part keys,
and the keys could be stored in firmware, then got loaded into the
.platform keyring. Now we have a symbol .platform_trusted_keyring as the
reference to .platform keyring, this patch makes use if it and allow
kexec_file_load to verify the image against keys in .platform keyring.

This commit adds a VERIFY_USE_PLATFORM_KEYRING similar to previous
VERIFY_USE_SECONDARY_KEYRING indicating that verify_pkcs7_signature
should verify the signature using platform keyring. Also, decrease
the error message log level when verification failed with -ENOKEY,
so that if called tried multiple time with different keyring it
won't generate extra noises.

Signed-off-by: Kairui Song 
---
 arch/x86/kernel/kexec-bzimage64.c | 15 ---
 certs/system_keyring.c| 11 ++-
 include/linux/verification.h  |  3 +++
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index 7d97e432cbbc..a06b04065bb1 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -534,9 +534,18 @@ static int bzImage64_cleanup(void *loader_data)
 #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
 static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
 {
-   return verify_pefile_signature(kernel, kernel_len,
-  VERIFY_USE_SECONDARY_KEYRING,
-  VERIFYING_KEXEC_PE_SIGNATURE);
+   int ret;
+   ret = verify_pefile_signature(kernel, kernel_len,
+   VERIFY_USE_SECONDARY_KEYRING,
+   VERIFYING_KEXEC_PE_SIGNATURE);
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+   if (ret == -ENOKEY) {
+   ret = verify_pefile_signature(kernel, kernel_len,
+   VERIFY_USE_PLATFORM_KEYRING,
+   VERIFYING_KEXEC_PE_SIGNATURE);
+   }
+#endif
+   return ret;
 }
 #endif
 
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 4690ef9cda8a..df2a09599bd8 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -239,12 +239,21 @@ int verify_pkcs7_signature(const void *data, size_t len,
trusted_keys = secondary_trusted_keys;
 #else
trusted_keys = builtin_trusted_keys;
+#endif
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+   } else if (trusted_keys == VERIFY_USE_PLATFORM_KEYRING) {
+   trusted_keys = platform_trusted_keys;
+   if (!trusted_keys) {
+   ret = -ENOKEY;
+   pr_devel("PKCS#7 platform keyring is not available\n");
+   goto error;
+   }
 #endif
}
ret = pkcs7_validate_trust(pkcs7, trusted_keys);
if (ret < 0) {
if (ret == -ENOKEY)
-   pr_err("PKCS#7 signature not signed with a trusted 
key\n");
+   pr_devel("PKCS#7 signature not signed with a trusted 
key\n");
goto error;
}
 
diff --git a/include/linux/verification.h b/include/linux/verification.h
index cfa4730d607a..dbd1686e9bc4 100644
--- a/include/linux/verification.h
+++ b/include/linux/verification.h
@@ -17,6 +17,9 @@
  * should be used.
  */
 #define VERIFY_USE_SECONDARY_KEYRING ((struct key *)1UL)
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+#define VERIFY_USE_PLATFORM_KEYRING  ((struct key *)2UL)
+#endif
 
 /*
  * The use to which an asymmetric key is being put.
-- 
2.20.1



[RFC PATCH v2 0/2] let kexec_file_load use platform keyring to verify the kernel image

2019-01-15 Thread Kairui Song
Hi,

This patch series adds a .platform_trusted_keys in system_keyring as the
reference to .platform keyring in integrity subsystem, when platform
keyring is being initialized it will be updated. So other component could
use this keyring as well.

This patch series also let kexec_file_load use platform keyring as fall
back if it failed to verify the image against secondary keyring, make it
possible to load kernel signed by third part key if third party key is
imported in the firmware.

After this patch kexec_file_load will be able to verify a signed PE
bzImage using keys in platform keyring.

Tested in a VM with locally signed kernel with pesign and imported the
cert to EFI's MokList variable.

Kairui Song (2):
  integrity, KEYS: add a reference to platform keyring
  kexec, KEYS: Make use of platform keyring for signature verify

Update from V1:
  - Make platform_trusted_keys static, and update commit message as suggested
by Mimi Zohar
  - Always check if platform keyring is initialized before use it

 arch/x86/kernel/kexec-bzimage64.c | 15 ---
 certs/system_keyring.c| 20 +++-
 include/keys/system_keyring.h |  5 +
 include/linux/verification.h  |  3 +++
 security/integrity/digsig.c   |  6 ++
 5 files changed, 45 insertions(+), 4 deletions(-)

-- 
2.20.1



[RFC PATCH v2 1/2] integrity, KEYS: add a reference to platform keyring

2019-01-15 Thread Kairui Song
Currently when loading new kernel via kexec_file_load syscall, it is able
to verify the signed PE bzimage against .builtin_trusted_keys or
.secondary_trusted_keys. But the image could be signed with third part
keys which will be provided by platform or firmware as EFI variable (eg.
stored in MokListRT EFI variable), and the keys won't be available in
keyrings mentioned above.

After commit 9dc92c45177a ('integrity: Define a trusted platform keyring')
a .platform keyring is introduced to store the keys provided by platform
or firmware, this keyring is intended to be used for verifying kernel
images being loaded by kexec_file_load syscall. And with a few following
up commits, keys provided by firmware is being loaded into this keyring,
and IMA-appraisal is able to use the keyring to verify kernel images.
IMA is the currently the only user of that keyring.

This patch exposes the .platform, and makes it useable for other
components. For example, kexec_file_load could use this .platform
keyring to verify the kernel image's image.

Suggested-by: Mimi Zohar 
Signed-off-by: Kairui Song 
---
 certs/system_keyring.c| 9 +
 include/keys/system_keyring.h | 5 +
 security/integrity/digsig.c   | 6 ++
 3 files changed, 20 insertions(+)

diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 81728717523d..4690ef9cda8a 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -24,6 +24,9 @@ static struct key *builtin_trusted_keys;
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
 static struct key *secondary_trusted_keys;
 #endif
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+static struct key *platform_trusted_keys;
+#endif
 
 extern __initconst const u8 system_certificate_list[];
 extern __initconst const unsigned long system_certificate_list_size;
@@ -265,4 +268,10 @@ int verify_pkcs7_signature(const void *data, size_t len,
 }
 EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
 
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+void __init set_platform_trusted_keys(struct key *keyring) {
+   platform_trusted_keys = keyring;
+}
+#endif
+
 #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 359c2f936004..9e1b7849b6aa 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -61,5 +61,10 @@ static inline struct key *get_ima_blacklist_keyring(void)
 }
 #endif /* CONFIG_IMA_BLACKLIST_KEYRING */
 
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+
+extern void __init set_platform_trusted_keys(struct key* keyring);
+
+#endif /* CONFIG_INTEGRITY_PLATFORM_KEYRING */
 
 #endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index f45d6edecf99..bfabc2a8111d 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -89,6 +89,12 @@ static int __integrity_init_keyring(const unsigned int id, 
key_perm_t perm,
keyring[id] = NULL;
}
 
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+   if (id == INTEGRITY_KEYRING_PLATFORM) {
+   set_platform_trusted_keys(keyring[id]);
+   }
+#endif
+
return err;
 }
 
-- 
2.20.1



Re: [RFC PATCH 2/2] kexec, KEYS: Make use of platform keyring for signature verify

2019-01-14 Thread Kairui Song
On Tue, Jan 15, 2019 at 10:42 AM Dave Young  wrote:
>
> On 01/14/19 at 11:10am, Mimi Zohar wrote:
> > On Sun, 2019-01-13 at 09:39 +0800, Dave Young wrote:
> > > Hi,
> > >
> > > On 01/11/19 at 11:13am, Mimi Zohar wrote:
> > > > On Fri, 2019-01-11 at 21:43 +0800, Dave Young wrote:
> > > > [snip]
> > > >
> > > > > Personally I would like to see platform key separated from integrity.
> > > > > But for the kexec_file part I think it is good at least it works with
> > > > > this fix.
> > > > >
> > > > > Acked-by: Dave Young 
> > > >
> > > > The original "platform" keyring patches that Nayna posted multiple
> > > > times were in the certs directory, but nobody commented/responded.  So
> > > > she reworked the patches, moving them to the integrity directory and
> > > > posted them (cc'ing the kexec mailing list).  It's a bit late to be
> > > > asking to move it, isn't it?
> > >
> > > Hmm, apologize for being late,  I did not get chance to have a look the
> > > old series.  Since we have the needs now, it should be still fine
> > >
> > > Maybe Kairui can check Nayna's old series, see if he can do something
> > > again?
> >
> > Whether the platform keyring is defined in certs/ or in integrity/ the
> > keyring id needs to be accessible to the other, without making the
> > keyring id global.  Moving where the platform keyring is defined is
> > not the problem.
>
> Agreed, but just feel kexec depends on IMA sounds not good.
>
> >
> > Commit a210fd32a46b ("kexec: add call to LSM hook in original
> > kexec_load syscall") introduced a new LSM hook.  Assuming
> > CONFIG_KEXEC_VERIFY_SIG is enabled, with commit b5ca117365d9 ("ima:
> > prevent kexec_load syscall based on runtime secureboot flag") we can
> > now block the kexec_load syscall.  Without being able to block the
> > kexec_load syscall, verifying the kexec image signature via the
> > kexec_file_load syscall is kind of pointless.
> >
> > Unless you're planning on writing an LSM to prevent the kexec_load
> > syscall, I assume you'll want to enable integrity anyway.
>
> User can disable kexec_load in kernel config, and only allow
> kexec_file_load.  But yes, this can be improved separately in case no
> IMA enabled.
>
> For the time being we can leave with it and fix like this series do.
>
> >
> > Mimi
> >
>
> Thanks
> Dave

Yes, for now, I think it's good to fix the problem by following this
patch series and get kexec_file_load work with platform keyring first.
Will adopt suggestion from Mimi in the previous reply and update the
patch series.

For other remaining potential issues, kexec_load not being protected,
it could be disabled by config, and the improvement may require more
discussion. And issues like where the keyring is located, dependency
to making the keyring available for more general use could be
discussed later.

--
Best Regards,
Kairui Song


Re: [RFC PATCH 2/2] kexec, KEYS: Make use of platform keyring for signature verify

2019-01-13 Thread Kairui Song
Hi, Mimi, Dave

I checked the previous patches:
https://www.spinics.net/lists/keyrings/msg03518.html
https://www.spinics.net/lists/keyrings/msg03517.html
https://www.spinics.net/lists/keyrings/msg03516.html

That the latest patched I could found that placed the platform keyring in certs/
However it didn't cc kexec list, and so I think Dave didn't receive them.

I could compose a patch to use the previous design, how do you think?


On Sun, Jan 13, 2019 at 9:40 AM Dave Young  wrote:
>
> Hi,
>
> On 01/11/19 at 11:13am, Mimi Zohar wrote:
> > On Fri, 2019-01-11 at 21:43 +0800, Dave Young wrote:
> > [snip]
> >
> > > Personally I would like to see platform key separated from integrity.
> > > But for the kexec_file part I think it is good at least it works with
> > > this fix.
> > >
> > > Acked-by: Dave Young 
> >
> > The original "platform" keyring patches that Nayna posted multiple
> > times were in the certs directory, but nobody commented/responded.  So
> > she reworked the patches, moving them to the integrity directory and
> > posted them (cc'ing the kexec mailing list).  It's a bit late to be
> > asking to move it, isn't it?
>
> Hmm, apologize for being late,  I did not get chance to have a look the
> old series.  Since we have the needs now, it should be still fine
>
> Maybe Kairui can check Nayna's old series, see if he can do something
> again?
>
> >
> > Mimi
> >
>
> Thanks
> Dave



--
Best Regards,
Kairui Song


[RFC PATCH 1/2] integrity, KEYS: add a reference to platform keyring

2019-01-09 Thread Kairui Song
Currently kexec_file_load will verify the kernel image being loaded
against .builtin_trusted_keys or .secondary_trusted_keys, but the
image could be signed with third part keys which will be provided by
platform or firmware and the keys won't be available in keyrings mentioned
above.

After commit ea93102f3224 ('integrity: Define a trusted platform keyring')
a .platform keyring is introduced to store the keys provided by platform
or firmware. And with a few following commits, now keys required to verify
the image is being imported to .platform keyring, but currently, only
IMA-appraisal could use the keyring and verify the image.

This patch exposes the .platform and makes other components, like
kexec_file_load, could use this .platform keyring to verify the
kernel image.

Suggested-by: Mimi Zohar 
Signed-off-by: Kairui Song 
---
 certs/system_keyring.c| 3 +++
 include/keys/system_keyring.h | 5 +
 security/integrity/digsig.c   | 4 
 3 files changed, 12 insertions(+)

diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 81728717523d..a61b95390b80 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -24,6 +24,9 @@ static struct key *builtin_trusted_keys;
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
 static struct key *secondary_trusted_keys;
 #endif
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+struct key *platform_trusted_keys;
+#endif
 
 extern __initconst const u8 system_certificate_list[];
 extern __initconst const unsigned long system_certificate_list_size;
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 359c2f936004..9eaf01d01036 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -61,5 +61,10 @@ static inline struct key *get_ima_blacklist_keyring(void)
 }
 #endif /* CONFIG_IMA_BLACKLIST_KEYRING */
 
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+
+extern struct key *platform_trusted_keys;
+
+#endif /* CONFIG_INTEGRITY_PLATFORM_KEYRING */
 
 #endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index f45d6edecf99..26206240388d 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -89,6 +89,10 @@ static int __integrity_init_keyring(const unsigned int id, 
key_perm_t perm,
keyring[id] = NULL;
}
 
+   if (id == INTEGRITY_KEYRING_PLATFORM) {
+   platform_trusted_keys = keyring[id];
+   }
+
return err;
 }
 
-- 
2.20.1



[RFC PATCH 0/2] let kexec_file_load use platform keyring to verify the kernel image

2019-01-09 Thread Kairui Song
Hi,

This is a different approach for the previous patch:
[RFC PATCH 0/1] KEYS, integrity: Link .platform keyring to 
.secondary_trusted_keys
make kexec_file_load be able to verify the kernel image against keys
provided by platform or firmware.

This patch adds a .platform_trusted_keys in system_keyring as the reference
to .platform keyring in integrity subsystem, when platform keyring is
being initialized it will be updated.

Another thing on my mind is that now kexec_file_load will still relay on
CONFIG_INTEGRITY_PLATFORM_KEYRING and all its dependencies to be enabled
to be able to verify the image against firmware keys. I'm thinking about
to have something like CONFIG_PLATFORM_KEYRING and make the .platform
keyring could be enabled for a more wider usage. Not sure if it's a good
idea though.

Tested in a VM with locally signed kernel with pesign and imported the
cert to EFI's MokList variable.

Kairui Song (2):
  integrity, KEYS: add a reference to platform keyring
  kexec, KEYS: Make use of platform keyring for signature verify

 arch/x86/kernel/kexec-bzimage64.c | 13 ++---
 certs/system_keyring.c| 10 +-
 include/keys/system_keyring.h |  5 +
 include/linux/verification.h  |  1 +
 security/integrity/digsig.c   |  4 
 5 files changed, 29 insertions(+), 4 deletions(-)

-- 
2.20.1



[RFC PATCH 2/2] kexec, KEYS: Make use of platform keyring for signature verify

2019-01-09 Thread Kairui Song
kexec_file_load will need to verify the kernel signed with third part
keys, and the keys could be stored in firmware, then got loaded into
the .platform keyring. Now we have a .platform_trusted_keyring
as the reference to .platform keyring, this patch makes use if it and
allow kexec_file_load to verify the image against keys in .platform
keyring.

This commit adds a VERIFY_USE_PLATFORM_KEYRING similar to previous
VERIFY_USE_SECONDARY_KEYRING indicating that verify_pkcs7_signature
should verify the signature using platform keyring. Also, decrease
the error message log level when verification failed with -ENOKEY,
so that if called tried multiple time with different keyring it
won't generate extra noises.

Signed-off-by: Kairui Song 
---
 arch/x86/kernel/kexec-bzimage64.c | 13 ++---
 certs/system_keyring.c|  7 ++-
 include/linux/verification.h  |  1 +
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index 7d97e432cbbc..a8a5c1773ccc 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -534,9 +534,16 @@ static int bzImage64_cleanup(void *loader_data)
 #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
 static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
 {
-   return verify_pefile_signature(kernel, kernel_len,
-  VERIFY_USE_SECONDARY_KEYRING,
-  VERIFYING_KEXEC_PE_SIGNATURE);
+   int ret;
+   ret = verify_pefile_signature(kernel, kernel_len,
+   VERIFY_USE_SECONDARY_KEYRING,
+   VERIFYING_KEXEC_PE_SIGNATURE);
+   if (ret == -ENOKEY) {
+   ret = verify_pefile_signature(kernel, kernel_len,
+   VERIFY_USE_PLATFORM_KEYRING,
+   VERIFYING_KEXEC_PE_SIGNATURE);
+   }
+   return ret;
 }
 #endif
 
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index a61b95390b80..7514e69e719f 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static struct key *builtin_trusted_keys;
@@ -239,12 +240,16 @@ int verify_pkcs7_signature(const void *data, size_t len,
trusted_keys = secondary_trusted_keys;
 #else
trusted_keys = builtin_trusted_keys;
+#endif
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+   } else if (trusted_keys == VERIFY_USE_PLATFORM_KEYRING) {
+   trusted_keys = platform_trusted_keys;
 #endif
}
ret = pkcs7_validate_trust(pkcs7, trusted_keys);
if (ret < 0) {
if (ret == -ENOKEY)
-   pr_err("PKCS#7 signature not signed with a trusted 
key\n");
+   pr_devel("PKCS#7 signature not signed with a trusted 
key\n");
goto error;
}
 
diff --git a/include/linux/verification.h b/include/linux/verification.h
index cfa4730d607a..018fb5f13d44 100644
--- a/include/linux/verification.h
+++ b/include/linux/verification.h
@@ -17,6 +17,7 @@
  * should be used.
  */
 #define VERIFY_USE_SECONDARY_KEYRING ((struct key *)1UL)
+#define VERIFY_USE_PLATFORM_KEYRING  ((struct key *)2UL)
 
 /*
  * The use to which an asymmetric key is being put.
-- 
2.20.1



Re: [PATCH 1/2] x86, kexec_file_load: Don't setup EFI info if EFI runtime is not enabled

2019-01-08 Thread Kairui Song
CCing more people

On Wed, Jan 9, 2019 at 2:45 PM Kairui Song  wrote:
>
> Currenly with "efi=noruntime" in kernel command line, calling
> kexec_file_load will raise below problem:
>
> [   97.967067] BUG: unable to handle kernel NULL pointer dereference at 
> 
> [   97.967894] #PF error: [normal kernel read fault]
> ...
> [   97.980456] Call Trace:
> [   97.980724]  efi_runtime_map_copy+0x28/0x30
> [   97.981267]  bzImage64_load+0x688/0x872
> [   97.981794]  arch_kexec_kernel_image_load+0x6d/0x70
> [   97.982441]  kimage_file_alloc_init+0x13e/0x220
> [   97.983035]  __x64_sys_kexec_file_load+0x144/0x290
> [   97.983586]  do_syscall_64+0x55/0x1a0
> [   97.983962]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>
> When efi runtime is not enabled, efi memmap is not mapped, so just skip
> EFI info setup.
>
> Suggested-by: Dave Young 
> Signed-off-by: Kairui Song 
> ---
>  arch/x86/kernel/kexec-bzimage64.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/x86/kernel/kexec-bzimage64.c 
> b/arch/x86/kernel/kexec-bzimage64.c
> index 0d5efa34f359..53917a3ebf94 100644
> --- a/arch/x86/kernel/kexec-bzimage64.c
> +++ b/arch/x86/kernel/kexec-bzimage64.c
> @@ -167,6 +167,9 @@ setup_efi_state(struct boot_params *params, unsigned long 
> params_load_addr,
> struct efi_info *current_ei = _params.efi_info;
> struct efi_info *ei = >efi_info;
>
> +   if (!efi_enabled(EFI_RUNTIME_SERVICES))
> +   return 0;
> +
> if (!current_ei->efi_memmap_size)
> return 0;
>
> --
> 2.20.1
>


-- 
Best Regards,
Kairui Song


Re: [PATCH 2/2] x86, kexec_file_load: make it work with efi=noruntime or efi=oldmap

2019-01-08 Thread Kairui Song
CCing more people

On Wed, Jan 9, 2019 at 2:47 PM Kairui Song  wrote:
>
> When efi=noruntime or efi=oldmap is used, EFI services won't be available
> in the second kernel, therefore the second kernel will not be able to get
> the ACPI RSDP address from firmware by calling EFI services and won't
> boot. Previously we are expecting the user to set the acpi_rsdp=
> on kernel command line for second kernel as there was no way to pass RSDP
> address to second kernel.
>
> After commit e6e094e053af ('x86/acpi, x86/boot: Take RSDP address from
> boot params if available'), now it's possible to set a acpi_rsdp_addr
> parameter in the boot_params passed to second kernel, this commit make
> use of it, detect and set the RSDP address when it's required for second
> kernel to boot.
>
> Tested with an EFI enabled KVM VM with efi=noruntime.
>
> Suggested-by: Dave Young 
> Signed-off-by: Kairui Song 
> ---
>  arch/x86/kernel/kexec-bzimage64.c | 21 +
>  drivers/acpi/acpica/tbxfroot.c|  3 +--
>  include/acpi/acpixf.h |  2 +-
>  3 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kernel/kexec-bzimage64.c 
> b/arch/x86/kernel/kexec-bzimage64.c
> index 53917a3ebf94..0a90dcbd041f 100644
> --- a/arch/x86/kernel/kexec-bzimage64.c
> +++ b/arch/x86/kernel/kexec-bzimage64.c
> @@ -20,6 +20,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include 
>  #include 
> @@ -255,8 +256,28 @@ setup_boot_parameters(struct kimage *image, struct 
> boot_params *params,
> /* Setup EFI state */
> setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
> efi_setup_data_offset);
> +
> +#ifdef CONFIG_ACPI
> +   /* Setup ACPI RSDP pointer in case EFI is not available in second 
> kernel */
> +   if (!acpi_disabled && (!efi_enabled(EFI_RUNTIME_SERVICES) || 
> efi_enabled(EFI_OLD_MEMMAP))) {
> +   /* Copied from acpi_os_get_root_pointer accordingly */
> +   params->acpi_rsdp_addr = boot_params.acpi_rsdp_addr;
> +   if (!params->acpi_rsdp_addr) {
> +   if (efi_enabled(EFI_CONFIG_TABLES)) {
> +   if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
> +   params->acpi_rsdp_addr = efi.acpi20;
> +   else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
> +   params->acpi_rsdp_addr = efi.acpi;
> +   } else if 
> (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
> +   
> acpi_find_root_pointer(>acpi_rsdp_addr);
> +   }
> +   }
> +   if (!params->acpi_rsdp_addr)
> +   pr_warn("RSDP is not available for second kernel\n");
> +   }
>  #endif
>
> +#endif
> /* Setup EDD info */
> memcpy(params->eddbuf, boot_params.eddbuf,
> EDDMAXNR * sizeof(struct edd_info));
> diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
> index 483d0ce5180a..dac1e34a931c 100644
> --- a/drivers/acpi/acpica/tbxfroot.c
> +++ b/drivers/acpi/acpica/tbxfroot.c
> @@ -108,8 +108,7 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp 
> *rsdp)
>   *
>   
> **/
>
> -acpi_status ACPI_INIT_FUNCTION
> -acpi_find_root_pointer(acpi_physical_address *table_address)
> +acpi_status acpi_find_root_pointer(acpi_physical_address *table_address)
>  {
> u8 *table_ptr;
> u8 *mem_rover;
> diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
> index 7aa38b648564..869d75ecaf7d 100644
> --- a/include/acpi/acpixf.h
> +++ b/include/acpi/acpixf.h
> @@ -474,7 +474,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
>  ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
> acpi_reallocate_root_table(void))
>
> -ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
> +ACPI_EXTERNAL_RETURN_STATUS(acpi_status
> acpi_find_root_pointer(acpi_physical_address
>*rsdp_address))
>  ACPI_EXTERNAL_RETURN_STATUS(acpi_status
> --
> 2.20.1
>


--
Best Regards,
Kairui Song


[PATCH 2/2] x86, kexec_file_load: make it work with efi=noruntime or efi=oldmap

2019-01-08 Thread Kairui Song
When efi=noruntime or efi=oldmap is used, EFI services won't be available
in the second kernel, therefore the second kernel will not be able to get
the ACPI RSDP address from firmware by calling EFI services and won't
boot. Previously we are expecting the user to set the acpi_rsdp=
on kernel command line for second kernel as there was no way to pass RSDP
address to second kernel.

After commit e6e094e053af ('x86/acpi, x86/boot: Take RSDP address from
boot params if available'), now it's possible to set a acpi_rsdp_addr
parameter in the boot_params passed to second kernel, this commit make
use of it, detect and set the RSDP address when it's required for second
kernel to boot.

Tested with an EFI enabled KVM VM with efi=noruntime.

Suggested-by: Dave Young 
Signed-off-by: Kairui Song 
---
 arch/x86/kernel/kexec-bzimage64.c | 21 +
 drivers/acpi/acpica/tbxfroot.c|  3 +--
 include/acpi/acpixf.h |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index 53917a3ebf94..0a90dcbd041f 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -255,8 +256,28 @@ setup_boot_parameters(struct kimage *image, struct 
boot_params *params,
/* Setup EFI state */
setup_efi_state(params, params_load_addr, efi_map_offset, efi_map_sz,
efi_setup_data_offset);
+
+#ifdef CONFIG_ACPI
+   /* Setup ACPI RSDP pointer in case EFI is not available in second 
kernel */
+   if (!acpi_disabled && (!efi_enabled(EFI_RUNTIME_SERVICES) || 
efi_enabled(EFI_OLD_MEMMAP))) {
+   /* Copied from acpi_os_get_root_pointer accordingly */
+   params->acpi_rsdp_addr = boot_params.acpi_rsdp_addr;
+   if (!params->acpi_rsdp_addr) {
+   if (efi_enabled(EFI_CONFIG_TABLES)) {
+   if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
+   params->acpi_rsdp_addr = efi.acpi20;
+   else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
+   params->acpi_rsdp_addr = efi.acpi;
+   } else if 
(IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
+   acpi_find_root_pointer(>acpi_rsdp_addr);
+   }
+   }
+   if (!params->acpi_rsdp_addr)
+   pr_warn("RSDP is not available for second kernel\n");
+   }
 #endif
 
+#endif
/* Setup EDD info */
memcpy(params->eddbuf, boot_params.eddbuf,
EDDMAXNR * sizeof(struct edd_info));
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index 483d0ce5180a..dac1e34a931c 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -108,8 +108,7 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp 
*rsdp)
  *
  
**/
 
-acpi_status ACPI_INIT_FUNCTION
-acpi_find_root_pointer(acpi_physical_address *table_address)
+acpi_status acpi_find_root_pointer(acpi_physical_address *table_address)
 {
u8 *table_ptr;
u8 *mem_rover;
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 7aa38b648564..869d75ecaf7d 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -474,7 +474,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
acpi_reallocate_root_table(void))
 
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
acpi_find_root_pointer(acpi_physical_address
   *rsdp_address))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-- 
2.20.1



[PATCH 1/2] x86, kexec_file_load: Don't setup EFI info if EFI runtime is not enabled

2019-01-08 Thread Kairui Song
Currenly with "efi=noruntime" in kernel command line, calling
kexec_file_load will raise below problem:

[   97.967067] BUG: unable to handle kernel NULL pointer dereference at 

[   97.967894] #PF error: [normal kernel read fault]
...
[   97.980456] Call Trace:
[   97.980724]  efi_runtime_map_copy+0x28/0x30
[   97.981267]  bzImage64_load+0x688/0x872
[   97.981794]  arch_kexec_kernel_image_load+0x6d/0x70
[   97.982441]  kimage_file_alloc_init+0x13e/0x220
[   97.983035]  __x64_sys_kexec_file_load+0x144/0x290
[   97.983586]  do_syscall_64+0x55/0x1a0
[   97.983962]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

When efi runtime is not enabled, efi memmap is not mapped, so just skip
EFI info setup.

Suggested-by: Dave Young 
Signed-off-by: Kairui Song 
---
 arch/x86/kernel/kexec-bzimage64.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/kernel/kexec-bzimage64.c 
b/arch/x86/kernel/kexec-bzimage64.c
index 0d5efa34f359..53917a3ebf94 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -167,6 +167,9 @@ setup_efi_state(struct boot_params *params, unsigned long 
params_load_addr,
struct efi_info *current_ei = _params.efi_info;
struct efi_info *ei = >efi_info;
 
+   if (!efi_enabled(EFI_RUNTIME_SERVICES))
+   return 0;
+
if (!current_ei->efi_memmap_size)
return 0;
 
-- 
2.20.1



Re: [RFC PATCH 1/1] KEYS, integrity: Link .platform keyring to .secondary_trusted_keys

2019-01-08 Thread Kairui Song
Thanks for the explanation Dave, my second thought is to let kexec use
the platform keyring directly, that is let kexec verify the image with
secondary/builtin keyring first then try platform keyring. And better
to make platform keyring independent of integrity subsystem, so kexec
could verify the image and don't depend on integrity. Any thought?

On Wed, Jan 9, 2019 at 9:34 AM Dave Young  wrote:
>
> CC kexec list
> On 01/08/19 at 10:18am, Mimi Zohar wrote:
> > [Cc'ing the LSM and integrity mailing lists]
> >
> > Repeating my comment on PATCH 0/1 here with the expanded set of
> > mailing lists.
> >
> > The builtin and secondary keyrings have a signature change of trust
> > rooted in the signed kernel image.  Adding the pre-boot keys to the
> > secondary keyring breaks that signature chain of trust.
> >
> > Please do NOT add the pre-boot "platform" keys to the secondary
> > keyring.
>
> If we regard kexec as a bootloader, it sounds natural to use the
> platform key to verify the signature with kexec_file_load syscall.
>
> It will be hard for user to manually sign a kernel and import the key
> then to reuse kexec_file_load.
>
> I think we do not care if platform key can be added to secondary or not,
> any suggestions how can kexec_file to use the platform key?
>
> >
> > Mimi
> >
> >
> > On Tue, 2019-01-08 at 16:12 +0800, Kairui Song wrote:
> > > Currently kexec may need to verify the kerne image, and the kernel image
> > > could be signed with third part keys which are provided by paltform or
> > > firmware (eg. stored in MokListRT EFI variable). And the same time,
> > > kexec_file_load will only verify the image agains .builtin_trusted_keys
> > > or .secondary_trusted_keys according to configuration, but there is no
> > > way for kexec_file_load to verify the image against any third part keys
> > > mentioned above.
> > >
> > > In ea93102f3224 ('integrity: Define a trusted platform keyring') a
> > > .platform keyring is introduced to store the keys provided by platform
> > > or firmware. And with a few following commits including 15ea0e1e3e185
> > > ('efi: Import certificates from UEFI Secure Boot'), now keys required to
> > > verify the image is being imported to .paltform keyring, and later
> > > IMA-appraisal could access the keyring and verify the image.
> > >
> > > This patch links the .platform keyring to .secondary_trusted_keys so
> > > kexec_file_load could also leverage the .platform keyring to verify the
> > > kernel image.
> > >
> > > Signed-off-by: Kairui Song 
> > > ---
> > >  certs/system_keyring.c  | 30 ++
> > >  include/keys/platform_keyring.h | 12 
> > >  security/integrity/digsig.c |  7 +++
> > >  3 files changed, 49 insertions(+)
> > >  create mode 100644 include/keys/platform_keyring.h
> > >
> > > diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> > > index 81728717523d..dcef0259e149 100644
> > > --- a/certs/system_keyring.c
> > > +++ b/certs/system_keyring.c
> > > @@ -18,12 +18,14 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >
> > >  static struct key *builtin_trusted_keys;
> > >  #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
> > >  static struct key *secondary_trusted_keys;
> > >  #endif
> > > +static struct key *platform_keys = NULL;
> > >
> > >  extern __initconst const u8 system_certificate_list[];
> > >  extern __initconst const unsigned long system_certificate_list_size;
> > > @@ -67,6 +69,12 @@ int restrict_link_by_builtin_and_secondary_trusted(
> > > /* Allow the builtin keyring to be added to the secondary */
> > > return 0;
> > >
> > > +   if (type == _type_keyring &&
> > > +   dest_keyring == secondary_trusted_keys &&
> > > +   payload == _keys->payload)
> > > +   /* Allow the platform keyring to be added to the secondary */
> > > +   return 0;
> > > +
> > > return restrict_link_by_signature(dest_keyring, type, payload,
> > >   secondary_trusted_keys);
> > >  }
> > > @@ -188,6 +196,28 @@ static __init int load_system_certificate_list(void)
> > >  }
> > >  late_initcall(load_system_certificate_list);
> > >
> > > +#if defined(CONFIG_INTEGRITY_PLATFORM_KEYRING

[RFC PATCH 1/1] KEYS, integrity: Link .platform keyring to .secondary_trusted_keys

2019-01-08 Thread Kairui Song
Currently kexec may need to verify the kerne image, and the kernel image
could be signed with third part keys which are provided by paltform or
firmware (eg. stored in MokListRT EFI variable). And the same time,
kexec_file_load will only verify the image agains .builtin_trusted_keys
or .secondary_trusted_keys according to configuration, but there is no
way for kexec_file_load to verify the image against any third part keys
mentioned above.

In ea93102f3224 ('integrity: Define a trusted platform keyring') a
.platform keyring is introduced to store the keys provided by platform
or firmware. And with a few following commits including 15ea0e1e3e185
('efi: Import certificates from UEFI Secure Boot'), now keys required to
verify the image is being imported to .paltform keyring, and later
IMA-appraisal could access the keyring and verify the image.

This patch links the .platform keyring to .secondary_trusted_keys so
kexec_file_load could also leverage the .platform keyring to verify the
kernel image.

Signed-off-by: Kairui Song 
---
 certs/system_keyring.c  | 30 ++
 include/keys/platform_keyring.h | 12 
 security/integrity/digsig.c |  7 +++
 3 files changed, 49 insertions(+)
 create mode 100644 include/keys/platform_keyring.h

diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 81728717523d..dcef0259e149 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -18,12 +18,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static struct key *builtin_trusted_keys;
 #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
 static struct key *secondary_trusted_keys;
 #endif
+static struct key *platform_keys = NULL;
 
 extern __initconst const u8 system_certificate_list[];
 extern __initconst const unsigned long system_certificate_list_size;
@@ -67,6 +69,12 @@ int restrict_link_by_builtin_and_secondary_trusted(
/* Allow the builtin keyring to be added to the secondary */
return 0;
 
+   if (type == _type_keyring &&
+   dest_keyring == secondary_trusted_keys &&
+   payload == _keys->payload)
+   /* Allow the platform keyring to be added to the secondary */
+   return 0;
+
return restrict_link_by_signature(dest_keyring, type, payload,
  secondary_trusted_keys);
 }
@@ -188,6 +196,28 @@ static __init int load_system_certificate_list(void)
 }
 late_initcall(load_system_certificate_list);
 
+#if defined(CONFIG_INTEGRITY_PLATFORM_KEYRING) && 
defined(CONFIG_SECONDARY_TRUSTED_KEYRING)
+
+/*
+ * Link .platform keyring to .secondary_trusted_key keyring
+ */
+static __init int load_platform_certificate_list(void)
+{
+   int ret = 0;
+   platform_keys = integrity_get_platform_keyring();
+   if (!platform_keys) {
+   return 0;
+   }
+   ret = key_link(secondary_trusted_keys, platform_keys);
+   if (ret < 0) {
+   pr_err("Failed to link platform keyring: %d", ret);
+   }
+   return 0;
+}
+late_initcall(load_platform_certificate_list);
+
+#endif
+
 #ifdef CONFIG_SYSTEM_DATA_VERIFICATION
 
 /**
diff --git a/include/keys/platform_keyring.h b/include/keys/platform_keyring.h
new file mode 100644
index ..4f92ed6c0b42
--- /dev/null
+++ b/include/keys/platform_keyring.h
@@ -0,0 +1,12 @@
+#ifndef _KEYS_PLATFORM_KEYRING_H
+#define _KEYS_PLATFORM_KEYRING_H
+
+#include 
+
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+
+extern const struct key* __init integrity_get_platform_keyring(void);
+
+#endif /* CONFIG_INTEGRITY_PLATFORM_KEYRING */
+
+#endif /* _KEYS_SYSTEM_KEYRING_H */
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index f45d6edecf99..397758d4f12d 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -176,3 +176,10 @@ int __init integrity_load_cert(const unsigned int id, 
const char *source,
pr_info("Loading X.509 certificate: %s\n", source);
return integrity_add_key(id, data, len, perm);
 }
+
+#ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING
+struct key* __init integrity_get_platform_keyring(void)
+{
+   return keyring[INTEGRITY_KEYRING_PLATFORM];
+}
+#endif
-- 
2.20.1



[RFC PATCH 0/1] KEYS, integrity: Link .platform keyring to .secondary_trusted_keys

2019-01-08 Thread Kairui Song
Hi, as the subject, this is a patch that links the new introduced
.platform keyring into .secondary_trusted_keys keyring. This is
mainly for the kexec_file_load, make kexec_file_load be able to verify
the kernel image agains keys provided by platform or firmware.
kexec_file_load already could verify the image agains secondary_trusted_keys
if secondary_trusted_keys exits, so this will make kexec_file_load be ware
of platform keys as well.

This may also useful for things like module sign verify that are using
secondary_trusted_keys. I'm not sure if it will be better to move the
INTEGRITY_PLATFORM_KEYRING to certs/ and let integrity subsystem use
the keyring there, so just linked the .platform keyring into kernel's
.secondary_trusted_keys keyring.

It workd for my case, tested in a VM, I signed the kernel image locally
with pesign and imported the cert to EFI's MokList variable.

Kairui Song (1):
  KEYS, integrity: Link .platform keyring to .secondary_trusted_keys

 certs/system_keyring.c  | 30 ++
 include/keys/platform_keyring.h | 12 
 security/integrity/digsig.c |  7 +++
 3 files changed, 49 insertions(+)
 create mode 100644 include/keys/platform_keyring.h

-- 
2.20.1



[PATCH v2] x86/gart/kcore: Exclude GART aperture from kcore

2019-01-02 Thread Kairui Song
On machines where the GART aperture is mapped over physical RAM,
/proc/kcore contains the GART aperture range and reading it may lead
to kernel panic.

In 'commit 2a3e83c6f96c ("x86/gart: Exclude GART aperture from vmcore")',
a special workaround is applied for vmcore to let /proc/vmcore return
zeroes when attempting to read the aperture region, as vmcore and kcore
have the same issue, and after 'commit 707d4eefbdb3 ("Revert "[PATCH]
Insert GART region into resource map"")', userspace tools can't detect and
exclude GART region.

This patch applies the same workaround for kcore. Let /proc/kcore return
zeroes too when trying to read the aperture region to fix the issue that
reading GART region may raise unexpected exceptions.

This applies to both first and second kernels as GART may get
initialized in the first and second kernels.

To get the same workaround work for kcore, this patch implement a hook
infrastructure for kcore which is same as the hook infrastructure for
vmcore introduced in 'commit 997c136f518c ("fs/proc/vmcore.c: add hook
to read_from_oldmem() to check for non-ram pages")'', and reuses the
checking function gart_oldmem_pfn_is_ram introduced in
'commit 2a3e83c6f96c ("x86/gart: Exclude GART aperture from vmcore"),'
as the hook function, but rename to gart_mem_pfn_is_ram as now it's
for a more generic use.

Suggested-by: Baoquan He 
Signed-off-by: Kairui Song 
---
Update from V1:
- Fix a complie error when CONFIG_PROC_KCORE is not set

 arch/x86/kernel/aperture_64.c | 12 +---
 fs/proc/kcore.c   | 34 ++
 include/linux/kcore.h |  3 +++
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 58176b56354e..c8a56f083419 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) "AGP: " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -57,7 +58,7 @@ int fallback_aper_force __initdata;
 
 int fix_aperture __initdata = 1;
 
-#ifdef CONFIG_PROC_VMCORE
+#if defined(CONFIG_PROC_VMCORE) || defined(CONFIG_PROC_KCORE)
 /*
  * If the first kernel maps the aperture over e820 RAM, the kdump kernel will
  * use the same range because it will remain configured in the northbridge.
@@ -66,7 +67,7 @@ int fix_aperture __initdata = 1;
  */
 static unsigned long aperture_pfn_start, aperture_page_count;
 
-static int gart_oldmem_pfn_is_ram(unsigned long pfn)
+static int gart_mem_pfn_is_ram(unsigned long pfn)
 {
return likely((pfn < aperture_pfn_start) ||
  (pfn >= aperture_pfn_start + aperture_page_count));
@@ -76,7 +77,12 @@ static void exclude_from_vmcore(u64 aper_base, u32 
aper_order)
 {
aperture_pfn_start = aper_base >> PAGE_SHIFT;
aperture_page_count = (32 * 1024 * 1024) << aper_order >> PAGE_SHIFT;
-   WARN_ON(register_oldmem_pfn_is_ram(_oldmem_pfn_is_ram));
+#ifdef CONFIG_PROC_VMCORE
+   WARN_ON(register_oldmem_pfn_is_ram(_mem_pfn_is_ram));
+#endif
+#ifdef CONFIG_PROC_KCORE
+   WARN_ON(register_mem_pfn_is_ram(_mem_pfn_is_ram));
+#endif
 }
 #else
 static void exclude_from_vmcore(u64 aper_base, u32 aper_order)
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index bbcc185062bb..24e13fcc31ea 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -54,6 +54,35 @@ static LIST_HEAD(kclist_head);
 static DECLARE_RWSEM(kclist_lock);
 static int kcore_need_update = 1;
 
+static int (*mem_pfn_is_ram)(unsigned long pfn);
+
+int register_mem_pfn_is_ram(int (*fn)(unsigned long pfn))
+{
+   if (mem_pfn_is_ram)
+   return -EBUSY;
+   mem_pfn_is_ram = fn;
+   return 0;
+}
+
+void unregister_mem_pfn_is_ram(void)
+{
+   mem_pfn_is_ram = NULL;
+   wmb();
+}
+
+static int pfn_is_ram(unsigned long pfn)
+{
+   int (*fn)(unsigned long pfn);
+   /* pfn is ram unless fn() checks pagetype */
+   int ret = 1;
+
+   fn = mem_pfn_is_ram;
+   if (fn)
+   ret = fn(pfn);
+
+   return ret;
+}
+
 /* This doesn't grab kclist_lock, so it should only be used at init time. */
 void __init kclist_add(struct kcore_list *new, void *addr, size_t size,
   int type)
@@ -465,6 +494,11 @@ read_kcore(struct file *file, char __user *buffer, size_t 
buflen, loff_t *fpos)
goto out;
}
m = NULL;   /* skip the list anchor */
+   } else if (!pfn_is_ram(__pa(start) >> PAGE_SHIFT)) {
+   if (clear_user(buffer, tsz)) {
+   ret = -EFAULT;
+   goto out;
+   }
} else if (m->type == KCORE_VMALLOC) {
vread(buf, (char *)start, tsz);
/* we have to zero-fill user buffer eve

[PATCH 1/1] x86/gart/kcore: Exclude GART aperture from kcore

2018-12-20 Thread Kairui Song
On machines where the GART aperture is mapped over physical RAM,
/proc/kcore contains the GART aperture range and reading it may lead
to kernel panic.

In 'commit 2a3e83c6f96c ("x86/gart: Exclude GART aperture from vmcore")',
a special workaround is applied for vmcore to let /proc/vmcore return
zeroes when attempting to read the aperture region, as vmcore and kcore
have the same issue, and after 'commit 707d4eefbdb3 ("Revert "[PATCH]
Insert GART region into resource map"")', userspace tools can't detect and
exclude GART region.

This patch applies the same workaround for kcore. Let /proc/kcore return
zeroes too when trying to read the aperture region to fix the issue that
reading GART region may raise unexpected exceptions.

This applies to both first and second kernels as GART may get
initialized in the first and second kernels.

To get the same workaround work for kcore, this patch implement a hook
infrastructure for kcore which is same as the hook infrastructure for
vmcore introduced in 'commit 997c136f518c ("fs/proc/vmcore.c: add hook
to read_from_oldmem() to check for non-ram pages")'', and reuses the
checking function gart_oldmem_pfn_is_ram introduced in
'commit 2a3e83c6f96c ("x86/gart: Exclude GART aperture from vmcore"),'
as the hook function, but rename to gart_mem_pfn_is_ram as now it's
for a more generic use.

Suggested-by: Baoquan He 
Signed-off-by: Kairui Song 
---
 arch/x86/kernel/aperture_64.c |  6 --
 fs/proc/kcore.c   | 34 ++
 include/linux/kcore.h |  3 +++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 2c4d5ece7456..e2e45ae63309 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -14,6 +14,7 @@
 #define pr_fmt(fmt) "AGP: " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -66,7 +67,7 @@ int fix_aperture __initdata = 1;
  */
 static unsigned long aperture_pfn_start, aperture_page_count;
 
-static int gart_oldmem_pfn_is_ram(unsigned long pfn)
+static int gart_mem_pfn_is_ram(unsigned long pfn)
 {
return likely((pfn < aperture_pfn_start) ||
  (pfn >= aperture_pfn_start + aperture_page_count));
@@ -76,7 +77,8 @@ static void exclude_from_vmcore(u64 aper_base, u32 aper_order)
 {
aperture_pfn_start = aper_base >> PAGE_SHIFT;
aperture_page_count = (32 * 1024 * 1024) << aper_order >> PAGE_SHIFT;
-   WARN_ON(register_oldmem_pfn_is_ram(_oldmem_pfn_is_ram));
+   WARN_ON(register_oldmem_pfn_is_ram(_mem_pfn_is_ram));
+   WARN_ON(register_mem_pfn_is_ram(_mem_pfn_is_ram));
 }
 #else
 static void exclude_from_vmcore(u64 aper_base, u32 aper_order)
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index bbcc185062bb..24e13fcc31ea 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -54,6 +54,35 @@ static LIST_HEAD(kclist_head);
 static DECLARE_RWSEM(kclist_lock);
 static int kcore_need_update = 1;
 
+static int (*mem_pfn_is_ram)(unsigned long pfn);
+
+int register_mem_pfn_is_ram(int (*fn)(unsigned long pfn))
+{
+   if (mem_pfn_is_ram)
+   return -EBUSY;
+   mem_pfn_is_ram = fn;
+   return 0;
+}
+
+void unregister_mem_pfn_is_ram(void)
+{
+   mem_pfn_is_ram = NULL;
+   wmb();
+}
+
+static int pfn_is_ram(unsigned long pfn)
+{
+   int (*fn)(unsigned long pfn);
+   /* pfn is ram unless fn() checks pagetype */
+   int ret = 1;
+
+   fn = mem_pfn_is_ram;
+   if (fn)
+   ret = fn(pfn);
+
+   return ret;
+}
+
 /* This doesn't grab kclist_lock, so it should only be used at init time. */
 void __init kclist_add(struct kcore_list *new, void *addr, size_t size,
   int type)
@@ -465,6 +494,11 @@ read_kcore(struct file *file, char __user *buffer, size_t 
buflen, loff_t *fpos)
goto out;
}
m = NULL;   /* skip the list anchor */
+   } else if (!pfn_is_ram(__pa(start) >> PAGE_SHIFT)) {
+   if (clear_user(buffer, tsz)) {
+   ret = -EFAULT;
+   goto out;
+   }
} else if (m->type == KCORE_VMALLOC) {
vread(buf, (char *)start, tsz);
/* we have to zero-fill user buffer even if no read */
diff --git a/include/linux/kcore.h b/include/linux/kcore.h
index 8c3f8c14eeaa..6818156fe520 100644
--- a/include/linux/kcore.h
+++ b/include/linux/kcore.h
@@ -56,4 +56,7 @@ void kclist_add_remap(struct kcore_list *m, void *addr, void 
*vaddr, size_t sz)
 }
 #endif
 
+extern int register_mem_pfn_is_ram(int (*fn)(unsigned long pfn));
+extern void unregister_mem_pfn_is_ram(void);
+
 #endif /* _LINUX_KCORE_H */
-- 
2.19.1



[tip:x86/urgent] x86/boot: Fix kexec booting failure in the SEV bit detection code

2018-09-27 Thread tip-bot for Kairui Song
Commit-ID:  bdec8d7fa55e6f5314ed72e5a0b435d90ff90548
Gitweb: https://git.kernel.org/tip/bdec8d7fa55e6f5314ed72e5a0b435d90ff90548
Author: Kairui Song 
AuthorDate: Thu, 27 Sep 2018 20:38:45 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 19:35:03 +0200

x86/boot: Fix kexec booting failure in the SEV bit detection code

Commit

  1958b5fc4010 ("x86/boot: Add early boot support when running with SEV active")

can occasionally cause system resets when kexec-ing a second kernel even
if SEV is not active.

That's because get_sev_encryption_bit() uses 32-bit rIP-relative
addressing to read the value of enc_bit - a variable which caches a
previously detected encryption bit position - but kexec may allocate
the early boot code to a higher location, beyond the 32-bit addressing
limit.

In this case, garbage will be read and get_sev_encryption_bit() will
return the wrong value, leading to accessing memory with the wrong
encryption setting.

Therefore, remove enc_bit, and thus get rid of the need to do 32-bit
rIP-relative addressing in the first place.

 [ bp: massage commit message heavily. ]

Fixes: 1958b5fc4010 ("x86/boot: Add early boot support when running with SEV 
active")
Suggested-by: Borislav Petkov 
Signed-off-by: Kairui Song 
Signed-off-by: Borislav Petkov 
Reviewed-by: Tom Lendacky 
Cc: linux-kernel@vger.kernel.org
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: brijesh.si...@amd.com
Cc: ke...@lists.infradead.org
Cc: dyo...@redhat.com
Cc: b...@redhat.com
Cc: gh...@redhat.com
Link: https://lkml.kernel.org/r/20180927123845.32052-1-kas...@redhat.com
---
 arch/x86/boot/compressed/mem_encrypt.S | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/arch/x86/boot/compressed/mem_encrypt.S 
b/arch/x86/boot/compressed/mem_encrypt.S
index eaa843a52907..a480356e0ed8 100644
--- a/arch/x86/boot/compressed/mem_encrypt.S
+++ b/arch/x86/boot/compressed/mem_encrypt.S
@@ -25,20 +25,6 @@ ENTRY(get_sev_encryption_bit)
push%ebx
push%ecx
push%edx
-   push%edi
-
-   /*
-* RIP-relative addressing is needed to access the encryption bit
-* variable. Since we are running in 32-bit mode we need this call/pop
-* sequence to get the proper relative addressing.
-*/
-   call1f
-1: popl%edi
-   subl$1b, %edi
-
-   movlenc_bit(%edi), %eax
-   cmpl$0, %eax
-   jge .Lsev_exit
 
/* Check if running under a hypervisor */
movl$1, %eax
@@ -69,15 +55,12 @@ ENTRY(get_sev_encryption_bit)
 
movl%ebx, %eax
andl$0x3f, %eax /* Return the encryption bit location */
-   movl%eax, enc_bit(%edi)
jmp .Lsev_exit
 
 .Lno_sev:
xor %eax, %eax
-   movl%eax, enc_bit(%edi)
 
 .Lsev_exit:
-   pop %edi
pop %edx
pop %ecx
pop %ebx
@@ -113,8 +96,6 @@ ENTRY(set_sev_encryption_mask)
 ENDPROC(set_sev_encryption_mask)
 
.data
-enc_bit:
-   .int0x
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
.balign 8


[tip:x86/urgent] x86/boot: Fix kexec booting failure in the SEV bit detection code

2018-09-27 Thread tip-bot for Kairui Song
Commit-ID:  bdec8d7fa55e6f5314ed72e5a0b435d90ff90548
Gitweb: https://git.kernel.org/tip/bdec8d7fa55e6f5314ed72e5a0b435d90ff90548
Author: Kairui Song 
AuthorDate: Thu, 27 Sep 2018 20:38:45 +0800
Committer:  Borislav Petkov 
CommitDate: Thu, 27 Sep 2018 19:35:03 +0200

x86/boot: Fix kexec booting failure in the SEV bit detection code

Commit

  1958b5fc4010 ("x86/boot: Add early boot support when running with SEV active")

can occasionally cause system resets when kexec-ing a second kernel even
if SEV is not active.

That's because get_sev_encryption_bit() uses 32-bit rIP-relative
addressing to read the value of enc_bit - a variable which caches a
previously detected encryption bit position - but kexec may allocate
the early boot code to a higher location, beyond the 32-bit addressing
limit.

In this case, garbage will be read and get_sev_encryption_bit() will
return the wrong value, leading to accessing memory with the wrong
encryption setting.

Therefore, remove enc_bit, and thus get rid of the need to do 32-bit
rIP-relative addressing in the first place.

 [ bp: massage commit message heavily. ]

Fixes: 1958b5fc4010 ("x86/boot: Add early boot support when running with SEV 
active")
Suggested-by: Borislav Petkov 
Signed-off-by: Kairui Song 
Signed-off-by: Borislav Petkov 
Reviewed-by: Tom Lendacky 
Cc: linux-kernel@vger.kernel.org
Cc: t...@linutronix.de
Cc: mi...@redhat.com
Cc: h...@zytor.com
Cc: brijesh.si...@amd.com
Cc: ke...@lists.infradead.org
Cc: dyo...@redhat.com
Cc: b...@redhat.com
Cc: gh...@redhat.com
Link: https://lkml.kernel.org/r/20180927123845.32052-1-kas...@redhat.com
---
 arch/x86/boot/compressed/mem_encrypt.S | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/arch/x86/boot/compressed/mem_encrypt.S 
b/arch/x86/boot/compressed/mem_encrypt.S
index eaa843a52907..a480356e0ed8 100644
--- a/arch/x86/boot/compressed/mem_encrypt.S
+++ b/arch/x86/boot/compressed/mem_encrypt.S
@@ -25,20 +25,6 @@ ENTRY(get_sev_encryption_bit)
push%ebx
push%ecx
push%edx
-   push%edi
-
-   /*
-* RIP-relative addressing is needed to access the encryption bit
-* variable. Since we are running in 32-bit mode we need this call/pop
-* sequence to get the proper relative addressing.
-*/
-   call1f
-1: popl%edi
-   subl$1b, %edi
-
-   movlenc_bit(%edi), %eax
-   cmpl$0, %eax
-   jge .Lsev_exit
 
/* Check if running under a hypervisor */
movl$1, %eax
@@ -69,15 +55,12 @@ ENTRY(get_sev_encryption_bit)
 
movl%ebx, %eax
andl$0x3f, %eax /* Return the encryption bit location */
-   movl%eax, enc_bit(%edi)
jmp .Lsev_exit
 
 .Lno_sev:
xor %eax, %eax
-   movl%eax, enc_bit(%edi)
 
 .Lsev_exit:
-   pop %edi
pop %edx
pop %ecx
pop %ebx
@@ -113,8 +96,6 @@ ENTRY(set_sev_encryption_mask)
 ENDPROC(set_sev_encryption_mask)
 
.data
-enc_bit:
-   .int0x
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
.balign 8


[PATCH] x86/boot: Fix kexec booting failure after SEV early boot support

2018-09-27 Thread Kairui Song
Commit 1958b5fc4010 ("x86/boot: Add early boot support when running
with SEV active") is causing kexec becomes sometimes unstable even if
SEV is not active. kexec reboot won't start a second kernel bypassing
BIOS boot process, instead, the system got reset.

That's because, in get_sev_encryption_bit function, we are using
32-bit RIP-relative addressing to read the value of enc_bit, but
kexec may alloc the early boot up code to a higher location, which
is beyond 32-bit addressing limit. Some garbage will be read and
get_sev_encryption_bit will return the wrong value, which leads to
wrong memory page flag.

This patch removes the use of enc_bit, as currently, enc_bit's only
purpose is to avoid duplicated encryption bit reading, but the overhead
of reading encryption bit is so tiny, so no need to cache that.

Fixes: 1958b5fc4010 ("x86/boot: Add early boot support when running with SEV 
active")
Suggested-by: Borislav Petkov 
Signed-off-by: Kairui Song 
---
 arch/x86/boot/compressed/mem_encrypt.S | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/arch/x86/boot/compressed/mem_encrypt.S 
b/arch/x86/boot/compressed/mem_encrypt.S
index eaa843a52907..a480356e0ed8 100644
--- a/arch/x86/boot/compressed/mem_encrypt.S
+++ b/arch/x86/boot/compressed/mem_encrypt.S
@@ -25,20 +25,6 @@ ENTRY(get_sev_encryption_bit)
push%ebx
push%ecx
push%edx
-   push%edi
-
-   /*
-* RIP-relative addressing is needed to access the encryption bit
-* variable. Since we are running in 32-bit mode we need this call/pop
-* sequence to get the proper relative addressing.
-*/
-   call1f
-1: popl%edi
-   subl$1b, %edi
-
-   movlenc_bit(%edi), %eax
-   cmpl$0, %eax
-   jge .Lsev_exit
 
/* Check if running under a hypervisor */
movl$1, %eax
@@ -69,15 +55,12 @@ ENTRY(get_sev_encryption_bit)
 
movl%ebx, %eax
andl$0x3f, %eax /* Return the encryption bit location */
-   movl%eax, enc_bit(%edi)
jmp .Lsev_exit
 
 .Lno_sev:
xor %eax, %eax
-   movl%eax, enc_bit(%edi)
 
 .Lsev_exit:
-   pop %edi
pop %edx
pop %ecx
pop %ebx
@@ -113,8 +96,6 @@ ENTRY(set_sev_encryption_mask)
 ENDPROC(set_sev_encryption_mask)
 
.data
-enc_bit:
-   .int0x
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
.balign 8
-- 
2.17.1



[PATCH] x86/boot: Fix kexec booting failure after SEV early boot support

2018-09-27 Thread Kairui Song
Commit 1958b5fc4010 ("x86/boot: Add early boot support when running
with SEV active") is causing kexec becomes sometimes unstable even if
SEV is not active. kexec reboot won't start a second kernel bypassing
BIOS boot process, instead, the system got reset.

That's because, in get_sev_encryption_bit function, we are using
32-bit RIP-relative addressing to read the value of enc_bit, but
kexec may alloc the early boot up code to a higher location, which
is beyond 32-bit addressing limit. Some garbage will be read and
get_sev_encryption_bit will return the wrong value, which leads to
wrong memory page flag.

This patch removes the use of enc_bit, as currently, enc_bit's only
purpose is to avoid duplicated encryption bit reading, but the overhead
of reading encryption bit is so tiny, so no need to cache that.

Fixes: 1958b5fc4010 ("x86/boot: Add early boot support when running with SEV 
active")
Suggested-by: Borislav Petkov 
Signed-off-by: Kairui Song 
---
 arch/x86/boot/compressed/mem_encrypt.S | 19 ---
 1 file changed, 19 deletions(-)

diff --git a/arch/x86/boot/compressed/mem_encrypt.S 
b/arch/x86/boot/compressed/mem_encrypt.S
index eaa843a52907..a480356e0ed8 100644
--- a/arch/x86/boot/compressed/mem_encrypt.S
+++ b/arch/x86/boot/compressed/mem_encrypt.S
@@ -25,20 +25,6 @@ ENTRY(get_sev_encryption_bit)
push%ebx
push%ecx
push%edx
-   push%edi
-
-   /*
-* RIP-relative addressing is needed to access the encryption bit
-* variable. Since we are running in 32-bit mode we need this call/pop
-* sequence to get the proper relative addressing.
-*/
-   call1f
-1: popl%edi
-   subl$1b, %edi
-
-   movlenc_bit(%edi), %eax
-   cmpl$0, %eax
-   jge .Lsev_exit
 
/* Check if running under a hypervisor */
movl$1, %eax
@@ -69,15 +55,12 @@ ENTRY(get_sev_encryption_bit)
 
movl%ebx, %eax
andl$0x3f, %eax /* Return the encryption bit location */
-   movl%eax, enc_bit(%edi)
jmp .Lsev_exit
 
 .Lno_sev:
xor %eax, %eax
-   movl%eax, enc_bit(%edi)
 
 .Lsev_exit:
-   pop %edi
pop %edx
pop %ecx
pop %ebx
@@ -113,8 +96,6 @@ ENTRY(set_sev_encryption_mask)
 ENDPROC(set_sev_encryption_mask)
 
.data
-enc_bit:
-   .int0x
 
 #ifdef CONFIG_AMD_MEM_ENCRYPT
.balign 8
-- 
2.17.1



<    1   2