VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/TrustedPlatformModuleImpl.cpp@ 92154

Last change on this file since 92154 was 91614, checked in by vboxsync, 3 years ago

Main: Initialize the TPM type properly based on the guest OS type and also initialize the UEFI variable store based on the guest OS type secure boot setting, bugref:9580 and bugref:10075

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: TrustedPlatformModuleImpl.cpp 91614 2021-10-07 10:12:16Z vboxsync $ */
2/** @file
3 * VirtualBox COM class implementation - Machine Trusted Platform Module settings.
4 */
5
6/*
7 * Copyright (C) 2021 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP LOG_GROUP_MAIN_TRUSTEDPLATFORMMODULE
19#include "TrustedPlatformModuleImpl.h"
20#include "MachineImpl.h"
21#include "GuestOSTypeImpl.h"
22
23#include <iprt/cpp/utils.h>
24#include <VBox/settings.h>
25
26#include "AutoStateDep.h"
27#include "AutoCaller.h"
28#include "LoggingNew.h"
29
30
31////////////////////////////////////////////////////////////////////////////////
32//
33// TrustedPlatformModule private data definition
34//
35////////////////////////////////////////////////////////////////////////////////
36
37struct TrustedPlatformModule::Data
38{
39 Data()
40 : pMachine(NULL)
41 { }
42
43 Machine * const pMachine;
44 ComObjPtr<TrustedPlatformModule> pPeer;
45
46 // use the XML settings structure in the members for simplicity
47 Backupable<settings::TpmSettings> bd;
48};
49
50// constructor / destructor
51/////////////////////////////////////////////////////////////////////////////
52
53DEFINE_EMPTY_CTOR_DTOR(TrustedPlatformModule)
54
55HRESULT TrustedPlatformModule::FinalConstruct()
56{
57 return BaseFinalConstruct();
58}
59
60void TrustedPlatformModule::FinalRelease()
61{
62 uninit();
63 BaseFinalRelease();
64}
65
66// public initializer/uninitializer for internal purposes only
67/////////////////////////////////////////////////////////////////////////////
68
69/**
70 * Initializes the BIOS settings object.
71 *
72 * @returns COM result indicator
73 */
74HRESULT TrustedPlatformModule::init(Machine *aParent)
75{
76 LogFlowThisFuncEnter();
77 LogFlowThisFunc(("aParent: %p\n", aParent));
78
79 ComAssertRet(aParent, E_INVALIDARG);
80
81 /* Enclose the state transition NotReady->InInit->Ready */
82 AutoInitSpan autoInitSpan(this);
83 AssertReturn(autoInitSpan.isOk(), E_FAIL);
84
85 m = new Data();
86
87 /* share the parent weakly */
88 unconst(m->pMachine) = aParent;
89
90 m->bd.allocate();
91
92 autoInitSpan.setSucceeded();
93
94 LogFlowThisFuncLeave();
95 return S_OK;
96}
97
98/**
99 * Initializes the Trusted Platform Module settings object given another Trusted Platform Module settings object
100 * (a kind of copy constructor). This object shares data with
101 * the object passed as an argument.
102 *
103 * @note This object must be destroyed before the original object
104 * it shares data with is destroyed.
105 */
106HRESULT TrustedPlatformModule::init(Machine *aParent, TrustedPlatformModule *that)
107{
108 LogFlowThisFuncEnter();
109 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
110
111 ComAssertRet(aParent && that, E_INVALIDARG);
112
113 /* Enclose the state transition NotReady->InInit->Ready */
114 AutoInitSpan autoInitSpan(this);
115 AssertReturn(autoInitSpan.isOk(), E_FAIL);
116
117 m = new Data();
118
119 unconst(m->pMachine) = aParent;
120 m->pPeer = that;
121
122 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
123 m->bd.share(that->m->bd);
124
125 autoInitSpan.setSucceeded();
126
127 LogFlowThisFuncLeave();
128 return S_OK;
129}
130
131/**
132 * Initializes the guest object given another guest object
133 * (a kind of copy constructor). This object makes a private copy of data
134 * of the original object passed as an argument.
135 */
136HRESULT TrustedPlatformModule::initCopy(Machine *aParent, TrustedPlatformModule *that)
137{
138 LogFlowThisFuncEnter();
139 LogFlowThisFunc(("aParent: %p, that: %p\n", aParent, that));
140
141 ComAssertRet(aParent && that, E_INVALIDARG);
142
143 /* Enclose the state transition NotReady->InInit->Ready */
144 AutoInitSpan autoInitSpan(this);
145 AssertReturn(autoInitSpan.isOk(), E_FAIL);
146
147 m = new Data();
148
149 unconst(m->pMachine) = aParent;
150 // mPeer is left null
151
152 AutoWriteLock thatlock(that COMMA_LOCKVAL_SRC_POS);
153 m->bd.attachCopy(that->m->bd);
154
155 autoInitSpan.setSucceeded();
156
157 LogFlowThisFuncLeave();
158 return S_OK;
159}
160
161/**
162 * Uninitializes the instance and sets the ready flag to FALSE.
163 * Called either from FinalRelease() or by the parent when it gets destroyed.
164 */
165void TrustedPlatformModule::uninit()
166{
167 LogFlowThisFuncEnter();
168
169 /* Enclose the state transition Ready->InUninit->NotReady */
170 AutoUninitSpan autoUninitSpan(this);
171 if (autoUninitSpan.uninitDone())
172 return;
173
174 m->bd.free();
175
176 unconst(m->pPeer) = NULL;
177 unconst(m->pMachine) = NULL;
178
179 delete m;
180 m = NULL;
181
182 LogFlowThisFuncLeave();
183}
184
185// ITrustedPlatformModule properties
186/////////////////////////////////////////////////////////////////////////////
187
188
189HRESULT TrustedPlatformModule::getType(TpmType_T *aType)
190{
191 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
192
193 *aType = m->bd->tpmType;
194
195 return S_OK;
196}
197
198HRESULT TrustedPlatformModule::setType(TpmType_T aType)
199{
200 /* the machine needs to be mutable */
201 AutoMutableStateDependency adep(m->pMachine);
202 if (FAILED(adep.rc())) return adep.rc();
203
204 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
205
206 m->bd.backup();
207 m->bd->tpmType = aType;
208
209 alock.release();
210 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
211 m->pMachine->i_setModified(Machine::IsModified_TrustedPlatformModule);
212
213 return S_OK;
214}
215
216HRESULT TrustedPlatformModule::getLocation(com::Utf8Str &location)
217{
218 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
219
220 location = m->bd->strLocation;
221 return S_OK;
222}
223
224HRESULT TrustedPlatformModule::setLocation(const com::Utf8Str &location)
225{
226 /* the machine needs to be mutable */
227 AutoMutableStateDependency adep(m->pMachine);
228 if (FAILED(adep.rc())) return adep.rc();
229
230 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
231
232 m->bd.backup();
233 m->bd->strLocation = location;
234
235 alock.release();
236 AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
237 m->pMachine->i_setModified(Machine::IsModified_TrustedPlatformModule);
238
239 return S_OK;
240}
241
242
243// ITrustedPlatformModule methods
244/////////////////////////////////////////////////////////////////////////////
245
246// public methods only for internal purposes
247/////////////////////////////////////////////////////////////////////////////
248
249/**
250 * Loads settings from the given machine node.
251 * May be called once right after this object creation.
252 *
253 * @param data Configuration settings.
254 *
255 * @note Locks this object for writing.
256 */
257HRESULT TrustedPlatformModule::i_loadSettings(const settings::TpmSettings &data)
258{
259 AutoCaller autoCaller(this);
260 AssertComRCReturnRC(autoCaller.rc());
261
262 AutoReadLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
263 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
264
265 // simply copy
266 m->bd.assignCopy(&data);
267 return S_OK;
268}
269
270/**
271 * Saves settings to the given machine node.
272 *
273 * @param data Configuration settings.
274 *
275 * @note Locks this object for reading.
276 */
277HRESULT TrustedPlatformModule::i_saveSettings(settings::TpmSettings &data)
278{
279 AutoCaller autoCaller(this);
280 AssertComRCReturnRC(autoCaller.rc());
281
282 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
283
284 data = *m->bd.data();
285
286 return S_OK;
287}
288
289void TrustedPlatformModule::i_rollback()
290{
291 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
292 m->bd.rollback();
293}
294
295void TrustedPlatformModule::i_commit()
296{
297 /* sanity */
298 AutoCaller autoCaller(this);
299 AssertComRCReturnVoid(autoCaller.rc());
300
301 /* sanity too */
302 AutoCaller peerCaller(m->pPeer);
303 AssertComRCReturnVoid(peerCaller.rc());
304
305 /* lock both for writing since we modify both (mPeer is "master" so locked
306 * first) */
307 AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS);
308
309 if (m->bd.isBackedUp())
310 {
311 m->bd.commit();
312 if (m->pPeer)
313 {
314 /* attach new data to the peer and reshare it */
315 AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS);
316 m->pPeer->m->bd.attach(m->bd);
317 }
318 }
319}
320
321void TrustedPlatformModule::i_copyFrom(TrustedPlatformModule *aThat)
322{
323 AssertReturnVoid(aThat != NULL);
324
325 /* sanity */
326 AutoCaller autoCaller(this);
327 AssertComRCReturnVoid(autoCaller.rc());
328
329 /* sanity too */
330 AutoCaller thatCaller(aThat);
331 AssertComRCReturnVoid(thatCaller.rc());
332
333 /* peer is not modified, lock it for reading (aThat is "master" so locked
334 * first) */
335 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
336 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
337
338 /* this will back up current data */
339 m->bd.assignCopy(aThat->m->bd);
340}
341
342void TrustedPlatformModule::i_applyDefaults(GuestOSType *aOsType)
343{
344 /* sanity */
345 AutoCaller autoCaller(this);
346 AssertComRCReturnVoid(autoCaller.rc());
347
348 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
349
350 /* Initialize default TPM settings here */
351 if (aOsType)
352 m->bd->tpmType = aOsType->i_recommendedTpm2() ? TpmType_v2_0 : TpmType_None;
353 else
354 m->bd->tpmType = TpmType_None;
355}
356
357/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use