mbox series

[v2,0/6] module: Introduce hash-based integrity checking

Message ID 20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net (mailing list archive)
Headers show
Series module: Introduce hash-based integrity checking | expand

Message

Thomas Weißschuh Jan. 20, 2025, 5:44 p.m. UTC
The current signature-based module integrity checking has some drawbacks
in combination with reproducible builds:
Either the module signing key is generated at build time, which makes
the build unreproducible, or a static key is used, which precludes
rebuilds by third parties and makes the whole build and packaging
process much more complicated.
Introduce a new mechanism to ensure only well-known modules are loaded
by embedding a list of hashes of all modules built as part of the full
kernel build into vmlinux.

Interest has been proclaimed by NixOS, Arch Linux, Proxmox, SUSE and the
general reproducible builds community.

To properly test the reproducibility in combination with CONFIG_INFO_BTF
another patch is needed:
"[PATCH bpf-next] kbuild, bpf: Enable reproducible BTF generation" [0]
(If you happen to test that one, please give some feedback)

Questions for current patch:
* Naming
* Can the number of built-in modules be retrieved while building
  kernel/module/hashes.o? This would remove the need for the
  preallocation step in link-vmlinux.sh.

Further improvements:
* Use a LSM/IMA/Keyring to store and validate hashes
* Use MODULE_SIG_HASH for configuration
* UAPI for discovery?

[0] https://lore.kernel.org/lkml/20241211-pahole-reproducible-v1-1-22feae19bad9@weissschuh.net/

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
Changes in v2:
- Drop RFC state
- Mention interested parties in cover letter
- Expand Kconfig description
- Add compatibility with CONFIG_MODULE_SIG
- Parallelize module-hashes.sh
- Update Documentation/kbuild/reproducible-builds.rst
- Link to v1: https://lore.kernel.org/r/20241225-module-hashes-v1-0-d710ce7a3fd1@weissschuh.net

---
Thomas Weißschuh (6):
      kbuild: add stamp file for vmlinux BTF data
      module: Make module loading policy usable without MODULE_SIG
      module: Move integrity checks into dedicated function
      module: Move lockdown check into generic module loader
      lockdown: Make the relationship to MODULE_SIG a dependency
      module: Introduce hash-based integrity checking

 .gitignore                                   |  1 +
 Documentation/kbuild/reproducible-builds.rst |  5 ++-
 Makefile                                     |  8 ++++-
 include/asm-generic/vmlinux.lds.h            | 11 ++++++
 include/linux/module.h                       |  8 ++---
 include/linux/module_hashes.h                | 17 +++++++++
 kernel/module/Kconfig                        | 21 ++++++++++-
 kernel/module/Makefile                       |  1 +
 kernel/module/hashes.c                       | 52 +++++++++++++++++++++++++++
 kernel/module/internal.h                     |  8 +----
 kernel/module/main.c                         | 54 +++++++++++++++++++++++++---
 kernel/module/signing.c                      | 24 +------------
 scripts/Makefile.modfinal                    | 10 ++++--
 scripts/Makefile.vmlinux                     |  5 +++
 scripts/link-vmlinux.sh                      | 31 +++++++++++++++-
 scripts/module-hashes.sh                     | 26 ++++++++++++++
 security/lockdown/Kconfig                    |  2 +-
 17 files changed, 238 insertions(+), 46 deletions(-)
---
base-commit: 2cd5917560a84d69dd6128b640d7a68406ff019b
change-id: 20241225-module-hashes-7a50a7cc2a30

Best regards,

Comments

Roberto Sassu Jan. 21, 2025, 10:26 a.m. UTC | #1
On Mon, 2025-01-20 at 18:44 +0100, Thomas Weißschuh wrote:
> The current signature-based module integrity checking has some drawbacks
> in combination with reproducible builds:
> Either the module signing key is generated at build time, which makes
> the build unreproducible, or a static key is used, which precludes
> rebuilds by third parties and makes the whole build and packaging
> process much more complicated.
> Introduce a new mechanism to ensure only well-known modules are loaded
> by embedding a list of hashes of all modules built as part of the full
> kernel build into vmlinux.
> 
> Interest has been proclaimed by NixOS, Arch Linux, Proxmox, SUSE and the
> general reproducible builds community.
> 
> To properly test the reproducibility in combination with CONFIG_INFO_BTF
> another patch is needed:
> "[PATCH bpf-next] kbuild, bpf: Enable reproducible BTF generation" [0]
> (If you happen to test that one, please give some feedback)
> 
> Questions for current patch:
> * Naming
> * Can the number of built-in modules be retrieved while building
>   kernel/module/hashes.o? This would remove the need for the
>   preallocation step in link-vmlinux.sh.
> 
> Further improvements:
> * Use a LSM/IMA/Keyring to store and validate hashes

+ linux-integrity, Mimi

Hi Thomas

I developed something related to it, it is called Integrity Digest
Cache [1].

It has the ability to store in the kernel memory a cache of digests
extracted from a file (or if desired in the future, from a reserved
area in the kernel image).

It exposes an API to query a digest (get/lookup/put) from a digest
cache and to verify whether or not the integrity of the file digests
were extracted from was verified by IMA or another LSM
(verif_set/verif_get). 

Roberto


[1]: https://lore.kernel.org/linux-integrity/20241119104922.2772571-1-roberto.sassu@huaweicloud.com/

> * Use MODULE_SIG_HASH for configuration
> * UAPI for discovery?
> 
> [0] https://lore.kernel.org/lkml/20241211-pahole-reproducible-v1-1-22feae19bad9@weissschuh.net/
> 
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> Changes in v2:
> - Drop RFC state
> - Mention interested parties in cover letter
> - Expand Kconfig description
> - Add compatibility with CONFIG_MODULE_SIG
> - Parallelize module-hashes.sh
> - Update Documentation/kbuild/reproducible-builds.rst
> - Link to v1: https://lore.kernel.org/r/20241225-module-hashes-v1-0-d710ce7a3fd1@weissschuh.net
> 
> ---
> Thomas Weißschuh (6):
>       kbuild: add stamp file for vmlinux BTF data
>       module: Make module loading policy usable without MODULE_SIG
>       module: Move integrity checks into dedicated function
>       module: Move lockdown check into generic module loader
>       lockdown: Make the relationship to MODULE_SIG a dependency
>       module: Introduce hash-based integrity checking
> 
>  .gitignore                                   |  1 +
>  Documentation/kbuild/reproducible-builds.rst |  5 ++-
>  Makefile                                     |  8 ++++-
>  include/asm-generic/vmlinux.lds.h            | 11 ++++++
>  include/linux/module.h                       |  8 ++---
>  include/linux/module_hashes.h                | 17 +++++++++
>  kernel/module/Kconfig                        | 21 ++++++++++-
>  kernel/module/Makefile                       |  1 +
>  kernel/module/hashes.c                       | 52 +++++++++++++++++++++++++++
>  kernel/module/internal.h                     |  8 +----
>  kernel/module/main.c                         | 54 +++++++++++++++++++++++++---
>  kernel/module/signing.c                      | 24 +------------
>  scripts/Makefile.modfinal                    | 10 ++++--
>  scripts/Makefile.vmlinux                     |  5 +++
>  scripts/link-vmlinux.sh                      | 31 +++++++++++++++-
>  scripts/module-hashes.sh                     | 26 ++++++++++++++
>  security/lockdown/Kconfig                    |  2 +-
>  17 files changed, 238 insertions(+), 46 deletions(-)
> ---
> base-commit: 2cd5917560a84d69dd6128b640d7a68406ff019b
> change-id: 20241225-module-hashes-7a50a7cc2a30
> 
> Best regards,
Thomas Weißschuh Jan. 21, 2025, 12:58 p.m. UTC | #2
Hi Roberto,

On 2025-01-21 11:26:29+0100, Roberto Sassu wrote:
> On Mon, 2025-01-20 at 18:44 +0100, Thomas Weißschuh wrote:
> > The current signature-based module integrity checking has some drawbacks
> > in combination with reproducible builds:
> > Either the module signing key is generated at build time, which makes
> > the build unreproducible, or a static key is used, which precludes
> > rebuilds by third parties and makes the whole build and packaging
> > process much more complicated.
> > Introduce a new mechanism to ensure only well-known modules are loaded
> > by embedding a list of hashes of all modules built as part of the full
> > kernel build into vmlinux.
> > 
> > Interest has been proclaimed by NixOS, Arch Linux, Proxmox, SUSE and the
> > general reproducible builds community.
> > 
> > To properly test the reproducibility in combination with CONFIG_INFO_BTF
> > another patch is needed:
> > "[PATCH bpf-next] kbuild, bpf: Enable reproducible BTF generation" [0]
> > (If you happen to test that one, please give some feedback)
> > 
> > Questions for current patch:
> > * Naming
> > * Can the number of built-in modules be retrieved while building
> >   kernel/module/hashes.o? This would remove the need for the
> >   preallocation step in link-vmlinux.sh.
> > 
> > Further improvements:
> > * Use a LSM/IMA/Keyring to store and validate hashes
> 
> + linux-integrity, Mimi
> 
> Hi Thomas
> 
> I developed something related to it, it is called Integrity Digest
> Cache [1].

Thanks for the pointer.

> It has the ability to store in the kernel memory a cache of digests
> extracted from a file (or if desired in the future, from a reserved
> area in the kernel image).
> 
> It exposes an API to query a digest (get/lookup/put) from a digest
> cache and to verify whether or not the integrity of the file digests
> were extracted from was verified by IMA or another LSM
> (verif_set/verif_get). 

I see how this could be used together with the module hashes.
For now I think both features should be developed independently.
Integrating them will require some extra code and coordination.

While the current linear, unsorted list of hashes used by my code may be
slightly inefficient, it shouldn't matter in practize as the hash
validation is only a bunch of memcmp()s over a contiguous chunk of
memory, which is very cheap.

When both features are well established we can look at integrating them.
At least a build-time userspace generator of a digest cache would be
necessary.
And due to the current implementation details it would be necessary to
estimate the size of a static digest cache more or less exactly by its
number of elements alone.


Thomas

> [1]: https://lore.kernel.org/linux-integrity/20241119104922.2772571-1-roberto.sassu@huaweicloud.com/
> 
> > * Use MODULE_SIG_HASH for configuration
> > * UAPI for discovery?
> > 
> > [0] https://lore.kernel.org/lkml/20241211-pahole-reproducible-v1-1-22feae19bad9@weissschuh.net/
> > 
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > ---
> > Changes in v2:
> > - Drop RFC state
> > - Mention interested parties in cover letter
> > - Expand Kconfig description
> > - Add compatibility with CONFIG_MODULE_SIG
> > - Parallelize module-hashes.sh
> > - Update Documentation/kbuild/reproducible-builds.rst
> > - Link to v1: https://lore.kernel.org/r/20241225-module-hashes-v1-0-d710ce7a3fd1@weissschuh.net
> > 
> > ---
> > Thomas Weißschuh (6):
> >       kbuild: add stamp file for vmlinux BTF data
> >       module: Make module loading policy usable without MODULE_SIG
> >       module: Move integrity checks into dedicated function
> >       module: Move lockdown check into generic module loader
> >       lockdown: Make the relationship to MODULE_SIG a dependency
> >       module: Introduce hash-based integrity checking
> > 
> >  .gitignore                                   |  1 +
> >  Documentation/kbuild/reproducible-builds.rst |  5 ++-
> >  Makefile                                     |  8 ++++-
> >  include/asm-generic/vmlinux.lds.h            | 11 ++++++
> >  include/linux/module.h                       |  8 ++---
> >  include/linux/module_hashes.h                | 17 +++++++++
> >  kernel/module/Kconfig                        | 21 ++++++++++-
> >  kernel/module/Makefile                       |  1 +
> >  kernel/module/hashes.c                       | 52 +++++++++++++++++++++++++++
> >  kernel/module/internal.h                     |  8 +----
> >  kernel/module/main.c                         | 54 +++++++++++++++++++++++++---
> >  kernel/module/signing.c                      | 24 +------------
> >  scripts/Makefile.modfinal                    | 10 ++++--
> >  scripts/Makefile.vmlinux                     |  5 +++
> >  scripts/link-vmlinux.sh                      | 31 +++++++++++++++-
> >  scripts/module-hashes.sh                     | 26 ++++++++++++++
> >  security/lockdown/Kconfig                    |  2 +-
> >  17 files changed, 238 insertions(+), 46 deletions(-)
> > ---
> > base-commit: 2cd5917560a84d69dd6128b640d7a68406ff019b
> > change-id: 20241225-module-hashes-7a50a7cc2a30
> > 
> > Best regards,
>
Roberto Sassu Jan. 21, 2025, 1:11 p.m. UTC | #3
On Tue, 2025-01-21 at 13:58 +0100, Thomas Weißschuh wrote:
> Hi Roberto,
> 
> On 2025-01-21 11:26:29+0100, Roberto Sassu wrote:
> > On Mon, 2025-01-20 at 18:44 +0100, Thomas Weißschuh wrote:
> > > The current signature-based module integrity checking has some drawbacks
> > > in combination with reproducible builds:
> > > Either the module signing key is generated at build time, which makes
> > > the build unreproducible, or a static key is used, which precludes
> > > rebuilds by third parties and makes the whole build and packaging
> > > process much more complicated.
> > > Introduce a new mechanism to ensure only well-known modules are loaded
> > > by embedding a list of hashes of all modules built as part of the full
> > > kernel build into vmlinux.
> > > 
> > > Interest has been proclaimed by NixOS, Arch Linux, Proxmox, SUSE and the
> > > general reproducible builds community.
> > > 
> > > To properly test the reproducibility in combination with CONFIG_INFO_BTF
> > > another patch is needed:
> > > "[PATCH bpf-next] kbuild, bpf: Enable reproducible BTF generation" [0]
> > > (If you happen to test that one, please give some feedback)
> > > 
> > > Questions for current patch:
> > > * Naming
> > > * Can the number of built-in modules be retrieved while building
> > >   kernel/module/hashes.o? This would remove the need for the
> > >   preallocation step in link-vmlinux.sh.
> > > 
> > > Further improvements:
> > > * Use a LSM/IMA/Keyring to store and validate hashes
> > 
> > + linux-integrity, Mimi
> > 
> > Hi Thomas
> > 
> > I developed something related to it, it is called Integrity Digest
> > Cache [1].
> 
> Thanks for the pointer.
> 
> > It has the ability to store in the kernel memory a cache of digests
> > extracted from a file (or if desired in the future, from a reserved
> > area in the kernel image).
> > 
> > It exposes an API to query a digest (get/lookup/put) from a digest
> > cache and to verify whether or not the integrity of the file digests
> > were extracted from was verified by IMA or another LSM
> > (verif_set/verif_get). 
> 
> I see how this could be used together with the module hashes.
> For now I think both features should be developed independently.
> Integrating them will require some extra code and coordination.

Yes, I agree.

> While the current linear, unsorted list of hashes used by my code may be
> slightly inefficient, it shouldn't matter in practize as the hash
> validation is only a bunch of memcmp()s over a contiguous chunk of
> memory, which is very cheap.

Ok, I guess so, should not be too slow for this use case.

> When both features are well established we can look at integrating them.
> At least a build-time userspace generator of a digest cache would be
> necessary.
> And due to the current implementation details it would be necessary to
> estimate the size of a static digest cache more or less exactly by its
> number of elements alone.

This information is included in the digest list, since it is also used
by the Integrity Digest Cache itself to determine the correct size of
the hash table.

Thanks

Roberto

> Thomas
> 
> > [1]: https://lore.kernel.org/linux-integrity/20241119104922.2772571-1-roberto.sassu@huaweicloud.com/
> > 
> > > * Use MODULE_SIG_HASH for configuration
> > > * UAPI for discovery?
> > > 
> > > [0] https://lore.kernel.org/lkml/20241211-pahole-reproducible-v1-1-22feae19bad9@weissschuh.net/
> > > 
> > > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > > ---
> > > Changes in v2:
> > > - Drop RFC state
> > > - Mention interested parties in cover letter
> > > - Expand Kconfig description
> > > - Add compatibility with CONFIG_MODULE_SIG
> > > - Parallelize module-hashes.sh
> > > - Update Documentation/kbuild/reproducible-builds.rst
> > > - Link to v1: https://lore.kernel.org/r/20241225-module-hashes-v1-0-d710ce7a3fd1@weissschuh.net
> > > 
> > > ---
> > > Thomas Weißschuh (6):
> > >       kbuild: add stamp file for vmlinux BTF data
> > >       module: Make module loading policy usable without MODULE_SIG
> > >       module: Move integrity checks into dedicated function
> > >       module: Move lockdown check into generic module loader
> > >       lockdown: Make the relationship to MODULE_SIG a dependency
> > >       module: Introduce hash-based integrity checking
> > > 
> > >  .gitignore                                   |  1 +
> > >  Documentation/kbuild/reproducible-builds.rst |  5 ++-
> > >  Makefile                                     |  8 ++++-
> > >  include/asm-generic/vmlinux.lds.h            | 11 ++++++
> > >  include/linux/module.h                       |  8 ++---
> > >  include/linux/module_hashes.h                | 17 +++++++++
> > >  kernel/module/Kconfig                        | 21 ++++++++++-
> > >  kernel/module/Makefile                       |  1 +
> > >  kernel/module/hashes.c                       | 52 +++++++++++++++++++++++++++
> > >  kernel/module/internal.h                     |  8 +----
> > >  kernel/module/main.c                         | 54 +++++++++++++++++++++++++---
> > >  kernel/module/signing.c                      | 24 +------------
> > >  scripts/Makefile.modfinal                    | 10 ++++--
> > >  scripts/Makefile.vmlinux                     |  5 +++
> > >  scripts/link-vmlinux.sh                      | 31 +++++++++++++++-
> > >  scripts/module-hashes.sh                     | 26 ++++++++++++++
> > >  security/lockdown/Kconfig                    |  2 +-
> > >  17 files changed, 238 insertions(+), 46 deletions(-)
> > > ---
> > > base-commit: 2cd5917560a84d69dd6128b640d7a68406ff019b
> > > change-id: 20241225-module-hashes-7a50a7cc2a30
> > > 
> > > Best regards,
> >