diff mbox series

[v3,6/7] ima: configure memory to log events between kexec load and execute

Message ID 20231216010729.2904751-7-tusharsu@linux.microsoft.com (mailing list archive)
State New, archived
Headers show
Series ima: kexec: measure events between kexec load and execute | expand

Commit Message

Tushar Sugandhi Dec. 16, 2023, 1:07 a.m. UTC
IMA currently allocates half a PAGE_SIZE for the extra events that would
be measured between kexec 'load' and 'execute'.  Depending on the IMA
policy and the system state, that memory may not be sufficient to hold
the extra IMA events measured after kexec 'load'.  The memory
requirements vary from system to system and they should be configurable.

Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the
extra memory (in kb) to be allocated for IMA measurements added in the
window from kexec 'load' to kexec 'execute'.

Update ima_add_kexec_buffer() function to allocate memory based on the 
Kconfig option value, rather than the currently hardcoded one.

Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
---
 security/integrity/ima/Kconfig     |  9 +++++++++
 security/integrity/ima/ima_kexec.c | 13 ++++++++-----
 2 files changed, 17 insertions(+), 5 deletions(-)

Comments

Mimi Zohar Dec. 20, 2023, 8:15 p.m. UTC | #1
Hi Tushar,

The Subject line should include the word "extra".   The use of the
extra memory isn't limited to the measurements between the kexec load
and exec.  Additional records could be added as a result of the kexec
load itself.  Let's simplify the title to "ima: make the kexec extra
memory configurable".

Please remove any references to measurements between kexec load and
execute.

On Fri, 2023-12-15 at 17:07 -0800, Tushar Sugandhi wrote:
> IMA currently allocates half a PAGE_SIZE for the extra events that would
> be measured between kexec 'load' and 'execute'.  Depending on the IMA
> policy and the system state, that memory may not be sufficient to hold
> the extra IMA events measured after kexec 'load'.  The memory
> requirements vary from system to system and they should be configurable.

The extra memory allocated for carrying the IMA measurement list across
kexec is hardcoded as a half a PAGE.   Make it configurable.

> Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the
> extra memory (in kb) to be allocated for IMA measurements added in the
> window from kexec 'load' to kexec 'execute'.

> Update ima_add_kexec_buffer() function to allocate memory based on the 
> Kconfig option value, rather than the currently hardcoded one.
> 
> Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
> ---
>  security/integrity/ima/Kconfig     |  9 +++++++++
>  security/integrity/ima/ima_kexec.c | 13 ++++++++-----
>  2 files changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
> index 60a511c6b583..8792b7aab768 100644
> --- a/security/integrity/ima/Kconfig
> +++ b/security/integrity/ima/Kconfig
> @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
>  	default n
>  	help
>  	   This option disables htable to allow measurement of duplicate records.
> +
> +config IMA_KEXEC_EXTRA_MEMORY_KB
> +	int
> +	depends on IMA && IMA_KEXEC
> +	default 64

Since this isn't optional, the default should remain as a half page. 
Since a page is architecture specific, the default will need to be arch
 specific.

thanks,

Mimih

> +	help
> +	  IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be
> +	  allocated (in kb) for IMA measurements added in the window
> +	  from kexec 'load' to kexec 'execute'.
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> index 55bd5362262e..063da9c834a0 100644
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -128,15 +128,18 @@ void ima_add_kexec_buffer(struct kimage *image)
>  	int ret;
>  
>  	/*
> -	 * Reserve an extra half page of memory for additional measurements
> -	 * added during the kexec load.
> +	 * Reserve extra memory for measurements added in the window from
> +	 * kexec 'load' to kexec 'execute'.
>  	 */
> -	binary_runtime_size = ima_get_binary_runtime_size();
> +	binary_runtime_size = ima_get_binary_runtime_size() +
> +			      sizeof(struct ima_kexec_hdr) +
> +			      (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024);
> +
>  	if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE)
>  		kexec_segment_size = ULONG_MAX;
>  	else
> -		kexec_segment_size = ALIGN(ima_get_binary_runtime_size() +
> -					   PAGE_SIZE / 2, PAGE_SIZE);
> +		kexec_segment_size = ALIGN(binary_runtime_size, PAGE_SIZE);
> +
>  	if ((kexec_segment_size == ULONG_MAX) ||
>  	    ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) {
>  		pr_err("Binary measurement list too large.\n");
Tushar Sugandhi Jan. 5, 2024, 8:20 p.m. UTC | #2
On 12/20/23 12:15, Mimi Zohar wrote:
> Hi Tushar,
> 
> The Subject line should include the word "extra".   The use of the
> extra memory isn't limited to the measurements between the kexec load
> and exec.  Additional records could be added as a result of the kexec
> load itself.  Let's simplify the title to "ima: make the kexec extra
> memory configurable".
> 
> Please remove any references to measurements between kexec load and
> execute.
> 
Thanks Mimi. I will make these changes.

> On Fri, 2023-12-15 at 17:07 -0800, Tushar Sugandhi wrote:
>> IMA currently allocates half a PAGE_SIZE for the extra events that would
>> be measured between kexec 'load' and 'execute'.  Depending on the IMA
>> policy and the system state, that memory may not be sufficient to hold
>> the extra IMA events measured after kexec 'load'.  The memory
>> requirements vary from system to system and they should be configurable.
> 
> The extra memory allocated for carrying the IMA measurement list across
> kexec is hardcoded as a half a PAGE.   Make it configurable.
> 
Will do.
>> Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the
>> extra memory (in kb) to be allocated for IMA measurements added in the
>> window from kexec 'load' to kexec 'execute'.
> 
>> Update ima_add_kexec_buffer() function to allocate memory based on the
>> Kconfig option value, rather than the currently hardcoded one.
>>
>> Signed-off-by: Tushar Sugandhi <tusharsu@linux.microsoft.com>
>> ---
>>   security/integrity/ima/Kconfig     |  9 +++++++++
>>   security/integrity/ima/ima_kexec.c | 13 ++++++++-----
>>   2 files changed, 17 insertions(+), 5 deletions(-)
>>
>> diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
>> index 60a511c6b583..8792b7aab768 100644
>> --- a/security/integrity/ima/Kconfig
>> +++ b/security/integrity/ima/Kconfig
>> @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
>>   	default n
>>   	help
>>   	   This option disables htable to allow measurement of duplicate records.
>> +
>> +config IMA_KEXEC_EXTRA_MEMORY_KB
>> +	int
>> +	depends on IMA && IMA_KEXEC
>> +	default 64
> 
> Since this isn't optional, the default should remain as a half page.
> Since a page is architecture specific, the default will need to be arch
>   specific.
> 
> thanks,
> 
> Mimih
> 
It was a feedback from Stefan in the V2 of this series to convert it 
from number of PAGES to KB.[1]

But I can revert it to number of pages again.

Also, making the default value as a fraction (1/2 page) feels weird for 
a CONFIG variable.

Is it ok to make the default value as one page rather than half page?

[1]
https://lore.kernel.org/all/15a12e79-2e90-28f7-ffa3-ff470c673099@linux.ibm.com/
 >>> +config IMA_KEXEC_EXTRA_PAGES
 >>> +    int
 >>> +    depends on IMA && IMA_KEXEC
 >>> +    default 16
 >>> +    help
 >>> +      IMA_KEXEC_EXTRA_PAGES determines the number of extra
 >>> +      pages to be allocated for IMA measurements added in the
 >>> +      window from kexec 'load' to kexec 'execute'.
 >>
 >>
 >> On ppc64 a page is 64kb. I would ask for additional kb here.
 >>
 >>
 > Not sure I understand.  Do you mean I should make the default value of
 > the config IMA_KEXEC_EXTRA_PAGES 64 or something?


No, what I mean is you should ask the user for how many extra kilobytes
(kb) to allocate - not ask for pages.


     Stefan

>> +	help
>> +	  IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be
>> +	  allocated (in kb) for IMA measurements added in the window
>> +	  from kexec 'load' to kexec 'execute'.
>> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
>> index 55bd5362262e..063da9c834a0 100644
>> --- a/security/integrity/ima/ima_kexec.c
>> +++ b/security/integrity/ima/ima_kexec.c
>> @@ -128,15 +128,18 @@ void ima_add_kexec_buffer(struct kimage *image)
>>   	int ret;
>>   
>>   	/*
>> -	 * Reserve an extra half page of memory for additional measurements
>> -	 * added during the kexec load.
>> +	 * Reserve extra memory for measurements added in the window from
>> +	 * kexec 'load' to kexec 'execute'.
>>   	 */
>> -	binary_runtime_size = ima_get_binary_runtime_size();
>> +	binary_runtime_size = ima_get_binary_runtime_size() +
>> +			      sizeof(struct ima_kexec_hdr) +
>> +			      (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024);
>> +
>>   	if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE)
>>   		kexec_segment_size = ULONG_MAX;
>>   	else
>> -		kexec_segment_size = ALIGN(ima_get_binary_runtime_size() +
>> -					   PAGE_SIZE / 2, PAGE_SIZE);
>> +		kexec_segment_size = ALIGN(binary_runtime_size, PAGE_SIZE);
>> +
>>   	if ((kexec_segment_size == ULONG_MAX) ||
>>   	    ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) {
>>   		pr_err("Binary measurement list too large.\n");
>
Mimi Zohar Jan. 7, 2024, 5 p.m. UTC | #3
On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:
> >> diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
> >> index 60a511c6b583..8792b7aab768 100644
> >> --- a/security/integrity/ima/Kconfig
> >> +++ b/security/integrity/ima/Kconfig
> >> @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
> >>      default n
> >>      help
> >>         This option disables htable to allow measurement of duplicate records.
> >> +
> >> +config IMA_KEXEC_EXTRA_MEMORY_KB
> >> +    int
> >> +    depends on IMA && IMA_KEXEC
> >> +    default 64
> > 
> > Since this isn't optional, the default should remain as a half page.
> > Since a page is architecture specific, the default will need to be arch
> >   specific
> > 
> It was a feedback from Stefan in the V2 of this series to convert it 
> from number of PAGES to KB.[1]
> 
> But I can revert it to number of pages again.
> 
> Also, making the default value as a fraction (1/2 page) feels weird for 
> a CONFIG variable.
> 
> Is it ok to make the default value as one page rather than half page?

The point is not whether the extra memory is specified in terms of pages or KB. 
For backwards compatibility the existing default should be the same as
previously.  This means the default needs to be architecture specific.b
 
$ uname -m; getconf PAGESIZE
x86_64
4096
 
$ uname -m; getconf PAGESIZE 
ppc64le
65536

For example:

default 32 if PPC_64K_PAGES
default 2
Tushar Sugandhi Jan. 11, 2024, 6:13 p.m. UTC | #4
On 1/7/24 09:00, Mimi Zohar wrote:
> On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:
>>>> diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
>>>> index 60a511c6b583..8792b7aab768 100644
>>>> --- a/security/integrity/ima/Kconfig
>>>> +++ b/security/integrity/ima/Kconfig
>>>> @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
>>>>       default n
>>>>       help
>>>>          This option disables htable to allow measurement of duplicate records.
>>>> +
>>>> +config IMA_KEXEC_EXTRA_MEMORY_KB
>>>> +    int
>>>> +    depends on IMA && IMA_KEXEC
>>>> +    default 64
>>>
>>> Since this isn't optional, the default should remain as a half page.
>>> Since a page is architecture specific, the default will need to be arch
>>>    specific
>>>
>> It was a feedback from Stefan in the V2 of this series to convert it
>> from number of PAGES to KB.[1]
>>
>> But I can revert it to number of pages again.
>>
>> Also, making the default value as a fraction (1/2 page) feels weird for
>> a CONFIG variable.
>>
>> Is it ok to make the default value as one page rather than half page?
> 
> The point is not whether the extra memory is specified in terms of pages or KB.
> For backwards compatibility the existing default should be the same as
> previously.  This means the default needs to be architecture specific.b
>   
> $ uname -m; getconf PAGESIZE
> x86_64
> 4096
>   
> $ uname -m; getconf PAGESIZE
> ppc64le
> 65536
> 
> For example:
> 
> default 32 if PPC_64K_PAGES
> default 2
> 
Ok. Thanks for the clarification.


Do we want to support only 64K or 4K as possible PAGE_SIZE values?
I spot checked a few architectures, there are scenarios where PAGE_SIZE
could be 8K, 16K, 128K, 256K etc. And of course mega pages with
PAGE_SIZE IN MBs (details below).

About the unit of the config value (KB v/s num_pages), if we go with
num pages, I am having hard time figuring out how to set the config
value to a float - if we truly want to support 1/2 a page (0.5) as
a default. Majority are bools or ints. I couldn't find any
config value with float which I can refer to.

Being said that, I can think of two ways to handle it:
Option (A) fine tune it to half a page given arch specific page size
config.

Option (B) Keep it simple and make the default extra memory to be
a single page rather than half-a-page.

(A) seems fragile, and I am worried we will not cover all the scenarios.

(B) Even though we are technically breaking the backward compatibility
by changing the default extra memory from half-a-page to a full page,
I don't see it adversely affecting anything else in the IMA/kexec
functionality.

I am leaning towards (B), but please let me know your thoughts.

Sample code for both the options:

Option A:
---------
config IMA_KEXEC_EXTRA_MEMORY_KB
     int
     depends on IMA && IMA_KEXEC
     default 128 if PAGE_SIZE_256KB
     default 32 if PPC_64K_PAGES || PAGE_SIZE_64KB || PARISC_PAGE_SIZE_16KB
     default 16 if PAGE_SIZE_32KB
     default 8 if PAGE_SIZE_16KB || ARC_PAGE_SIZE_16K || 
PARISC_PAGE_SIZE_16KB
     default 4 if PAGE_SIZE_8KB || ARC_PAGE_SIZE_8K
     default 2
	  IMA_KEXEC_EXTRA_MEMORY_KB determines the number of extra
	  memory (in KB) to be allocated for IMA measurements added
	  during kexec soft-reboot.

Option B:
--------
config IMA_KEXEC_EXTRA_PAGES
	int
	depends on IMA && IMA_KEXEC
	default 1
	help
	  IMA_KEXEC_EXTRA_PAGES determines the number of extra
	  pages to be allocated for IMA measurements added during
	  kexec soft-reboot.


Below are a few PAGE_SIZE configs I found for a some architectures.


---------------------------------------------------------------------------------
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/arc/Kconfig
choice
prompt "MMU Page Size"
default ARC_PAGE_SIZE_8K

config ARC_PAGE_SIZE_8K
bool "8KB"
help
  Choose between 8k vs 16k

config ARC_PAGE_SIZE_16K
bool "16KB"

config ARC_PAGE_SIZE_4K
bool "4KB"
depends on ARC_MMU_V3 || ARC_MMU_V4

endchoice

choice
prompt "MMU Super Page Size"
depends on ISA_ARCV2 && TRANSPARENT_HUGEPAGE
default ARC_HUGEPAGE_2M

config ARC_HUGEPAGE_2M
bool "2MB"

config ARC_HUGEPAGE_16M
bool "16MB"

endchoice
---------------------------------------------------------------------------------------------------------
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/hexagon/Kconfig
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
help
  Changes the default page size; use with caution.

config PAGE_SIZE_4KB
bool "4KB"

config PAGE_SIZE_16KB
bool "16KB"

config PAGE_SIZE_64KB
bool "64KB"

config PAGE_SIZE_256KB
bool "256KB"

endchoice
---------------------------------------------------------------------------------------------------------
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/loongarch/Kconfig

config PAGE_SIZE_4KB
bool

config PAGE_SIZE_16KB
bool

config PAGE_SIZE_64KB
bool

---------------------------------------------------------------------------------------------------------

https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/mips/Kconfig
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB

config PAGE_SIZE_4KB
bool "4kB"
depends on !CPU_LOONGSON2EF && !CPU_LOONGSON64
help
  This option select the standard 4kB Linux page size.  On some
  R3000-family processors this is the only available page size.  Using
  4kB page size will minimize memory consumption and is therefore
  recommended for low memory systems.

config PAGE_SIZE_8KB
bool "8kB"
depends on CPU_CAVIUM_OCTEON
depends on !MIPS_VA_BITS_48
help
  Using 8kB page size will result in higher performance kernel at
  the price of higher memory consumption.  This option is available
  only on cnMIPS processors.  Note that you will need a suitable Linux
  distribution to support this.

config PAGE_SIZE_16KB
bool "16kB"
depends on !CPU_R3000
help
  Using 16kB page size will result in higher performance kernel at
  the price of higher memory consumption.  This option is available on
  all non-R3000 family processors.  Note that you will need a suitable
  Linux distribution to support this.

config PAGE_SIZE_32KB
bool "32kB"
depends on CPU_CAVIUM_OCTEON
depends on !MIPS_VA_BITS_48
help
  Using 32kB page size will result in higher performance kernel at
  the price of higher memory consumption.  This option is available
  only on cnMIPS cores.  Note that you will need a suitable Linux
  distribution to support this.

config PAGE_SIZE_64KB
bool "64kB"
depends on !CPU_R3000
help
  Using 64kB page size will result in higher performance kernel at
  the price of higher memory consumption.  This option is available on
  all non-R3000 family processor.  Not that at the time of this
  writing this option is still high experimental.

endchoice

----------------------------------------------------------------------------
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/parisc/Kconfig

choice
prompt "Kernel page size"
default PARISC_PAGE_SIZE_4KB

config PARISC_PAGE_SIZE_4KB
bool "4KB"
help
  This lets you select the page size of the kernel.  For best
  performance, a page size of 16KB is recommended.  For best
  compatibility with 32bit applications, a page size of 4KB should be
  selected (the vast majority of 32bit binaries work perfectly fine
  with a larger page size).

  4KB                For best 32bit compatibility
  16KB               For best performance
  64KB               For best performance, might give more overhead.

  If you don't know what to do, choose 4KB.

config PARISC_PAGE_SIZE_16KB
bool "16KB"
depends on PA8X00 && BROKEN && !KFENCE

config PARISC_PAGE_SIZE_64KB
bool "64KB"
depends on PA8X00 && BROKEN && !KFENCE

endchoice

----------------------------------------------------------------------------
https://elixir.bootlin.com/linux/v6.7-rc8/source/arch/sh/Kconfig

config ENTRY_OFFSET
hex
default "0x00001000" if PAGE_SIZE_4KB
default "0x00002000" if PAGE_SIZE_8KB
default "0x00004000" if PAGE_SIZE_16KB
default "0x00010000" if PAGE_SIZE_64KB
default "0x00000000"


~Tushar
Stefan Berger Jan. 11, 2024, 7:20 p.m. UTC | #5
On 1/11/24 13:13, Tushar Sugandhi wrote:
> 
> 
> On 1/7/24 09:00, Mimi Zohar wrote:
>> On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:
>>>>> diff --git a/security/integrity/ima/Kconfig 
>>>>> b/security/integrity/ima/Kconfig
>>>>> index 60a511c6b583..8792b7aab768 100644
>>>>> --- a/security/integrity/ima/Kconfig
>>>>> +++ b/security/integrity/ima/Kconfig
>>>>> @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
>>>>>       default n
>>>>>       help
>>>>>          This option disables htable to allow measurement of 
>>>>> duplicate records.
>>>>> +
>>>>> +config IMA_KEXEC_EXTRA_MEMORY_KB
>>>>> +    int
>>>>> +    depends on IMA && IMA_KEXEC
>>>>> +    default 64
>>>>
>>>> Since this isn't optional, the default should remain as a half page.
>>>> Since a page is architecture specific, the default will need to be arch
>>>>    specific
>>>>
>>> It was a feedback from Stefan in the V2 of this series to convert it
>>> from number of PAGES to KB.[1]
>>>
>>> But I can revert it to number of pages again.
>>>
>>> Also, making the default value as a fraction (1/2 page) feels weird for
>>> a CONFIG variable.
>>>
>>> Is it ok to make the default value as one page rather than half page?
>>
>> The point is not whether the extra memory is specified in terms of 
>> pages or KB.
>> For backwards compatibility the existing default should be the same as
>> previously.  This means the default needs to be architecture specific.b
>> $ uname -m; getconf PAGESIZE
>> x86_64
>> 4096
>> $ uname -m; getconf PAGESIZE
>> ppc64le
>> 65536
>>
>> For example:
>>
>> default 32 if PPC_64K_PAGES
>> default 2
>>
> Ok. Thanks for the clarification.
> 
> 
> Do we want to support only 64K or 4K as possible PAGE_SIZE values?
> I spot checked a few architectures, there are scenarios where PAGE_SIZE
> could be 8K, 16K, 128K, 256K etc. And of course mega pages with
> PAGE_SIZE IN MBs (details below).

I would let the user specify the number of kilobytes to reserve and from 
this you can conclude the page numbers:

needed_pages = KBs_TO_RESERVE / PAGE_SIZE
if (KBs_TO_RESERVER % PAGE_SIZE)
     needed_pages++;

    Stefan
Tushar Sugandhi Jan. 11, 2024, 8:52 p.m. UTC | #6
On 1/11/24 11:20, Stefan Berger wrote:
> 
> 
> On 1/11/24 13:13, Tushar Sugandhi wrote:
>>
>>
>> On 1/7/24 09:00, Mimi Zohar wrote:
>>> On Fri, 2024-01-05 at 12:20 -0800, Tushar Sugandhi wrote:
>>>>>> diff --git a/security/integrity/ima/Kconfig 
>>>>>> b/security/integrity/ima/Kconfig
>>>>>> index 60a511c6b583..8792b7aab768 100644
>>>>>> --- a/security/integrity/ima/Kconfig
>>>>>> +++ b/security/integrity/ima/Kconfig
>>>>>> @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE
>>>>>>       default n
>>>>>>       help
>>>>>>          This option disables htable to allow measurement of 
>>>>>> duplicate records.
>>>>>> +
>>>>>> +config IMA_KEXEC_EXTRA_MEMORY_KB
>>>>>> +    int
>>>>>> +    depends on IMA && IMA_KEXEC
>>>>>> +    default 64
>>>>>
>>>>> Since this isn't optional, the default should remain as a half page.
>>>>> Since a page is architecture specific, the default will need to be 
>>>>> arch
>>>>>    specific
>>>>>
>>>> It was a feedback from Stefan in the V2 of this series to convert it
>>>> from number of PAGES to KB.[1]
>>>>
>>>> But I can revert it to number of pages again.
>>>>
>>>> Also, making the default value as a fraction (1/2 page) feels weird for
>>>> a CONFIG variable.
>>>>
>>>> Is it ok to make the default value as one page rather than half page?
>>>
>>> The point is not whether the extra memory is specified in terms of 
>>> pages or KB.
>>> For backwards compatibility the existing default should be the same as
>>> previously.  This means the default needs to be architecture specific.b
>>> $ uname -m; getconf PAGESIZE
>>> x86_64
>>> 4096
>>> $ uname -m; getconf PAGESIZE
>>> ppc64le
>>> 65536
>>>
>>> For example:
>>>
>>> default 32 if PPC_64K_PAGES
>>> default 2
>>>
>> Ok. Thanks for the clarification.
>>
>>
>> Do we want to support only 64K or 4K as possible PAGE_SIZE values?
>> I spot checked a few architectures, there are scenarios where PAGE_SIZE
>> could be 8K, 16K, 128K, 256K etc. And of course mega pages with
>> PAGE_SIZE IN MBs (details below).
> 
> I would let the user specify the number of kilobytes to reserve and from 
> this you can conclude the page numbers:
> 
> needed_pages = KBs_TO_RESERVE / PAGE_SIZE
> if (KBs_TO_RESERVER % PAGE_SIZE)
>      needed_pages++;
> 
>     Stefan
Thanks Stefan.

But the issue here is about the default value,
not the user specified value.

Mimi is suggesting to keep the default value half-a-page,
to maintain backwards compatibility.

If we go with the KBs approach -
half-a-page translates to different KBs on different architectures.
And setting the right default value in KBs which would translate to
the desired half-a-page, on a given arch, inside the Kconfig seems
fragile (as I mentioned in the context of Option A in my previous
response.

And if we go with num_pages approach -
putting a fractional value (0.5) as a default in Kconfig seems to be non
trivial too.

Translating num_pages to KBs is trivial in code, but I think its
orthogonal to this conversation, since its about setting the desired 
arch specific default value in Kconfig.


Option A:
---------
config IMA_KEXEC_EXTRA_MEMORY_KB
     int
     depends on IMA && IMA_KEXEC
     default 128 if PAGE_SIZE_256KB
     default 32 if PPC_64K_PAGES || PAGE_SIZE_64KB || PARISC_PAGE_SIZE_16KB
     default 16 if PAGE_SIZE_32KB
     default 8 if PAGE_SIZE_16KB || ARC_PAGE_SIZE_16K || 
PARISC_PAGE_SIZE_16KB
     default 4 if PAGE_SIZE_8KB || ARC_PAGE_SIZE_8K
     default 2
       IMA_KEXEC_EXTRA_MEMORY_KB determines the number of extra
       memory (in KB) to be allocated for IMA measurements added
       during kexec soft-reboot.

Option B:
--------
config IMA_KEXEC_EXTRA_PAGES
     int
     depends on IMA && IMA_KEXEC
     default 1
     help
       IMA_KEXEC_EXTRA_PAGES determines the number of extra
       pages to be allocated for IMA measurements added during
       kexec soft-reboot.

~Tushar
Mimi Zohar Jan. 12, 2024, 5:44 p.m. UTC | #7
On Thu, 2024-01-11 at 12:52 -0800, Tushar Sugandhi wrote:
[...]
> If we go with the KBs approach -
> 
> half-a-page translates to different KBs on different architectures.
> And setting the right default value in KBs which would translate to
> the desired half-a-page, on a given arch, inside the Kconfig seems
> fragile (as I mentioned in the context of Option A in my previous
> response.

How about setting the default value to 0, indicating not to change the current
half page default.  Any other value would be KBs, as Stefan suggested.
Tushar Sugandhi Jan. 12, 2024, 6:23 p.m. UTC | #8
On 1/12/24 09:44, Mimi Zohar wrote:
> On Thu, 2024-01-11 at 12:52 -0800, Tushar Sugandhi wrote:
> [...]
>> If we go with the KBs approach -
>>
>> half-a-page translates to different KBs on different architectures.
>> And setting the right default value in KBs which would translate to
>> the desired half-a-page, on a given arch, inside the Kconfig seems
>> fragile (as I mentioned in the context of Option A in my previous
>> response.
> 
> How about setting the default value to 0, indicating not to change the current
> half page default.  Any other value would be KBs, as Stefan suggested.
> 
Thanks.
That's way more elegant than the other alternatives.
It's definitely doable in KConfig and handle the default in code 
appropriately.

It may cause some confusion in the documentation of the config param.
But it would be a wording issue, and we can work on it.

Thanks for the suggestion.  I like it honestly.

~Tushar
diff mbox series

Patch

diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 60a511c6b583..8792b7aab768 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -338,3 +338,12 @@  config IMA_DISABLE_HTABLE
 	default n
 	help
 	   This option disables htable to allow measurement of duplicate records.
+
+config IMA_KEXEC_EXTRA_MEMORY_KB
+	int
+	depends on IMA && IMA_KEXEC
+	default 64
+	help
+	  IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be
+	  allocated (in kb) for IMA measurements added in the window
+	  from kexec 'load' to kexec 'execute'.
diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index 55bd5362262e..063da9c834a0 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -128,15 +128,18 @@  void ima_add_kexec_buffer(struct kimage *image)
 	int ret;
 
 	/*
-	 * Reserve an extra half page of memory for additional measurements
-	 * added during the kexec load.
+	 * Reserve extra memory for measurements added in the window from
+	 * kexec 'load' to kexec 'execute'.
 	 */
-	binary_runtime_size = ima_get_binary_runtime_size();
+	binary_runtime_size = ima_get_binary_runtime_size() +
+			      sizeof(struct ima_kexec_hdr) +
+			      (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024);
+
 	if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE)
 		kexec_segment_size = ULONG_MAX;
 	else
-		kexec_segment_size = ALIGN(ima_get_binary_runtime_size() +
-					   PAGE_SIZE / 2, PAGE_SIZE);
+		kexec_segment_size = ALIGN(binary_runtime_size, PAGE_SIZE);
+
 	if ((kexec_segment_size == ULONG_MAX) ||
 	    ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) {
 		pr_err("Binary measurement list too large.\n");