microsoft / MSRSec

Security and Privacy Research at Microsoft
MIT License
38 stars 29 forks source link

fTPM TA crashes during Linux powerdown/reboot #36

Open dgarrett-microsoft opened 2 years ago

dgarrett-microsoft commented 2 years ago

I've found that the fTPM TA crashes consistently during Linux powerdown/reboot. The issue seems to be that the Linux TPM driver issues TPM2_Shutdown to attached TPMs during powerdown. The fTPM's implementation of TPM2_Shutdown makes some writes to storage, which fail because tee-supplicant is already stopped as a result of the powerdown.

         Stopping TEE Supplicant...
...
[  OK  ] Stopped TEE Supplicant.
...
[  OK  ] Finished System Reboot.
[  OK  ] Reached target System Reboot.
D/TA:  fTPM_Submit_Command:270 fTPM submit command
D/TA:  _plat__MarkDirtyBlocks:532 Marking blocks 1 to 2 dirty
D/TA:  _plat__MarkDirtyBlocks:532 Marking blocks 1 to 2 dirty
D/TA:  _plat__MarkDirtyBlocks:532 Marking blocks 1 to 2 dirty
D/TA:  _plat__MarkDirtyBlocks:532 Marking blocks 0 to 1 dirty
D/TA:  _plat__NvWriteBack:271 Start writeback.
D/TA:  _plat__NvWriteBack:290 Writing block at 0x4007c228 back
E/TC:? 0 
E/TC:? 0 TA panicked with code 0xffff000c
E/LD:  Status of TA bc50d971-d4c9-42c4-82cb-343fb7f37896
E/LD:   arch: aarch64
E/LD:  region  0: va 0x40004000 pa 0xa6200000 size 0x002000 flags rw-s (ldelf)
E/LD:  region  1: va 0x40006000 pa 0xa6202000 size 0x008000 flags r-xs (ldelf)
E/LD:  region  2: va 0x4000e000 pa 0xa620a000 size 0x001000 flags rw-s (ldelf)
E/LD:  region  3: va 0x4000f000 pa 0xa620b000 size 0x004000 flags rw-s (ldelf)
E/LD:  region  4: va 0x40013000 pa 0xa620f000 size 0x001000 flags r--s
E/LD:  region  5: va 0x40015000 pa 0xa7c00000 size 0x003000 flags rw-- (param)
E/LD:  region  6: va 0x40024000 pa 0x00001000 size 0x055000 flags r-xs [0]
E/LD:  region  7: va 0x40079000 pa 0x00056000 size 0x024000 flags rw-s [0]
E/LD:  region  8: va 0x4009d000 pa 0xa6289000 size 0x011000 flags rw-s (stack)
E/LD:   [0] bc50d971-d4c9-42c4-82cb-343fb7f37896 @ 0x40024000
E/LD:  Call stack:
E/LD:   0x40056400
E/LD:   0x4002505c
E/LD:   0x40025a08
E/LD:   0x4004b9c4
E/LD:   0x40047614
E/LD:   0x40024438
E/LD:   0x4005aac8
E/LD:   0x40052b98
D/TC:? 0 user_ta_enter:176 tee_user_ta_enter: TA panicked with code 0xffff000c
D/TC:? 0 destroy_ta_ctx_from_session:324 Remove references to context (0xa60d0ae8)
D/TC:? 0 destroy_context:308 Destroy TA ctx (0xa60d0ad0)
[  108.320534] tpm tpm0: ftpm_tee_tpm_op_send: SUBMIT_COMMAND invoke error: 0xffff3024
[  108.328217] tpm tpm0: tpm_try_transmit: send(): error -53212
[  108.353635] reboot: Restarting system

I was able to work around this with the following systemd unit that unloads the fTPM Linux driver before tee-supplicant is stopped:

[Unit]
Description=OP-TEE fTPM
After=tee-supplicant.service

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=sh -c "echo -n 'optee-ta-bc50d971-d4c9-42c4-82cb-343fb7f37896' > /sys/bus/tee/drivers/optee-ftpm/unbind"

[Install]
WantedBy=multi-user.target

But as far as I can tell, this is a bug. Does anyone have any thoughts on where this should be fixed? Or is my systemd unit likely the best solution here to get the appropriate order of operations?

jan-kiszka commented 1 year ago

We need an in-kernel tee-supplicant, for RPMB access at least. See also discussion about StandAloneMM support (https://lkml.kernel.org/lkml/20230622085112.1521-3-masahisa.kojima@linaro.org/T/#m9552b4a9a88a20753bf068cf21ced84f6cbe880f)