Skip to content

Commit 70f437f

Browse files
author
zhong.zhou
committed
<fix>[crypto]: keep TPM key ref until VM removed from DB
Delay/trash deletion no longer drops EncryptedResourceKeyRef; cleanup runs in vmJustBeforeDeleteFromDb (expunge/direct delete). Centralize ref delete in VmTpmManager; wire RemoveTpm/add-tpm rollback and drop unused destroy extension from VmTpmExtensions. Resolves: ZSV-11721 Change-Id: I68676e706f6a786773627074636f6e6a617a6e4f
1 parent b5be037 commit 70f437f

7 files changed

Lines changed: 78 additions & 15 deletions

File tree

compute/src/main/java/org/zstack/compute/vm/devices/DummyEncryptedResourceKeyManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@ public void getOrCreateKey(GetOrCreateResourceKeyContext ctx,
2323
public void rollbackCreatedKey(ResourceKeyResult result, Completion completion) {
2424
completion.success();
2525
}
26+
27+
@Override
28+
public void deleteRef(String resourceType, String resourceUuid) {
29+
// do-nothing
30+
}
2631
}

compute/src/main/java/org/zstack/compute/vm/devices/VmTpmExtensions.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import org.zstack.header.tpm.entity.TpmVO;
1010
import org.zstack.header.tpm.entity.TpmVO_;
1111
import org.zstack.header.vm.CreateVmInstanceMsg;
12+
import org.zstack.header.vm.VmInstanceInventory;
1213
import org.zstack.header.vm.VmInstanceCreateExtensionPoint;
14+
import org.zstack.header.vm.VmJustBeforeDeleteFromDbExtensionPoint;
1315
import org.zstack.header.vm.VmInstanceSpec;
1416
import org.zstack.header.vm.VmInstanceVO;
1517
import org.zstack.header.vm.VmMachineType;
@@ -23,7 +25,7 @@
2325
import static org.zstack.compute.vm.VmGlobalConfig.ENABLE_UEFI_SECURE_BOOT;
2426

2527
public class VmTpmExtensions implements VmInstanceCreateExtensionPoint,
26-
BuildVmSpecExtensionPoint {
28+
BuildVmSpecExtensionPoint, VmJustBeforeDeleteFromDbExtensionPoint {
2729
private static final CLogger logger = Utils.getLogger(VmTpmExtensions.class);
2830

2931
@Autowired
@@ -70,11 +72,7 @@ public void afterRollbackPersistVmInstanceVO(VmInstanceVO vo, CreateVmInstanceMs
7072
new SQLBatch() {
7173
@Override
7274
protected void scripts() {
73-
try {
74-
resourceKeyBackend.detachKeyProviderFromTpm(tpmUuid);
75-
} finally {
76-
vmTpmManager.deleteTpmVO(tpmUuid);
77-
}
75+
vmTpmManager.deleteTpmAndResourceKeyRef(tpmUuid);
7876
}
7977
}.execute();
8078
}
@@ -129,4 +127,15 @@ public void afterBuildVmSpec(VmInstanceSpec spec) {
129127
"auto-set machineType to q35 for VM[uuid:%s] because NvRam/TPM registration is needed", vmUuid));
130128
}
131129
}
130+
131+
/**
132+
* Remove the TPM resource-key ref when the VM row is about to be removed from the database
133+
* (e.g. direct delete, expunge). A VM has at most one vTPM; ref follows that device. Delay
134+
* (recycle bin) does not call this hook, so refs remain for recovery and rekey. RemoveTpm
135+
* already drops ref via {@link VmTpmManager#deleteResourceKeyRefForTpm} before TpmVO is removed.
136+
*/
137+
@Override
138+
public void vmJustBeforeDeleteFromDb(VmInstanceInventory inv) {
139+
vmTpmManager.deleteResourceKeyRefForVmTpmIfPresent(inv.getUuid());
140+
}
132141
}

compute/src/main/java/org/zstack/compute/vm/devices/VmTpmManager.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.zstack.core.db.DatabaseFacade;
66
import org.zstack.core.db.Q;
77
import org.zstack.header.image.ImageBootMode;
8+
import org.zstack.header.keyprovider.EncryptedResourceKeyManager;
89
import org.zstack.header.tpm.entity.TpmVO;
910
import org.zstack.header.tpm.entity.TpmVO_;
1011
import org.zstack.resourceconfig.ResourceConfig;
@@ -23,6 +24,8 @@ public class VmTpmManager {
2324
private DatabaseFacade databaseFacade;
2425
@Autowired
2526
private ResourceConfigFacade resourceConfigFacade;
27+
@Autowired
28+
private EncryptedResourceKeyManager resourceKeyManager;
2629

2730
public TpmVO persistTpmVO(String tpmUuid, String vmUuid) {
2831
if (tpmUuid == null) {
@@ -42,6 +45,36 @@ public void deleteTpmVO(String tpmUuid) {
4245
databaseFacade.removeByPrimaryKey(tpmUuid, TpmVO.class);
4346
}
4447

48+
/**
49+
* Drop encrypted-resource key ref for this TPM device (logical key binding). Call when the vTPM is
50+
* removed or before the {@link TpmVO} row disappears (e.g. VM expunged).
51+
*/
52+
public void deleteResourceKeyRefForTpm(String tpmUuid) {
53+
resourceKeyManager.deleteRef(TpmVO.class.getSimpleName(), tpmUuid);
54+
}
55+
56+
/**
57+
* Same as {@link #deleteResourceKeyRefForTpm} for the vTPM attached to this VM, if any.
58+
* A VM has at most one {@link TpmVO}.
59+
*/
60+
public void deleteResourceKeyRefForVmTpmIfPresent(String vmInstanceUuid) {
61+
String tpmUuid = Q.New(TpmVO.class)
62+
.eq(TpmVO_.vmInstanceUuid, vmInstanceUuid)
63+
.select(TpmVO_.uuid)
64+
.findValue();
65+
if (tpmUuid != null) {
66+
deleteResourceKeyRefForTpm(tpmUuid);
67+
}
68+
}
69+
70+
/**
71+
* Remove TPM resource-key ref then delete {@link TpmVO} (e.g. create-rollback or add-tpm rollback).
72+
*/
73+
public void deleteTpmAndResourceKeyRef(String tpmUuid) {
74+
deleteResourceKeyRefForTpm(tpmUuid);
75+
deleteTpmVO(tpmUuid);
76+
}
77+
4578
/**
4679
* @param bootMode boot mode, null is Legacy
4780
*/

conf/springConfigXml/VmInstanceManager.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@
286286
<zstack:plugin>
287287
<zstack:extension interface="org.zstack.header.vm.VmInstanceCreateExtensionPoint" />
288288
<zstack:extension interface="org.zstack.compute.vm.BuildVmSpecExtensionPoint" />
289+
<zstack:extension interface="org.zstack.header.vm.VmJustBeforeDeleteFromDbExtensionPoint" />
289290
</zstack:plugin>
290291
</bean>
291292

header/src/main/java/org/zstack/header/keyprovider/EncryptedResourceKeyManager.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,17 @@ void getOrCreateKey(GetOrCreateResourceKeyContext ctx,
3434
*/
3535
void rollbackCreatedKey(ResourceKeyResult result, Completion completion);
3636

37+
/**
38+
* Delete the resource-to-key-provider relationship for the specified resource.
39+
* This only removes the persisted ref record and does not delete the remote secret.
40+
*/
41+
void deleteRef(String resourceType, String resourceUuid);
42+
3743
class GetOrCreateResourceKeyContext {
3844
private String resourceUuid;
3945
private String resourceType;
4046
private String keyProviderUuid;
47+
private String keyProviderName;
4148
private String purpose;
4249

4350
public String getResourceUuid() {
@@ -64,6 +71,14 @@ public void setKeyProviderUuid(String keyProviderUuid) {
6471
this.keyProviderUuid = keyProviderUuid;
6572
}
6673

74+
public String getKeyProviderName() {
75+
return keyProviderName;
76+
}
77+
78+
public void setKeyProviderName(String keyProviderName) {
79+
this.keyProviderName = keyProviderName;
80+
}
81+
6782
public String getPurpose() {
6883
return purpose;
6984
}

plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmExtensions.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public void fail(ErrorCode errorCode) {
173173
@Override
174174
public boolean skip(Map data) {
175175
boolean shouldSkip = VmGlobalConfig.ALLOWED_TPM_VM_WITHOUT_KMS.value(Boolean.class) &&
176-
(StringUtils.isBlank(context.providerUuid) || StringUtils.isBlank(context.providerName));
176+
(StringUtils.isBlank(context.providerUuid) && StringUtils.isBlank(context.providerName));
177177
if (shouldSkip) {
178178
logger.info("skip create-dek: allowed.tpm.vm.without.kms is enabled and no KMS provider bound");
179179
}
@@ -182,7 +182,7 @@ public boolean skip(Map data) {
182182

183183
@Override
184184
public void run(FlowTrigger trigger, Map data) {
185-
if (StringUtils.isBlank(context.providerUuid) || StringUtils.isBlank(context.providerName)) {
185+
if (StringUtils.isBlank(context.providerUuid) && StringUtils.isBlank(context.providerName)) {
186186
trigger.fail(operr("missing TPM resource key binding for tpm[uuid:%s], attachKeyProviderToTpm must run before create-dek", context.tpmUuid));
187187
return;
188188
}
@@ -191,13 +191,15 @@ public void run(FlowTrigger trigger, Map data) {
191191
keyCtx.setResourceUuid(context.tpmUuid);
192192
keyCtx.setResourceType(TpmVO.class.getSimpleName());
193193
keyCtx.setKeyProviderUuid(context.providerUuid);
194+
keyCtx.setKeyProviderName(context.providerName);
194195
keyCtx.setPurpose("vtpm");
195196

196197
resourceKeyManager.getOrCreateKey(keyCtx, new ReturnValueCompletion<ResourceKeyResult>(trigger) {
197198
@Override
198199
public void success(ResourceKeyResult result) {
199200
tpmSpec.setResourceKeyCreatedNew(result.isCreatedNewKey());
200201
tpmSpec.setResourceKeyProviderUuid(result.getKeyProviderUuid());
202+
context.providerUuid = result.getKeyProviderUuid();
201203
context.providerName = result.getKeyProviderName();
202204
context.dekBase64 = result.getDekBase64();
203205
trigger.next();

plugin/kvm/src/main/java/org/zstack/kvm/tpm/KvmTpmManager.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,10 @@ private void addTpmToVm(AddTpmToVmContext context, Completion completion) {
244244
}
245245
})
246246
.rollback(trigger -> {
247-
try {
248-
if (context.keyProviderAttached && context.createdTpmUuid != null) {
249-
tpmKeyBackend.detachKeyProviderFromTpm(context.createdTpmUuid);
250-
}
251-
} finally {
252-
if (context.tpmCreated && context.createdTpmUuid != null) {
247+
if (context.tpmCreated && context.createdTpmUuid != null) {
248+
if (context.keyProviderAttached) {
249+
vmTpmManager.deleteTpmAndResourceKeyRef(context.createdTpmUuid);
250+
} else {
253251
vmTpmManager.deleteTpmVO(context.createdTpmUuid);
254252
}
255253
}
@@ -386,7 +384,7 @@ public void done(ErrorCodeList errorCodeList) {
386384
.build())
387385
.then(Flow.of("detach-resource-key")
388386
.handle(trigger -> {
389-
tpmKeyBackend.detachKeyProviderFromTpm(context.tpmUuid);
387+
vmTpmManager.deleteResourceKeyRefForTpm(context.tpmUuid);
390388
trigger.next();
391389
})
392390
.build())

0 commit comments

Comments
 (0)