VirtualBox

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

Last change on this file since 100841 was 98262, checked in by vboxsync, 23 months ago

Main: rc() -> hrc()/vrc(). bugref:10223

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette