Skip to content

Make IMA able to wait and correctly detect the TPM device #5003

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 24, 2022

Conversation

AlbertoSvg
Copy link
Contributor

Problem:

We encountered a problem with IMA detecting the TPM device.
Here is our .config where we enabled these modules to be built-in:

CONFIG_INTEGRITY=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_NG_TEMPLATE=y
CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
CONFIG_IMA_DEFAULT_HASH_SHA256=y
CONFIG_IMA_DEFAULT_HASH="sha256"
CONFIG_IMA_AUDIT=y
CONFIG_IMA_LSM_RULES=y
CONFIG_TCG_TPM=y
CONFIG_HW_RANDOM_TPM=y
CONFIG_TCG_TIS_CORE=y
CONFIG_TCG_TIS_SPI=y
CONFIG_SPI_BCM2835=y

We have noticed that in the function ima_init() there is a call to tpm_default_chip() that should return a valid tpm instance, but it always fails to "No TPM chip found, activating TPM-bypass!\n". In that function there is a call to idr_get_next() which returns NULL because the idr_replace() function in tpm_add_char_device() is called after the call to
ima_init()->tpm_default_chip().
We introduced some debugging prints in order to detect the function calls order (Figure 1). In the picture below (Figure 2), we can see that the idr_replace() is called at second 2.3 ("tpm: TPM available" print) which is after ima_init calls tpm_default_chip to retrieve the tpm device (which takes only 1.65 seconds).
To recap, at second 1.65 IMA did not find any TPM because the TPM device registration/loading finishes later.

Figure 1
stampa

Figure 2
problem

Solution:

We managed to get TPM finish before IMA looks for it by making the following changes.

  1. First we postponed the bcm2835 clock driver initialization by substituting the postcore_initcall(__bcm2835_clk_driver_init) with subsys_initcall(__bcm2835_clk_driver_init).

  2. Second we forced the “TPM Driver for native SPI access” to run its probe routine synchronously with driver and device registration when IMA is enabled. In this way we are sure that the TPM registration finishes before IMA starts looking for the TPM device.

static struct spi_driver tpm_tis_spi_driver = {
	.driver = {
		.name = "tpm_tis_spi",
		.pm = &tpm_tis_pm,
		.of_match_table = of_match_ptr(of_tis_spi_match),
		.acpi_match_table = ACPI_PTR(acpi_tis_spi_match),
#ifdef CONFIG_IMA
		.probe_type = PROBE_FORCE_SYNCHRONOUS,
#else
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
#endif
	},
	.probe = tpm_tis_spi_driver_probe,
	.remove = tpm_tis_spi_remove,
	.id_table = tpm_tis_spi_id,
};
module_spi_driver(tpm_tis_spi_driver);

MODULE_DESCRIPTION("TPM Driver for native SPI access");

In the picture below (Figure 3) we show that IMA successfully found the TPM device and didn’t fall in bypass mode.

Figure 3
solution

AlbertoSvg and others added 2 commits April 20, 2022 17:15
…bled



Co-authored-by: Davide Scovotto <[email protected]>
Co-developed-by: Davide Scovotto <[email protected]>
Signed-off-by: Davide Scovotto <[email protected]>
Signed-off-by: Alberto Solavagione <[email protected]>
…r and device registration when IMA is enabled



Co-authored-by: Alberto Solavagione <[email protected]>
Co-developed-by: Alberto Solavagione <[email protected]>
Signed-off-by: Alberto Solavagione <[email protected]>
Signed-off-by: Davide Scovotto <[email protected]>
@lategoodbye
Copy link
Contributor

I would appreciate if security related and critical changes are send to the official kernel mailing lists for a review.

@AlbertoSvg
Copy link
Contributor Author

AlbertoSvg commented Apr 23, 2022

@lategoodbye Ok, thank you very much. Could you tell us who we should contact? We were thinking to contact IMA/TPM mantainers, do you think it's the best choice?

@lategoodbye
Copy link
Contributor

@AlbertoSvg To be honest, this wont be trivial like creating a pull request here. At first the issue must be reproduced with a mainline kernel (torvalds tree without optimizations from here). I could prepare a branch (based on 5.18-rcX) with the necessary changes for you.

Which Raspberry Pi do you use?

@pelwell
Copy link
Contributor

pelwell commented Apr 24, 2022

I've been wary about tampering with the initcall level in the past because of unintended consequences, but as this is conditional on a less common, non-standard (to us) config setting, the chances of anything going wrong are much reduced.

@pelwell pelwell merged commit 66265ec into raspberrypi:rpi-5.15.y Apr 24, 2022
@davinat0r
Copy link
Contributor

I'm the co-developer of this PR together with @AlbertoSvg. We thank you for accepting our solution.
Regards.
@pelwell @lategoodbye

popcornmix added a commit to raspberrypi/firmware that referenced this pull request Apr 25, 2022
See: raspberrypi/linux#5006

kernel: overlays: Add drm parameter to pitft28-resistive
See: raspberrypi/linux#5004

kernel: Make IMA able to wait and correctly detect the TPM device
See: raspberrypi/linux#5003
popcornmix added a commit to raspberrypi/rpi-firmware that referenced this pull request Apr 25, 2022
See: raspberrypi/linux#5006

kernel: overlays: Add drm parameter to pitft28-resistive
See: raspberrypi/linux#5004

kernel: Make IMA able to wait and correctly detect the TPM device
See: raspberrypi/linux#5003
@mpeters
Copy link

mpeters commented May 9, 2022

I know this is closed and merged, but I'm still having the same issue even after this PR. My Infineon Optiga SLB 9670 takes a long time to load (17s?!?) and IMA has long given up on it by then. Any thoughts on how/why this is and what I can do to remedy it? Btw, I'm running with your debug patch to add the extra log entry so it's clearly visible when the TPM becomes available.

[pi@pi-01 ~]$ sudo dmesg | grep -i 'ima\|tpm'
[sudo] password for pi: 
[    0.000000] Kernel command line: BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+ root=UUID=0cf3008c-e4cd-461e-a3d4-b882a513fba7 ro rhgb quiet console=tty0 ima=on ima_policy=tcb
[    0.000000] Unknown kernel command line parameters "rhgb BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+ ima=on", will be passed to user space.
[    1.082341] Trying to unpack rootfs image as initramfs...
[    2.483756] device-mapper: core: CONFIG_IMA_DISABLE_HTABLE is disabled. Duplicate IMA measurements will not be recorded in the IMA log.
[    2.698338] ima: secureboot mode disabled
[    2.698351] ima: No TPM chip found, activating TPM-bypass!
[    2.701447] ima: Allocated hash algorithm: sha256
[    2.701513] ima: No architecture policies found
[    2.701640] evm: security.ima
[    2.853735]     BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+
[    2.853740]     ima=on
[    3.263467] systemd[1]: systemd v249.11-2.fc35 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[    8.419969] systemd[1]: Successfully loaded the IMA custom policy /etc/ima/ima-policy.
[    8.419997] ima: policy update completed
[    8.906255] systemd[1]: systemd v249.11-2.fc35 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
[   16.401124] unimac-mdio unimac-mdio.-19: Broadcom UniMAC MDIO bus
[   17.077361] tpm_tis_spi spi0.1: 2.0 TPM (device-id 0x1B, rev-id 22)
[   17.119791] TPM chip available

@davinat0r
Copy link
Contributor

@mpeters If the TPM driver is loaded so late it is probable that you did not set the TPM module as built-in.
Can you show the TPM and IMA entries of your .config file ?
We specified at the top of this PR our .config file.

@mpeters
Copy link

mpeters commented May 9, 2022

@ScovottoDavide it's using this .config file: https://gist.github.com/jimcadden/38122c9b89083e4a619f1e7fdc234ee1

@davinat0r
Copy link
Contributor

davinat0r commented May 9, 2022

Try to recompile the kernel by modifying this two lines:

CONFIG_TCG_TIS_SPI=m
CONFIG_SPI_BCM2835=m

To

CONFIG_TCG_TIS_SPI=y
CONFIG_SPI_BCM2835=y

In this way you enable to load those modules as built-in, and you will see that the loading time of the TPM should reduce by a lot and everything should work. Built-in modules (=y) are loaded before any loadable modules (=m), you have not set SPI to be built-in.
@mpeters

@mpeters
Copy link

mpeters commented May 9, 2022

@ScovottoDavide thanks, that actually helps a lot, but it still doesn't quite get there. After recompiling I get this:

[    0.000000] Kernel command line: BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+ root=UUID=0cf3008c-e4cd-461e-a3d4-b882a513fba7 ro rhgb quiet console=tty0 ima=on ima_policy=tcb
[    0.000000] Unknown kernel command line parameters "rhgb BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+ ima=on", will be passed to user space.
[    1.072550] Trying to unpack rootfs image as initramfs...
[    8.161405] ima: secureboot mode disabled
[    8.161418] ima: No TPM chip found, activating TPM-bypass!
[    8.164508] ima: Allocated hash algorithm: sha256
[    8.164574] ima: No architecture policies found
[    8.164692] evm: security.ima
[    8.302674]     ima=on
[   10.283086] tpm_tis_spi spi0.1: 2.0 TPM (device-id 0x1B, rev-id 22)
[   14.006937] systemd[1]: Successfully loaded the IMA custom policy /etc/ima/ima-policy.
[   14.006965] ima: policy update completed
[   22.040716] unimac-mdio unimac-mdio.-19: Broadcom UniMAC MDIO bus

So IMA still checks for the TPM before it's ready, even if the gap is down to 2 seconds now.

@davinat0r
Copy link
Contributor

@mpeters Mmm, can you run the kernel by passing the option "initcall_debug" on the command line (cmdline.txt file) and send me the resulting log?

@mpeters
Copy link

mpeters commented May 10, 2022

@mpeters Mmm, can you run the kernel by passing the option "initcall_debug" on the command line (cmdline.txt file) and send me the resulting log?

@ScovottoDavide The whole log? Or just the parts that match tpm\|ima ?

@mpeters
Copy link

mpeters commented May 10, 2022

@ScovottoDavide it appears the tpm_tis_spi driver is being init'd before IMA, but dtpm is happening after IMA:

[    0.000000] Kernel command line: BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+ root=UUID=0cf3008c-e4cd-461e-a3d4-b882a513fba7 ro rhgb quiet console=tty0 ima=on ima_policy=tcb initcall_debug
[    0.000000] Unknown kernel command line parameters "rhgb BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.36+ ima=on", will be passed to user space.
[    0.983565] calling  tpm_init+0x0/0x128 @ 1
[    0.983820] initcall tpm_init+0x0/0x128 returned 0 after 0 usecs
[    1.086246] Trying to unpack rootfs image as initramfs...
[    2.490420] calling  tpm_tis_spi_driver_init+0x0/0x30 @ 1
[    2.490455] initcall tpm_tis_spi_driver_init+0x0/0x30 returned 0 after 20 usecs
[    2.718138] calling  init_ima+0x0/0xdc @ 1
[    2.718221] ima: secureboot mode disabled
[    2.718234] ima: No TPM chip found, activating TPM-bypass!
[    2.721343] ima: Allocated hash algorithm: sha256
[    2.721404] ima: No architecture policies found
[    2.721481] initcall init_ima+0x0/0xdc returned 0 after 3254 usecs
[    2.721544] evm: security.ima
[    2.732983] calling  dtpm_init+0x0/0x94 @ 1
[    2.733083] initcall dtpm_init+0x0/0x94 returned 0 after 86 usecs
[    2.846338]     ima=on
[    4.819466] tpm_tis_spi spi0.1: 2.0 TPM (device-id 0x1B, rev-id 22)
[    8.360876] systemd[1]: Successfully loaded the IMA custom policy /etc/ima/ima-policy.
[    8.360903] ima: policy update completed
[   16.097119] calling  unimac_mdio_driver_init+0x0/0x1000 [mdio_bcm_unimac] @ 418
[   16.115159] initcall unimac_mdio_driver_init+0x0/0x1000 [mdio_bcm_unimac] returned 0 after 17566 usecs
[   16.542241] unimac-mdio unimac-mdio.-19: Broadcom UniMAC MDIO bus

@mpeters
Copy link

mpeters commented May 10, 2022

@mpeters
Copy link

mpeters commented May 10, 2022

@ScovottoDavide it appears the tpm_tis_spi driver is being init'd before IMA, but dtpm is happening after IMA:

nvm, dtpm is about power management, not the TPM.

@AlbertoSvg
Copy link
Contributor Author

AlbertoSvg commented May 11, 2022

@mpeters You can try to disable these configurations (by setting them to "n"), because i think that linux is choosing another driver and our solution was for the SPI one.

CONFIG_TCG_TIS=n
CONFIG_TCG_TIS_SPI_CR50=n
CONFIG_TCG_TIS_SYNQUACER=n
CONFIG_TCG_TIS_I2C_ATMEL=n
CONFIG_TCG_TIS_I2C_INFINEON=n
CONFIG_TCG_TIS_I2C_NUVOTON=n
CONFIG_TCG_ATMEL=n
CONFIG_TCG_CRB=n
CONFIG_TCG_VTPM_PROXY=n
CONFIG_TCG_FTPM_TEE=n

You set to "y" only these ones:

CONFIG_TCG_TPM=y
CONFIG_HW_RANDOM_TPM=y
CONFIG_TCG_TIS_CORE=y
CONFIG_TCG_TIS_SPI=y

Do you have these two lines set in /boot/config.txt? :

dtparam=spi=on
dtoverlay=tpm-slb9670

Can you also tell us what is your setup? (raspberry, OS, ...)

@mpeters
Copy link

mpeters commented May 11, 2022

Even with those config options, it's still having the same issue:

[pi@pi-01 ~]$ sudo dmesg | grep 'tpm\|ima'
[sudo] password for pi: 
[    0.000000] Kernel command line: BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.38+ root=UUID=0cf3008c-e4cd-461e-a3d4-b882a513fba7 ro rhgb quiet console=tty0 ima=on ima_policy=tcb initcall_debug
[    0.000000] Unknown kernel command line parameters "rhgb BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.38+ ima=on", will be passed to user space.
[    0.983532] calling  tpm_init+0x0/0x128 @ 1
[    0.983786] initcall tpm_init+0x0/0x128 returned 0 after 0 usecs
[    1.086680] Trying to unpack rootfs image as initramfs...
[    2.486835] calling  tpm_tis_spi_driver_init+0x0/0x30 @ 1
[    2.486872] initcall tpm_tis_spi_driver_init+0x0/0x30 returned 0 after 23 usecs
[    2.714502] calling  init_ima+0x0/0xdc @ 1
[    2.714588] ima: secureboot mode disabled
[    2.714599] ima: No TPM chip found, activating TPM-bypass!
[    2.717684] ima: Allocated hash algorithm: sha256
[    2.717747] ima: No architecture policies found
[    2.717847] initcall init_ima+0x0/0xdc returned 0 after 3256 usecs
[    2.717912] evm: security.ima
[    2.729233] calling  dtpm_init+0x0/0x94 @ 1
[    2.729337] initcall dtpm_init+0x0/0x94 returned 0 after 89 usecs
[    2.855696]     ima=on
[    4.773715] tpm_tis_spi spi0.1: 2.0 TPM (device-id 0x1B, rev-id 22)
[    8.320276] systemd[1]: Successfully loaded the IMA custom policy /etc/ima/ima-policy.
[    8.320304] ima: policy update completed

My /boot/efi/config.txt has the following:

[pi4]
kernel=rpi4-u-boot.bin
dtoverlay=upstream-pi4
dtparam=i2c_arm=on
dtparam=spi=on
dtoverlay=tpm-slb9670

I'm using a Raspberry Pi 4 B with an Infineon Optiga SLB 9670 TPM chip. I'm running Fedora 35 with a custom built (using the options I've posted above) raspberry PI kernel.

@AlbertoSvg
Copy link
Contributor Author

AlbertoSvg commented May 11, 2022

@mpeters Ok, we have It working on different Raspberry Pis, so It is strange to me that is not working. Your configuration seems also very similar to our, two things that i noticed are different are these lines kernel=rpi4-u-boot.bin and dtoverlay=upstream-pi4 in config.txt.
Anyway can you do me another favor? Add a log line in
tpm_tis_spi_main.c, precisely in the function tpm_tis_spi_driver_probe to check of it is calling the right probing function.

@mpeters
Copy link

mpeters commented May 11, 2022

@AlbertoSvg I changed the tpm_tis_spi_driver_probe to look like this:

--- a/drivers/char/tpm/tpm_tis_spi_main.c
+++ b/drivers/char/tpm/tpm_tis_spi_main.c
@@ -243,10 +243,17 @@ static int tpm_tis_spi_driver_probe(struct spi_device *spi)
        if (!probe_func) {
                if (spi_dev_id) {
                        probe_func = (tpm_tis_spi_probe_func)spi_dev_id->driver_data;
-                       if (!probe_func)
+                       if (!probe_func) {
                                return -ENODEV;
-               } else
+                       } else {
+                               pr_info("Probe func found from spi_dev_id\n");
+                       }
+               } else {
                        probe_func = tpm_tis_spi_probe;
+                       pr_info("Probe func using tpm_tis_spi_probe\n");
+               }
+       } else {
+               pr_info("Probe func found from of_device_get_match_data\n");
        }

And then dmesg gives this:

[    4.755891] initcall bcm2835_dma_init+0x0/0x38 [bcm2835_dma] returned 0 after 1912 usecs
[    4.756244] Probe func found from of_device_get_match_data
[    4.760753] audit: type=1130 audit(1649721601.519:10): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=kernel msg='unit=systemd-udev-trigger comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
[    4.762835] calling  sdhci_iproc_driver_init+0x0/0x1000 [sdhci_iproc] @ 243
[    4.762881] tpm_tis_spi spi0.1: 2.0 TPM (device-id 0x1B, rev-id 22)
[    4.765689] tpm tpm0: A TPM error (256) occurred attempting the self test
[    4.765724] tpm tpm0: starting up the TPM manually

which is, again, still ~2s after IMA startup. Is this what you were expecting from the probe?

@davinat0r
Copy link
Contributor

davinat0r commented May 11, 2022

@mpeters So from our understanding, correct me if I'm wrong, you're not using the default boot loader and you're building the upstream kernel.

Just to be sure, are you using the rpi 5.15.y kernel?

The cause of your problem it may be coming from your custom configuration. This patch has not been tested upstream.

P.S. just for curiosity, did you remove the debug line "TPM chip available" that you set up at the beginning? I saw that in your dmesg was not there anymore.

@mpeters
Copy link

mpeters commented May 12, 2022

@mpeters So from our understanding, correct me if I'm wrong, you're not using the default boot loader and you're building the upstream kernel.

Yes

Just to be sure, are you using the rpi 5.15.y kernel?

Yes, I'm in the rpi-5.15.y branch of this repo.

The cause of your problem it may be coming from your custom configuration. This patch has not been tested upstream.

P.S. just for curiosity, did you remove the debug line "TPM chip available" that you set up at the beginning? I saw that in your dmesg was not there anymore.

Oh interesting. No, I didn't remove it, but it's not showing up in the output anymore. I missed that. My tpm-chip.c still has this diff:

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 65d800ecc996..6edd2c932742 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -418,12 +418,14 @@ static int tpm_add_char_device(struct tpm_chip *chip)
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                rc = tpm_devs_add(chip);
                if (rc)
                        goto err_del_cdev;
        }
 
        /* Make the chip available. */
        mutex_lock(&idr_lock);
        idr_replace(&dev_nums_idr, chip, chip->dev_num);
+       pr_info("TPM chip available\n");
        mutex_unlock(&idr_lock);
 
        return 0;

I'll add a few more debugging statements to see if I can notice why...

@AlbertoSvg
Copy link
Contributor Author

@mpeters
Ok, that's a problem, since the TPM device registration should call that debug line.

This should be the flow of the TPM registration:

  1. Call to this (tpm_tis_spi_driver_probe) probing function synchronously
static struct spi_driver tpm_tis_spi_driver = {
	.driver = {
		.name = "tpm_tis_spi",
		.pm = &tpm_tis_pm,
		.of_match_table = of_match_ptr(of_tis_spi_match),
		.acpi_match_table = ACPI_PTR(acpi_tis_spi_match),
#ifdef CONFIG_IMA
		.probe_type = PROBE_FORCE_SYNCHRONOUS,
#else
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
#endif
	},
	.probe = tpm_tis_spi_driver_probe,
	.remove = tpm_tis_spi_remove,
	.id_table = tpm_tis_spi_id,
};
module_spi_driver(tpm_tis_spi_driver);
  1. call to tpm_tis_spi_probe
  2. call to tpm_tis_spi_init
  3. call to tpm_tis_core_init
  4. call to tpm_chip_register
  5. call to tpm_add_char_device where there is the debug line

The problem could be that you are integrating the upstream kernel with this one.

By chance would you be able to give us a detailed description of how to build you custom kernel in order to be able to replicate it and test it?

@mpeters
Copy link

mpeters commented May 17, 2022

Sorry for the delay, but just now coming back to this with more info:

@mpeters Ok, that's a problem, since the TPM device registration should call that debug line.

Yeah, not sure why it wasn't there, but that doesn't seem like the problem anymore. I've added a few more debugging lines to tpm_add_char_device as follows:

 static int tpm_add_char_device(struct tpm_chip *chip)
 {
        int rc;
+       pr_info("mpeters: In tpm_add_char_device\n");
 
        rc = cdev_device_add(&chip->cdev, &chip->dev);
        if (rc) {
+               pr_info("mpeters: After cdev_device_add with return code %d\n", rc);
                dev_err(&chip->dev,
                        "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
                        dev_name(&chip->dev), MAJOR(chip->dev.devt),
@@ -417,13 +419,16 @@ static int tpm_add_char_device(struct tpm_chip *chip)
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                rc = tpm_devs_add(chip);
+               pr_info("mpeters: After tpm_devs_add with return code %d\n", rc);
                if (rc)
                        goto err_del_cdev;
        }
 
        /* Make the chip available. */
+       pr_info("mpeters: Making TPM chip available\n");
        mutex_lock(&idr_lock);
        idr_replace(&dev_nums_idr, chip, chip->dev_num);
+       pr_info("mpeters: TPM chip available\n");
        mutex_unlock(&idr_lock);
 
        return 0;

as well as some debug lines at the beginning of each function call you mentioned in the chain (I added a "mpeters: " prefix to those info lines just to make it easier to see) and they are executing as expected, just after IMA is done initializing:

[pi@pi-01 ~]$ sudo dmesg | grep 'tpm\|ima\|mpeters'
[sudo] password for pi: 
[    0.000000] Kernel command line: BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.40+ root=UUID=0cf3008c-e4cd-461e-a3d4-b882a513fba7 ro rhgb quiet console=tty0 ima=on ima_policy=tcb initcall_debug
[    0.000000] Unknown kernel command line parameters "rhgb BOOT_IMAGE=(hd0,msdos2)/vmlinuz-5.15.40+ ima=on", will be passed to user space.
[    0.982658] calling  tpm_init+0x0/0x128 @ 1
[    0.982895] initcall tpm_init+0x0/0x128 returned 0 after 0 usecs
[    1.088087] Trying to unpack rootfs image as initramfs...
[    7.995041] calling  tpm_tis_spi_driver_init+0x0/0x30 @ 1
[    7.995074] initcall tpm_tis_spi_driver_init+0x0/0x30 returned 0 after 21 usecs
[    8.222934] calling  init_ima+0x0/0xdc @ 1
[    8.223023] ima: secureboot mode disabled
[    8.223036] ima: No TPM chip found, activating TPM-bypass!
[    8.226114] ima: Allocated hash algorithm: sha256
[    8.226176] ima: No architecture policies found
[    8.226251] initcall init_ima+0x0/0xdc returned 0 after 3227 usecs
[    8.226317] evm: security.ima
[    8.237868] calling  dtpm_init+0x0/0x94 @ 1
[    8.237959] initcall dtpm_init+0x0/0x94 returned 0 after 75 usecs
[    8.374928]     ima=on
[   10.400261] mpeters: In tpm_tis_spi_probe
[   10.400280] mpeters: In tpm_tis_spi_init
[   10.400286] mpeters: In tpm_tis_core_init
[   10.413643] tpm_tis_spi spi0.1: 2.0 TPM (device-id 0x1B, rev-id 22)
[   10.413734] mpeters: In tpm_chip_register
[   10.449666] mpeters: In tpm_add_char_device
[   10.451207] mpeters: After tpm_devs_add with return code 0
[   10.451218] mpeters: Making TPM chip available
[   10.451225] mpeters: TPM chip available
[   15.570078] systemd[1]: Successfully loaded the IMA custom policy /etc/ima/ima-policy.
[   15.570102] ima: policy update completed

The problem could be that you are integrating the upstream kernel with this one.

I'm not doing anything with the upstream kernel. I'm just building this one with a custom config (and loading it into a running Fedora raspi).

By chance would you be able to give us a detailed description of how to build you custom kernel in order to be able to replicate it and test it?

I'm using this config file: https://gist.github.com/mpeters/c74817e4a862c9583ee9247be17b5650 (which is from a stock F35 kernel but with some options enabled for the broadcom and GPIO modules) and then using make oldconfig to update it for this kernel (which results in this .config https://gist.github.com/mpeters/0d283fbb17a69d029112f007994b2d56), and then what I'm doing is pretty straight forward. I used the raspi image installer to install the Fedora-Minimal-35-1.2.aarch64 (from https://alt.fedoraproject.org/alt/) image onto an SD card. I load that SD card into my raspi and go through the text install to create a user with sudo privileges and get the network setup (for wifi I use the nmcli after install to join my wifi network). I then build a custom raspi kernel from this repo (not upstream) on a aarch64 machine to replace the running Fedora one.

cp mpeters-rpi-config linux/.config
cd linux
make oldconfig
make -j 8 binrpm-pkg

This will create rpm packages in rpmbuild/RPMS/aarch64/ for the kernel and headers. My current build is named kernel-5.15.40+-24.aarch64.rpm. I then scp these to my raspi and install them and reboot (note: you might have to fiddle with grubby to make sure the latest kernel is the one that boots, or just use the grub menu during boot).

sudo dnf -y localinstall kernel-5.15.40+-24.aarch64.rpm kernel-headers-5.15.40+-24.aarch64.rpm
sudo reboot

Nothing too fancy or complicated. So if something is amiss it's probably still in my config file.

@mpeters
Copy link

mpeters commented May 18, 2022

@AlbertoSvg would you mind sharing with me a config file that you use that you know works?

@AlbertoSvg
Copy link
Contributor Author

@mpeters This is our .config: https://gist.github.com/AlbertoSvg/f460e03c6707ad01a2d321a4ff54b003
When i have time i will try to replicate your configuration on our system and see if i can find out what is the problem

@mpeters
Copy link

mpeters commented May 24, 2022

@AlbertoSvg btw, I can confirm that compiling the latest kernel on the raspi itself with the stock config + your additions at the top (enabling IMA and the TPM) does indeed work. So now I need to figure out what differences between this config and the Fedora one are causing the problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants