[0/3] fs: reduce export usage of kerne_read*() calls
mbox series

Message ID 20200513152108.25669-1-mcgrof@kernel.org
Headers show
Series
  • fs: reduce export usage of kerne_read*() calls
Related show

Message

Luis Chamberlain May 13, 2020, 3:21 p.m. UTC
While reviewing Scott Branden's submission of the new Broadcom VK driver
driver upstream [0], part of which included 4 new pread varaints of the
existing kernel_read*(), calls I grew shivers of the possibility of drivers
using these exported symbols loosely. If we're going to grow these, it
seems best to restrict the symbols to a namespace so drivers and
subsystem maintainers don't use these carelessly.

This should also help with making it easier to audit future locations in
the kernel such read calls happen by just looking at the imports of the
namespace.

This goes compile tested with allyesconfig and allmodconfig on x86_64.
0-day should have a report on build status with other configs later of
my branch [1].

[0] https://lkml.kernel.org/r/20200508002739.19360-1-scott.branden@broadcom.com
[1] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20200513-kernel-read-sym

Luis Chamberlain (3):
  fs: unexport kernel_read_file()
  security: add symbol namespace for reading file data
  fs: move kernel_read*() calls to its own symbol namespace

 drivers/base/firmware_loader/fallback.c | 1 +
 drivers/base/firmware_loader/main.c     | 1 +
 fs/exec.c                               | 9 +++++----
 kernel/kexec.c                          | 2 ++
 kernel/kexec_file.c                     | 2 ++
 kernel/module.c                         | 3 +++
 security/integrity/digsig.c             | 3 +++
 security/integrity/ima/ima_fs.c         | 3 +++
 security/integrity/ima/ima_main.c       | 2 ++
 security/loadpin/loadpin.c              | 2 ++
 security/security.c                     | 8 +++++---
 security/selinux/hooks.c                | 2 ++
 12 files changed, 31 insertions(+), 7 deletions(-)

Comments

Christoph Hellwig May 13, 2020, 6:17 p.m. UTC | #1
Can you also move kernel_read_* out of fs.h?  That header gets pulled
in just about everywhere and doesn't really need function not related
to the general fs interface.
Luis Chamberlain May 15, 2020, 9:29 p.m. UTC | #2
On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> Can you also move kernel_read_* out of fs.h?  That header gets pulled
> in just about everywhere and doesn't really need function not related
> to the general fs interface.

Sure, where should I dump these?

  Luis
Christoph Hellwig May 18, 2020, 6:22 a.m. UTC | #3
On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
> On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> > Can you also move kernel_read_* out of fs.h?  That header gets pulled
> > in just about everywhere and doesn't really need function not related
> > to the general fs interface.
> 
> Sure, where should I dump these?

Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
of the file comment explaining the point of the interface, which I
still don't get :)
Mimi Zohar May 18, 2020, 12:37 p.m. UTC | #4
Hi Christoph,

On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
> On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
> > On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> > > Can you also move kernel_read_* out of fs.h?  That header gets pulled
> > > in just about everywhere and doesn't really need function not related
> > > to the general fs interface.
> > 
> > Sure, where should I dump these?
> 
> Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
> of the file comment explaining the point of the interface, which I
> still don't get :)

Instead of rolling your own method of having the kernel read a file,
which requires call specific security hooks, this interface provides a
single generic set of pre and post security hooks.  The
kernel_read_file_id enumeration permits the security hook to
differentiate between callers.

To comply with secure and trusted boot concepts, a file cannot be
accessible to the caller until after it has been measured and/or the
integrity (hash/signature) appraised.

In some cases, the file was previously read twice, first to measure
and/or appraise the file and then read again into a buffer for
use.  This interface reads the file into a buffer once, calls the
generic post security hook, before providing the buffer to the caller.
 (Note using firmware pre-allocated memory might be an issue.)

Partial reading firmware will result in needing to pre-read the entire
file, most likely on the security pre hook.

Mimi
Kees Cook May 18, 2020, 3:21 p.m. UTC | #5
On Mon, May 18, 2020 at 08:37:42AM -0400, Mimi Zohar wrote:
> Hi Christoph,
> 
> On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
> > On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
> > > On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> > > > Can you also move kernel_read_* out of fs.h?  That header gets pulled
> > > > in just about everywhere and doesn't really need function not related
> > > > to the general fs interface.
> > > 
> > > Sure, where should I dump these?
> > 
> > Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
> > of the file comment explaining the point of the interface, which I
> > still don't get :)
> 
> Instead of rolling your own method of having the kernel read a file,
> which requires call specific security hooks, this interface provides a
> single generic set of pre and post security hooks.  The
> kernel_read_file_id enumeration permits the security hook to
> differentiate between callers.
> 
> To comply with secure and trusted boot concepts, a file cannot be
> accessible to the caller until after it has been measured and/or the
> integrity (hash/signature) appraised.
> 
> In some cases, the file was previously read twice, first to measure
> and/or appraise the file and then read again into a buffer for
> use.  This interface reads the file into a buffer once, calls the
> generic post security hook, before providing the buffer to the caller.
>  (Note using firmware pre-allocated memory might be an issue.)
> 
> Partial reading firmware will result in needing to pre-read the entire
> file, most likely on the security pre hook.

Well described! :)
Scott Branden May 22, 2020, 10:24 p.m. UTC | #6
Hi Mimi,

On 2020-05-18 5:37 a.m., Mimi Zohar wrote:
> Hi Christoph,
>
> On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
>> On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
>>> On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
>>>> Can you also move kernel_read_* out of fs.h?  That header gets pulled
>>>> in just about everywhere and doesn't really need function not related
>>>> to the general fs interface.
>>> Sure, where should I dump these?
>> Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
>> of the file comment explaining the point of the interface, which I
>> still don't get :)
> Instead of rolling your own method of having the kernel read a file,
> which requires call specific security hooks, this interface provides a
> single generic set of pre and post security hooks.  The
> kernel_read_file_id enumeration permits the security hook to
> differentiate between callers.
>
> To comply with secure and trusted boot concepts, a file cannot be
> accessible to the caller until after it has been measured and/or the
> integrity (hash/signature) appraised.
>
> In some cases, the file was previously read twice, first to measure
> and/or appraise the file and then read again into a buffer for
> use.  This interface reads the file into a buffer once, calls the
> generic post security hook, before providing the buffer to the caller.
>   (Note using firmware pre-allocated memory might be an issue.)
>
> Partial reading firmware will result in needing to pre-read the entire
> file, most likely on the security pre hook.
The entire file may be very large and not fit into a buffer.
Hence one of the reasons for a partial read of the file.
For security purposes, you need to change your code to limit the amount
of data it reads into a buffer at one time to not consume or run out of 
much memory.
>
> Mimi
Scott
Kees Cook May 22, 2020, 11:04 p.m. UTC | #7
On Fri, May 22, 2020 at 03:24:32PM -0700, Scott Branden wrote:
> On 2020-05-18 5:37 a.m., Mimi Zohar wrote:
> > On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
> > > On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
> > > > On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> > > > > Can you also move kernel_read_* out of fs.h?  That header gets pulled
> > > > > in just about everywhere and doesn't really need function not related
> > > > > to the general fs interface.
> > > > Sure, where should I dump these?
> > > Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
> > > of the file comment explaining the point of the interface, which I
> > > still don't get :)
> > Instead of rolling your own method of having the kernel read a file,
> > which requires call specific security hooks, this interface provides a
> > single generic set of pre and post security hooks.  The
> > kernel_read_file_id enumeration permits the security hook to
> > differentiate between callers.
> > 
> > To comply with secure and trusted boot concepts, a file cannot be
> > accessible to the caller until after it has been measured and/or the
> > integrity (hash/signature) appraised.
> > 
> > In some cases, the file was previously read twice, first to measure
> > and/or appraise the file and then read again into a buffer for
> > use.  This interface reads the file into a buffer once, calls the
> > generic post security hook, before providing the buffer to the caller.
> >   (Note using firmware pre-allocated memory might be an issue.)
> > 
> > Partial reading firmware will result in needing to pre-read the entire
> > file, most likely on the security pre hook.
> The entire file may be very large and not fit into a buffer.
> Hence one of the reasons for a partial read of the file.
> For security purposes, you need to change your code to limit the amount
> of data it reads into a buffer at one time to not consume or run out of much
> memory.

Hm? That's not how whole-file hashing works. :)

These hooks need to finish their hashing and policy checking before they
can allow the rest of the code to move forward. (That's why it's a
security hook.) If kernel memory utilization is the primary concern,
then sure, things could be rearranged to do partial read and update the
hash incrementally, but the entire file still needs to be locked,
entirely hashed by hook, then read by the caller, then unlocked and
released.

So, if you want to have partial file reads work, you'll need to
rearchitect the way this works to avoid regressing the security coverage
of these operations.

So, probably, the code will look something like:


file = kernel_open_file_for_reading(...)
	file = open...
	disallow_writes(file);
	while (processed < size-of-file) {
		buf = read(file, size...)
		security_file_read_partial(buf)
	}
	ret = security_file_read_finished(file);
	if (ret < 0) {
		allow_writes(file);
		return PTR_ERR(ret);
	}
	return file;

while (processed < size-of-file) {
	buf = read(file, size...)
	firmware_send_partial(buf);
}

kernel_close_file_for_reading(file)
	allow_writes(file);
Scott Branden May 22, 2020, 11:25 p.m. UTC | #8
Hi Kees,

On 2020-05-22 4:04 p.m., Kees Cook wrote:
> On Fri, May 22, 2020 at 03:24:32PM -0700, Scott Branden wrote:
>> On 2020-05-18 5:37 a.m., Mimi Zohar wrote:
>>> On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
>>>> On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
>>>>> On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
>>>>>> Can you also move kernel_read_* out of fs.h?  That header gets pulled
>>>>>> in just about everywhere and doesn't really need function not related
>>>>>> to the general fs interface.
>>>>> Sure, where should I dump these?
>>>> Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
>>>> of the file comment explaining the point of the interface, which I
>>>> still don't get :)
>>> Instead of rolling your own method of having the kernel read a file,
>>> which requires call specific security hooks, this interface provides a
>>> single generic set of pre and post security hooks.  The
>>> kernel_read_file_id enumeration permits the security hook to
>>> differentiate between callers.
>>>
>>> To comply with secure and trusted boot concepts, a file cannot be
>>> accessible to the caller until after it has been measured and/or the
>>> integrity (hash/signature) appraised.
>>>
>>> In some cases, the file was previously read twice, first to measure
>>> and/or appraise the file and then read again into a buffer for
>>> use.  This interface reads the file into a buffer once, calls the
>>> generic post security hook, before providing the buffer to the caller.
>>>    (Note using firmware pre-allocated memory might be an issue.)
>>>
>>> Partial reading firmware will result in needing to pre-read the entire
>>> file, most likely on the security pre hook.
>> The entire file may be very large and not fit into a buffer.
>> Hence one of the reasons for a partial read of the file.
>> For security purposes, you need to change your code to limit the amount
>> of data it reads into a buffer at one time to not consume or run out of much
>> memory.
> Hm? That's not how whole-file hashing works. :)

>
> These hooks need to finish their hashing and policy checking before they
> can allow the rest of the code to move forward. (That's why it's a
> security hook.) If kernel memory utilization is the primary concern,
> then sure, things could be rearranged to do partial read and update the
> hash incrementally, but the entire file still needs to be locked,
> entirely hashed by hook, then read by the caller, then unlocked and
> released.
>
> So, if you want to have partial file reads work, you'll need to
> rearchitect the way this works to avoid regressing the security coverage
> of these operations.
I am not familiar with how the security handling code works at all.
Is the same security check run on files opened from user space?
A file could be huge.

If it assumes there is there is enough memory available to read the 
entire file into kernel space
then the improvement below can be left as a memory optimization to be 
done in
an independent (or future) patch series.

> So, probably, the code will look something like:
>
>
> file = kernel_open_file_for_reading(...)
> 	file = open...
> 	disallow_writes(file);
> 	while (processed < size-of-file) {
> 		buf = read(file, size...)
> 		security_file_read_partial(buf)
> 	}
> 	ret = security_file_read_finished(file);
> 	if (ret < 0) {
> 		allow_writes(file);
> 		return PTR_ERR(ret);
> 	}
> 	return file;
>
> while (processed < size-of-file) {
> 	buf = read(file, size...)
> 	firmware_send_partial(buf);
> }
>
> kernel_close_file_for_reading(file)
> 	allow_writes(file);
>
>
Mimi Zohar May 24, 2020, 2:52 a.m. UTC | #9
On Fri, 2020-05-22 at 16:25 -0700, Scott Branden wrote:
> Hi Kees,
> 
> On 2020-05-22 4:04 p.m., Kees Cook wrote:
> > On Fri, May 22, 2020 at 03:24:32PM -0700, Scott Branden wrote:
> >> On 2020-05-18 5:37 a.m., Mimi Zohar wrote:
> >>> On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
> >>>> On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
> >>>>> On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> >>>>>> Can you also move kernel_read_* out of fs.h?  That header gets pulled
> >>>>>> in just about everywhere and doesn't really need function not related
> >>>>>> to the general fs interface.
> >>>>> Sure, where should I dump these?
> >>>> Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
> >>>> of the file comment explaining the point of the interface, which I
> >>>> still don't get :)
> >>> Instead of rolling your own method of having the kernel read a file,
> >>> which requires call specific security hooks, this interface provides a
> >>> single generic set of pre and post security hooks.  The
> >>> kernel_read_file_id enumeration permits the security hook to
> >>> differentiate between callers.
> >>>
> >>> To comply with secure and trusted boot concepts, a file cannot be
> >>> accessible to the caller until after it has been measured and/or the
> >>> integrity (hash/signature) appraised.
> >>>
> >>> In some cases, the file was previously read twice, first to measure
> >>> and/or appraise the file and then read again into a buffer for
> >>> use.  This interface reads the file into a buffer once, calls the
> >>> generic post security hook, before providing the buffer to the caller.
> >>>    (Note using firmware pre-allocated memory might be an issue.)
> >>>
> >>> Partial reading firmware will result in needing to pre-read the entire
> >>> file, most likely on the security pre hook.
> >> The entire file may be very large and not fit into a buffer.
> >> Hence one of the reasons for a partial read of the file.
> >> For security purposes, you need to change your code to limit the amount
> >> of data it reads into a buffer at one time to not consume or run out of much
> >> memory.
> > Hm? That's not how whole-file hashing works. :)
> 
> >
> > These hooks need to finish their hashing and policy checking before they
> > can allow the rest of the code to move forward. (That's why it's a
> > security hook.) If kernel memory utilization is the primary concern,
> > then sure, things could be rearranged to do partial read and update the
> > hash incrementally, but the entire file still needs to be locked,
> > entirely hashed by hook, then read by the caller, then unlocked and
> > released.

Exactly.

> >
> > So, if you want to have partial file reads work, you'll need to
> > rearchitect the way this works to avoid regressing the security coverage
> > of these operations.
> I am not familiar with how the security handling code works at all.
> Is the same security check run on files opened from user space?
> A file could be huge.
> 
> If it assumes there is there is enough memory available to read the 
> entire file into kernel space then the improvement below can be left as
> a memory optimization to be done in an independent (or future) patch series.

There are two security hooks - security_kernel_read_file(),
security_kernel_post_read_file - in kernel_read_file().  The first
hook is called before the file is read into a buffer, while the second
hook is called afterwards.

For partial reads, measuring the firmware and verifying the firmware's
signature will need to be done on the security_kernel_read_file()
hook.

> 
> > So, probably, the code will look something like:
> >
> >
> > file = kernel_open_file_for_reading(...)
> > 	file = open...
> > 	disallow_writes(file);
> > 	while (processed < size-of-file) {
> > 		buf = read(file, size...)
> > 		security_file_read_partial(buf)
> > 	}
> > 	ret = security_file_read_finished(file);
> > 	if (ret < 0) {
> > 		allow_writes(file);
> > 		return PTR_ERR(ret);
> > 	}
> > 	return file;
> >
> > while (processed < size-of-file) {
> > 	buf = read(file, size...)
> > 	firmware_send_partial(buf);
> > }
> >
> > kernel_close_file_for_reading(file)
> > 	allow_writes(file);

Right, the ima_file_mmap(), ima_bprm_check(), and ima_file_check()
hooks call process_measurement() to do this.  ima_post_read_file()
passes a buffer to process_measurement() instead.

Scott, the change should be straight forward.  The additional patch
needs to:
- define a new kernel_read_file_id enumeration, like
FIRMWARE_PARTIAL_READ.
- Currently ima_read_file() has a comment about pre-allocated firmware
buffers.  Update ima_read_file() to call process_measurement() for the
new enumeration FIRMWARE_PARTIAL_READ and update ima_post_read_file()
to return immediately.

The built-in IMA measurement policy contains a rule to measure
firmware.  The policy can be specified on the boot command line by
specifying "ima_policy=tcb".  After reading the firmware, the firmware
measurement should be in <securityfs>/ima/ascii_runtime_measurements.

thanks,

Mimi
Scott Branden June 5, 2020, 6:15 p.m. UTC | #10
Hi Mimi,

On 2020-05-23 7:52 p.m., Mimi Zohar wrote:
> On Fri, 2020-05-22 at 16:25 -0700, Scott Branden wrote:
>> Hi Kees,
>>
>> On 2020-05-22 4:04 p.m., Kees Cook wrote:
>>> On Fri, May 22, 2020 at 03:24:32PM -0700, Scott Branden wrote:
>>>> On 2020-05-18 5:37 a.m., Mimi Zohar wrote:
>>>>> On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
>>>>>> On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
>>>>>>> On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
>>>>>>>> Can you also move kernel_read_* out of fs.h?  That header gets pulled
>>>>>>>> in just about everywhere and doesn't really need function not related
>>>>>>>> to the general fs interface.
>>>>>>> Sure, where should I dump these?
>>>>>> Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
>>>>>> of the file comment explaining the point of the interface, which I
>>>>>> still don't get :)
>>>>> Instead of rolling your own method of having the kernel read a file,
>>>>> which requires call specific security hooks, this interface provides a
>>>>> single generic set of pre and post security hooks.  The
>>>>> kernel_read_file_id enumeration permits the security hook to
>>>>> differentiate between callers.
>>>>>
>>>>> To comply with secure and trusted boot concepts, a file cannot be
>>>>> accessible to the caller until after it has been measured and/or the
>>>>> integrity (hash/signature) appraised.
>>>>>
>>>>> In some cases, the file was previously read twice, first to measure
>>>>> and/or appraise the file and then read again into a buffer for
>>>>> use.  This interface reads the file into a buffer once, calls the
>>>>> generic post security hook, before providing the buffer to the caller.
>>>>>     (Note using firmware pre-allocated memory might be an issue.)
>>>>>
>>>>> Partial reading firmware will result in needing to pre-read the entire
>>>>> file, most likely on the security pre hook.
>>>> The entire file may be very large and not fit into a buffer.
>>>> Hence one of the reasons for a partial read of the file.
>>>> For security purposes, you need to change your code to limit the amount
>>>> of data it reads into a buffer at one time to not consume or run out of much
>>>> memory.
>>> Hm? That's not how whole-file hashing works. :)
>>> These hooks need to finish their hashing and policy checking before they
>>> can allow the rest of the code to move forward. (That's why it's a
>>> security hook.) If kernel memory utilization is the primary concern,
>>> then sure, things could be rearranged to do partial read and update the
>>> hash incrementally, but the entire file still needs to be locked,
>>> entirely hashed by hook, then read by the caller, then unlocked and
>>> released.
> Exactly.
>
>>> So, if you want to have partial file reads work, you'll need to
>>> rearchitect the way this works to avoid regressing the security coverage
>>> of these operations.
>> I am not familiar with how the security handling code works at all.
>> Is the same security check run on files opened from user space?
>> A file could be huge.
>>
>> If it assumes there is there is enough memory available to read the
>> entire file into kernel space then the improvement below can be left as
>> a memory optimization to be done in an independent (or future) patch series.
> There are two security hooks - security_kernel_read_file(),
> security_kernel_post_read_file - in kernel_read_file().  The first
> hook is called before the file is read into a buffer, while the second
> hook is called afterwards.
>
> For partial reads, measuring the firmware and verifying the firmware's
> signature will need to be done on the security_kernel_read_file()
> hook.
>
>>> So, probably, the code will look something like:
>>>
>>>
>>> file = kernel_open_file_for_reading(...)
>>> 	file = open...
>>> 	disallow_writes(file);
>>> 	while (processed < size-of-file) {
>>> 		buf = read(file, size...)
>>> 		security_file_read_partial(buf)
>>> 	}
>>> 	ret = security_file_read_finished(file);
>>> 	if (ret < 0) {
>>> 		allow_writes(file);
>>> 		return PTR_ERR(ret);
>>> 	}
>>> 	return file;
>>>
>>> while (processed < size-of-file) {
>>> 	buf = read(file, size...)
>>> 	firmware_send_partial(buf);
>>> }
>>>
>>> kernel_close_file_for_reading(file)
>>> 	allow_writes(file);
> Right, the ima_file_mmap(), ima_bprm_check(), and ima_file_check()
> hooks call process_measurement() to do this.  ima_post_read_file()
> passes a buffer to process_measurement() instead.
>
> Scott, the change should be straight forward.  The additional patch
> needs to:
> - define a new kernel_read_file_id enumeration, like
> FIRMWARE_PARTIAL_READ.
> - Currently ima_read_file() has a comment about pre-allocated firmware
> buffers.  Update ima_read_file() to call process_measurement() for the
> new enumeration FIRMWARE_PARTIAL_READ and update ima_post_read_file()
> to return immediately.
Should this be what is in ima_read_file?
{
     enum ima_hooks func;
     u32 secid;

     if (read_id != READING_FIRMWARE_PARTIAL_READ)
         return 0;

     if (!file) { /* should never happen */
         if (ima_appraise & IMA_APPRAISE_ENFORCE)
             return -EACCES;
         return 0;
     }

     security_task_getsecid(current, &secid);
     return process_measurement(file, current_cred(), secid, NULL,
                    0, MAY_READ, FILE_CHECK);
}
>
> The built-in IMA measurement policy contains a rule to measure
> firmware.  The policy can be specified on the boot command line by
> specifying "ima_policy=tcb".  After reading the firmware, the firmware
> measurement should be in <securityfs>/ima/ascii_runtime_measurements.
>
> thanks,
>
> Mimi
Mimi Zohar June 5, 2020, 6:37 p.m. UTC | #11
On Fri, 2020-06-05 at 11:15 -0700, Scott Branden wrote:
> Hi Mimi,
> 
> On 2020-05-23 7:52 p.m., Mimi Zohar wrote:
> > Scott, the change should be straight forward.  The additional patch
> > needs to:
> > - define a new kernel_read_file_id enumeration, like
> > FIRMWARE_PARTIAL_READ.
> > - Currently ima_read_file() has a comment about pre-allocated firmware
> > buffers.  Update ima_read_file() to call process_measurement() for the
> > new enumeration FIRMWARE_PARTIAL_READ and update ima_post_read_file()
> > to return immediately.
> Should this be what is in ima_read_file?
> {
>      enum ima_hooks func;
>      u32 secid;

Please don't remove the existing comment.

>      if (read_id != READING_FIRMWARE_PARTIAL_READ)
>          return 0;
> 
>      if (!file) { /* should never happen */
>          if (ima_appraise & IMA_APPRAISE_ENFORCE)
>              return -EACCES;
>          return 0;
>      }

This checks for any IMA appraise rule.  You want to enforce firmware
signature checking only if there is a firmware appraise rule.  Refer
to ima_post_read_file().

>      security_task_getsecid(current, &secid);
>      return process_measurement(file, current_cred(), secid, NULL,
>                     0, MAY_READ, FILE_CHECK);

The read_idmap enumeration should be updated similar to the other
firmware.  Keep the code generic.  Refer to ima_post_read_file().
 func will be defined as FIRMWARE_CHECK.

thanks,

Mimi
Luis Chamberlain July 29, 2020, 1:20 a.m. UTC | #12
On Mon, May 18, 2020 at 08:21:08AM -0700, Kees Cook wrote:
> On Mon, May 18, 2020 at 08:37:42AM -0400, Mimi Zohar wrote:
> > Hi Christoph,
> > 
> > On Sun, 2020-05-17 at 23:22 -0700, Christoph Hellwig wrote:
> > > On Fri, May 15, 2020 at 09:29:33PM +0000, Luis Chamberlain wrote:
> > > > On Wed, May 13, 2020 at 11:17:36AM -0700, Christoph Hellwig wrote:
> > > > > Can you also move kernel_read_* out of fs.h?  That header gets pulled
> > > > > in just about everywhere and doesn't really need function not related
> > > > > to the general fs interface.
> > > > 
> > > > Sure, where should I dump these?
> > > 
> > > Maybe a new linux/kernel_read_file.h?  Bonus points for a small top
> > > of the file comment explaining the point of the interface, which I
> > > still don't get :)
> > 
> > Instead of rolling your own method of having the kernel read a file,
> > which requires call specific security hooks, this interface provides a
> > single generic set of pre and post security hooks.  The
> > kernel_read_file_id enumeration permits the security hook to
> > differentiate between callers.
> > 
> > To comply with secure and trusted boot concepts, a file cannot be
> > accessible to the caller until after it has been measured and/or the
> > integrity (hash/signature) appraised.
> > 
> > In some cases, the file was previously read twice, first to measure
> > and/or appraise the file and then read again into a buffer for
> > use.  This interface reads the file into a buffer once, calls the
> > generic post security hook, before providing the buffer to the caller.
> >  (Note using firmware pre-allocated memory might be an issue.)
> > 
> > Partial reading firmware will result in needing to pre-read the entire
> > file, most likely on the security pre hook.
> 
> Well described! :)

Since you're moving all this stuff, it woudl be good if you can add this
as part of new kdoc as well.

  Luis