mbox series

[RFC,0/5] shmem/fsverity: Prepare for mandatory integrity enforcement

Message ID 20211112124411.1948809-1-roberto.sassu@huawei.com (mailing list archive)
Headers show
Series shmem/fsverity: Prepare for mandatory integrity enforcement | expand

Message

Roberto Sassu Nov. 12, 2021, 12:44 p.m. UTC
The biggest advantage of fsverity compared to file-based solutions like IMA
is the lower overhead added for integrity measurement and enforcement.
Although fsverity offers the same file representation as a digest, it works
instead at page granularity rather than file granularity. Only the pages
that are going to be used will be evaluated by fsverity, while IMA has to
read the whole file.

Although fsverity has a built-in enforcement mechanism, it is basically
discretionary, it can be enabled (or disabled by replacing the file) by
the user himself. A mandatory mechanism could be used to impose fsverity
protection for files involved in certain events, defined with a policy.

Integrity Policy Enforcement (IPE) is one of such mandatory mechanisms
designed to work in conjunction with fsverity (IMA integration is planned).
However, at this stage (v7), IPE is storing fsverity data at file
instantiation time rather than at usage time. One disadvantage of such
approach is that a security blob needs to be allocated and maintained for
such purpose, which makes the code unnecessarily more complex. A much
better approach would be to retrieve the information when needed, without
storing it in a security blob.

Another gap that currently limits the applicability of fsverity is the
missing support for the tmpfs filesystem. Files could still be executed
from it (e.g. during the boot process) and would still need to be verified
by IPE. Not verifying those files would considerably reduce the
effectiveness of the integrity protection. Alternatively, requiring that
the initial ram disk is signed limits the applicability of the solution
only to embedded systems, where the initial ram disk can be also
distributed. General purpose OSes instead regenerate it locally depending
on the system configuration, and after critical packages changes.

Given that tmpfs is not persistent, the question is if support should be
implemented in a similar way of persistent filesystems, such as ext4. And,
while fsverity protection needs to be enabled on a file each time a tmpfs
filesystem is mounted, probably implementing fsverity support in the same
way is simpler.

Another question is whether and when pages should be checked. In a
preliminary test, checking a page after it was swapped in resulted in the
page not being considered valid by fsverity. For now there are no calls to
fsverity_verify_page().

The implementation in this patch set is not necessarily the most efficient,
and does not consider the specific features of tmpfs. The goal was to aim
at correctness, by following closely the implementation for f2fs, doing the
minimal changes necessary to make it work for tmpfs (e.g. replacing
read_mapping_page() with shmem_read_mapping_page()).

Other than with trivial operations, this patch set has been tested with
the xfstests-dev testsuite, also under severe memory pressure to ensure
that everything still works when a page is swapped out.

Make the following changes: provide the fsverity_get_file_digest() and
fsverity_sig_validated() for IPE to retrieve fsverity information at usage
time, and additionally revalidate the signature at every file open
(patches 1, 2); make fsverity suitable to protect files in the rootfs
filesystem (patch 3); fix a small problem in shmem_read_mapping_page_gfp()
(patch 4) and finally add support for fsverity in tmpfs (patch 5).

An open point, not addressed by this patch set, is how to enable the
fsverity protection for files in the rootfs filesystem, given that it is
too early for user space to invoke the ioctl() system call. It should not
be a problem to enable fsverity from the kernel, depending on a labelling
policy.

Roberto Sassu (5):
  fsverity: Introduce fsverity_get_file_digest()
  fsverity: Revalidate built-in signatures at file open
  fsverity: Do initialization earlier
  shmem: Avoid segfault in shmem_read_mapping_page_gfp()
  shmem: Add fsverity support

 Documentation/filesystems/fsverity.rst |  18 ++
 MAINTAINERS                            |   1 +
 fs/Kconfig                             |   7 +
 fs/verity/enable.c                     |   6 +-
 fs/verity/fsverity_private.h           |   7 +-
 fs/verity/init.c                       |   2 +-
 fs/verity/open.c                       |  43 +++-
 fs/verity/signature.c                  |   6 +-
 include/linux/fsverity.h               |  16 ++
 include/linux/shmem_fs.h               |  27 +++
 mm/Makefile                            |   2 +
 mm/shmem.c                             |  71 ++++++-
 mm/shmem_verity.c                      | 267 +++++++++++++++++++++++++
 13 files changed, 463 insertions(+), 10 deletions(-)
 create mode 100644 mm/shmem_verity.c

Comments

Ajay Garg Nov. 12, 2021, 12:53 p.m. UTC | #1
Hi Roberto.

Identical patch has been floated earlier via :
https://lore.kernel.org/linux-mm/CAMZfGtUp6dkT4OWzLhL8whqNnXAbfVw5c6AQogHzY3bbM_k2Qw@mail.gmail.com/T/#m2189d135b9293de9b4a11362f0179c17b254d5ab


Thanks and Regards,
Ajay

On Fri, Nov 12, 2021 at 6:15 PM Roberto Sassu <roberto.sassu@huawei.com> wrote:
>
> Check the hwpoison page flag only if the page is valid in
> shmem_read_mapping_page_gfp(). The PageHWPoison() macro tries to access
> the page flags and cannot work on an error pointer.
>
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> ---
>  mm/shmem.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 23c91a8beb78..427863cbf0dc 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -4222,7 +4222,7 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
>         else
>                 unlock_page(page);
>
> -       if (PageHWPoison(page))
> +       if (!IS_ERR(page) && PageHWPoison(page))
>                 page = ERR_PTR(-EIO);
>
>         return page;
> --
> 2.32.0
>
Roberto Sassu Nov. 12, 2021, 12:56 p.m. UTC | #2
> From: Ajay Garg [mailto:ajaygargnsit@gmail.com]
> Sent: Friday, November 12, 2021 1:54 PM
> Hi Roberto.
> 
> Identical patch has been floated earlier via :
> https://lore.kernel.org/linux-
> mm/CAMZfGtUp6dkT4OWzLhL8whqNnXAbfVw5c6AQogHzY3bbM_k2Qw@mail.
> gmail.com/T/#m2189d135b9293de9b4a11362f0179c17b254d5ab

Hi Ajay

thanks, I was not aware.

Roberto

HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Li Peng, Zhong Ronghua

> Thanks and Regards,
> Ajay
> 
> On Fri, Nov 12, 2021 at 6:15 PM Roberto Sassu <roberto.sassu@huawei.com>
> wrote:
> >
> > Check the hwpoison page flag only if the page is valid in
> > shmem_read_mapping_page_gfp(). The PageHWPoison() macro tries to
> access
> > the page flags and cannot work on an error pointer.
> >
> > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> > ---
> >  mm/shmem.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/mm/shmem.c b/mm/shmem.c
> > index 23c91a8beb78..427863cbf0dc 100644
> > --- a/mm/shmem.c
> > +++ b/mm/shmem.c
> > @@ -4222,7 +4222,7 @@ struct page
> *shmem_read_mapping_page_gfp(struct address_space *mapping,
> >         else
> >                 unlock_page(page);
> >
> > -       if (PageHWPoison(page))
> > +       if (!IS_ERR(page) && PageHWPoison(page))
> >                 page = ERR_PTR(-EIO);
> >
> >         return page;
> > --
> > 2.32.0
> >