Skip to content

Commit 5fe14d8

Browse files
shjalaeriknordmark
authored andcommitted
tpm : make file write resilient to sudden crash/poweroff
Use WriteRename to be resilient against sudden crash/poweroff, it will create a tmp file, writes to and does a atomic rename. This commit also fixes some mindless yetus complains on using %w instead of %v. Signed-off-by: Shahriyar Jalayeri <[email protected]>
1 parent 932a03f commit 5fe14d8

File tree

2 files changed

+24
-28
lines changed

2 files changed

+24
-28
lines changed

pkg/pillar/cmd/vaultmgr/vaultmgr.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ func handleVaultKeyFromControllerImpl(ctxArg interface{}, key string,
456456
}
457457
log.Warnln("default vault removed")
458458
if err := handler.SetupDefaultVault(); err != nil {
459-
log.Errorf("setupDefaultVault failed, err: %v", err)
459+
log.Errorf("SetupDefaultVault failed, err: %v", err)
460460
getAndPublishAllVaultStatuses(ctx)
461461
return
462462
}
@@ -494,12 +494,12 @@ func publishVaultKey(ctx *vaultMgrContext, vaultName string) error {
494494
}
495495
keyBytes, err := etpm.FetchSealedVaultKey(log)
496496
if err != nil {
497-
return fmt.Errorf("Failed to retrieve key from TPM %v", err)
497+
return fmt.Errorf("Failed to retrieve key from TPM %w", err)
498498
}
499499

500500
encryptedKey, err := etpm.EncryptDecryptUsingTpm(keyBytes, true)
501501
if err != nil {
502-
return fmt.Errorf("Failed to encrypt vault key %v", err)
502+
return fmt.Errorf("Failed to encrypt vault key %w", err)
503503
}
504504

505505
hash := sha256.New()
@@ -512,7 +512,7 @@ func publishVaultKey(ctx *vaultMgrContext, vaultName string) error {
512512
}
513513
encryptedVaultKey, err = proto.Marshal(keyData)
514514
if err != nil {
515-
return fmt.Errorf("Failed to Marshal keyData %v", err)
515+
return fmt.Errorf("Failed to Marshal keyData %w", err)
516516
}
517517
}
518518

pkg/pillar/evetpm/tpm.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func TpmSign(digest []byte) (*big.Int, *big.Int, error) {
197197

198198
tpmOwnerPasswd, err := ReadOwnerCrdl()
199199
if err != nil {
200-
return nil, nil, fmt.Errorf("fetching TPM credentials failed: %v", err)
200+
return nil, nil, fmt.Errorf("fetching TPM credentials failed: %w", err)
201201
}
202202

203203
//XXX This "32" should really come from Hash algo used.
@@ -212,7 +212,7 @@ func TpmSign(digest []byte) (*big.Int, *big.Int, error) {
212212
sig, err := tpm2.Sign(rw, TpmDeviceKeyHdl,
213213
tpmOwnerPasswd, digest, nil, scheme)
214214
if err != nil {
215-
return nil, nil, fmt.Errorf("signing data using TPM failed: %v", err)
215+
return nil, nil, fmt.Errorf("signing data using TPM failed: %w", err)
216216
}
217217
return sig.ECC.R, sig.ECC.S, nil
218218
}
@@ -347,6 +347,7 @@ func FetchTpmHwInfo() (string, error) {
347347
_, err := os.Stat(TpmDevicePath)
348348
if err != nil {
349349
tpmHwInfo = "Not Available"
350+
//nolint:nilerr
350351
return tpmHwInfo, nil
351352
}
352353

@@ -402,11 +403,11 @@ func FetchVaultKey(log *base.LogObject) ([]byte, error) {
402403
//
403404
key, err = GetRandom(vaultKeyLength)
404405
if err != nil {
405-
return nil, fmt.Errorf("GetRandom failed: %v", err)
406+
return nil, fmt.Errorf("GetRandom failed: %w", err)
406407
}
407408
err = writeDiskKey(key)
408409
if err != nil {
409-
return nil, fmt.Errorf("writing legacy Key to TPM failed: %v", err)
410+
return nil, fmt.Errorf("writing legacy Key to TPM failed: %w", err)
410411
}
411412
} else {
412413
log.Noticef("successfully read the legacy disk key from TPM")
@@ -501,11 +502,11 @@ func FetchSealedVaultKey(log *base.LogObject) ([]byte, error) {
501502
//
502503
key, err := GetRandom(vaultKeyLength)
503504
if err != nil {
504-
return nil, fmt.Errorf("GetRandom failed: %v", err)
505+
return nil, fmt.Errorf("GetRandom failed: %w", err)
505506
}
506507
err = SealDiskKey(key, DiskKeySealingPCRs)
507508
if err != nil {
508-
return nil, fmt.Errorf("sealing the fresh disk key failed: %v", err)
509+
return nil, fmt.Errorf("sealing the fresh disk key failed: %w", err)
509510
}
510511

511512
log.Noticef("successfully sealed the fresh disk key into TPM")
@@ -525,14 +526,14 @@ func FetchSealedVaultKey(log *base.LogObject) ([]byte, error) {
525526
//Upgrade path will be to first upgrade to a) first release and then b)
526527
key, err := readDiskKey()
527528
if err != nil {
528-
return nil, fmt.Errorf("retrieving the legacy disk key from TPM failed: %v", err)
529+
return nil, fmt.Errorf("retrieving the legacy disk key from TPM failed: %w", err)
529530
}
530531

531532
log.Noticef("try to convert the legacy key into a sealed key")
532533

533534
err = SealDiskKey(key, DiskKeySealingPCRs)
534535
if err != nil {
535-
return nil, fmt.Errorf("sealing the legacy disk key into TPM failed: %v", err)
536+
return nil, fmt.Errorf("sealing the legacy disk key into TPM failed: %w", err)
536537
}
537538
}
538539
//sealedKeyPresent && !legacyKeyPresent : unseal
@@ -587,7 +588,7 @@ func SealDiskKey(key []byte, pcrSel tpm2.PCRSelection) error {
587588

588589
priv, public, err := tpm2.Seal(rw, TpmSRKHdl, EmptyPassword, EmptyPassword, policy, key)
589590
if err != nil {
590-
return fmt.Errorf("sealing the disk key into TPM failed: %v", err)
591+
return fmt.Errorf("sealing the disk key into TPM failed: %w", err)
591592
}
592593

593594
// Define space in NV storage and clean up afterwards or subsequent runs will fail.
@@ -629,7 +630,7 @@ func SealDiskKey(key []byte, pcrSel tpm2.PCRSelection) error {
629630

630631
// save a snapshot of PCR values
631632
if err := saveDiskKeySealingPCRs(TpmSavedDiskSealingPcrs); err != nil {
632-
return fmt.Errorf("saving snapshot of sealing PCRs failed: %v", err)
633+
return fmt.Errorf("saving snapshot of sealing PCRs failed: %w", err)
633634
}
634635

635636
return nil
@@ -675,7 +676,7 @@ func UnsealDiskKey(pcrSel tpm2.PCRSelection) ([]byte, error) {
675676

676677
sealedObjHandle, _, err := tpm2.Load(rw, TpmSRKHdl, "", pub, priv)
677678
if err != nil {
678-
return nil, fmt.Errorf("loading the disk key into TPM failed: %v", err)
679+
return nil, fmt.Errorf("loading the disk key into TPM failed: %w", err)
679680
}
680681
defer tpm2.FlushContext(rw, sealedObjHandle)
681682

@@ -689,12 +690,12 @@ func UnsealDiskKey(pcrSel tpm2.PCRSelection) ([]byte, error) {
689690
if err != nil {
690691
// We get here mostly because of RCPolicyFail error, so try to get more
691692
// information about the failure by finding the mismatching PCR index.
692-
mismatch, newErr := findMismatchingPCRs(TpmSavedDiskSealingPcrs)
693-
if newErr != nil {
694-
return nil, fmt.Errorf("UnsealWithSession failed: %v, getting more info failed: %v", err, newErr)
693+
mismatch, extraErr := findMismatchingPCRs(TpmSavedDiskSealingPcrs)
694+
if extraErr != nil {
695+
return nil, fmt.Errorf("UnsealWithSession failed: %w, getting more info failed: %v", err, extraErr)
695696
}
696697

697-
return nil, fmt.Errorf("UnsealWithSession failed: %v, possibly mismatching PCR indexes %v", err, mismatch)
698+
return nil, fmt.Errorf("UnsealWithSession failed: %w, possibly mismatching PCR indexes %v", err, mismatch)
698699
}
699700
return key, nil
700701
}
@@ -725,7 +726,7 @@ func PolicyPCRSession(rw io.ReadWriteCloser, pcrSel tpm2.PCRSelection) (tpmutil.
725726

726727
policy, err := tpm2.PolicyGetDigest(rw, session)
727728
if err != nil {
728-
return session, nil, fmt.Errorf("PolicyGetDigest failed: %v", err)
729+
return session, nil, fmt.Errorf("PolicyGetDigest failed: %w", err)
729730
}
730731
return session, policy, nil
731732
}
@@ -816,19 +817,14 @@ func saveDiskKeySealingPCRs(pcrsFile string) error {
816817
return err
817818
}
818819

819-
frw, err := os.Create(pcrsFile)
820-
if err != nil {
821-
return err
822-
}
823-
defer frw.Close()
824-
825-
e := gob.NewEncoder(frw)
820+
buff := new(bytes.Buffer)
821+
e := gob.NewEncoder(buff)
826822
err = e.Encode(readPCRs)
827823
if err != nil {
828824
return err
829825
}
830826

831-
return nil
827+
return fileutils.WriteRename(pcrsFile, buff.Bytes())
832828
}
833829

834830
func findMismatchingPCRs(savedPCRsFile string) ([]int, error) {

0 commit comments

Comments
 (0)