]> git.proxmox.com Git - swtpm.git/blame - src/swtpm/swtpm.c
swtpm: Make --daemon not racy
[swtpm.git] / src / swtpm / swtpm.c
CommitLineData
f163b202
SB
1/********************************************************************************/
2/* */
3/* TPM Main Program */
4/* Written by Ken Goldman, Stefan Berger */
5/* IBM Thomas J. Watson Research Center */
6/* */
869df69f 7/* (c) Copyright IBM Corporation 2006, 2010, 2016, 2019. */
f163b202
SB
8/* */
9/* All rights reserved. */
10/* */
11/* Redistribution and use in source and binary forms, with or without */
12/* modification, are permitted provided that the following conditions are */
13/* met: */
14/* */
15/* Redistributions of source code must retain the above copyright notice, */
16/* this list of conditions and the following disclaimer. */
17/* */
18/* Redistributions in binary form must reproduce the above copyright */
19/* notice, this list of conditions and the following disclaimer in the */
20/* documentation and/or other materials provided with the distribution. */
21/* */
22/* Neither the names of the IBM Corporation nor the names of its */
23/* contributors may be used to endorse or promote products derived from */
24/* this software without specific prior written permission. */
25/* */
26/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
27/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
28/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
29/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
30/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
31/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
32/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
33/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
34/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
35/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
36/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37/********************************************************************************/
38
39#include <config.h>
40
41#include <stdlib.h>
42#include <stdio.h>
43#include <string.h>
44#include <time.h>
f163b202
SB
45#include <getopt.h>
46#include <errno.h>
47#include <poll.h>
48#include <sys/stat.h>
804e7472 49#include <stdbool.h>
87d56f93
AV
50#include <sys/types.h>
51#include <sys/socket.h>
f163b202
SB
52
53#include <libtpms/tpm_error.h>
54#include <libtpms/tpm_library.h>
55#include <libtpms/tpm_memory.h>
56
57#include "main.h"
58#include "swtpm_debug.h"
59#include "swtpm_io.h"
2d3deaef 60#include "swtpm_nvstore.h"
4716d35a 61#include "server.h"
f163b202
SB
62#include "common.h"
63#include "logging.h"
b2151737 64#include "pidfile.h"
1bebb6be
SB
65#include "tpmlib.h"
66#include "utils.h"
b959335e 67#include "mainloop.h"
298d1782 68#include "ctrlchannel.h"
fc36ef35 69#include "tpmstate.h"
af23737e 70#include "sys_dependencies.h"
98d1d126 71#include "daemonize.h"
07dfd958 72#include "seccomp_profile.h"
11114ba7
SB
73#include "options.h"
74#include "capabilities.h"
f163b202
SB
75
76/* local variables */
27a3c239 77static int notify_fd[2] = {-1, -1};
f163b202 78
27a3c239 79static struct libtpms_callbacks callbacks = {
f163b202
SB
80 .sizeOfStruct = sizeof(struct libtpms_callbacks),
81 .tpm_nvram_init = SWTPM_NVRAM_Init,
82 .tpm_nvram_loaddata = SWTPM_NVRAM_LoadData,
83 .tpm_nvram_storedata = SWTPM_NVRAM_StoreData,
84 .tpm_nvram_deletename = SWTPM_NVRAM_DeleteName,
85 .tpm_io_init = SWTPM_IO_Init,
f56a0cd2 86 .tpm_io_getlocality = mainloop_cb_get_locality,
f163b202
SB
87};
88
1bebb6be
SB
89static void sigterm_handler(int sig __attribute__((unused)))
90{
91 TPM_DEBUG("Terminating...\n");
92 if (write(notify_fd[1], "T", 1) < 0) {
93 logprintf(STDERR_FILENO, "Error: sigterm notification failed: %s\n",
94 strerror(errno));
95 }
b959335e 96 mainloop_terminate = true;
f163b202
SB
97}
98
f163b202
SB
99static void usage(FILE *file, const char *prgname, const char *iface)
100{
101 fprintf(file,
102 "Usage: %s %s [options]\n"
103 "\n"
104 "The following options are supported:\n"
105 "\n"
106 "-p|--port <port> : use the given port\n"
f163b202
SB
107 "-f|--fd <fd> : use the given socket file descriptor\n"
108 "-t|--terminate : terminate the TPM once a connection has been lost\n"
109 "-d|--daemon : daemonize the TPM\n"
f34e01a5 110 "--ctrl type=[unixio|tcp][,path=<path>][,port=<port>[,bindaddr=address[,ifname=ifname]]][,fd=<filedescriptor>|clientfd=<filedescriptor>][,mode=0...][,uid=uid][,gid=gid]\n"
9ddc6998
SB
111 " : TPM control channel using either UnixIO or TCP sockets;\n"
112 " the path is only valid for Unixio channels; the port must\n"
113 " be given in case the type is TCP; the TCP socket is bound\n"
16eb0ff2 114 " to 127.0.0.1 by default and other bind addresses can be\n"
93edca48
AV
115 " given with the bindaddr parameter; if fd is provided,\n"
116 " it will be treated as a server socket and used for \n"
117 " accepting client connections; if clientfd is provided,\n"
118 " it will be treaded as client connection;\n"
119 " NOTE: fd and clientfd are mutually exclusive and clientfd\n"
120 " is only valid for UnixIO channels\n"
2bc601bb 121 " mode allows a user to set the file mode bits of a Unixio socket;\n"
682fe581 122 " the value must be given in octal number format\n"
f34e01a5 123 " uid and gid set the ownership of the Unixio socket's file;\n"
1ed09c03 124 "--migration-key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n"
84259c17
SB
125 " : use an AES key for the encryption of the TPM's state\n"
126 " when it is retrieved from the TPM via ioctls;\n"
127 " Setting this key ensures that the TPM's state will always\n"
128 " be encrypted when migrated\n"
26933af5 129 "--migration-key pwdfile=<path>|pwdfd=<fd>[,mode=aes-cbc|aes-256-cbc][,remove=[true|false]][,kdf=sha512|pbkdf2]\n"
84259c17 130 " : provide a passphrase in a file; the AES key will be\n"
bf5220cf 131 " derived from this passphrase; default kdf is PBKDF2\n"
3760c342 132 "--log file=<path>|fd=<filedescriptor>[,level=n][,prefix=<prefix>][,truncate]\n"
bc525ccd
SB
133 " : write the TPM's log into the given file rather than\n"
134 " to the console; provide '-' for path to avoid logging\n"
93f4a389 135 " log level 5 and higher will enable libtpms logging;\n"
3760c342
SB
136 " all logged output will be prefixed with prefix;\n"
137 " the log file can be reset (truncate)\n"
1ed09c03 138 "--key file=<path>|fd=<fd>[,mode=aes-cbc|aes-256-cbc][,format=hex|binary][,remove=[true|false]]\n"
f163b202
SB
139 " : use an AES key for the encryption of the TPM's state\n"
140 " files; use the given mode for the block encryption;\n"
141 " the key is to be provided as a hex string or in binary\n"
142 " format; the keyfile can be automatically removed using\n"
143 " the remove parameter\n"
1253088f 144 "--key pwdfile=<path>|pwdfd=<fd>[,mode=aes-cbc|aes-256-cbc][,remove=[true|false]][,kdf=sha512|pbkdf2]\n"
bc525ccd 145 " : provide a passphrase in a file; the AES key will be\n"
bf5220cf 146 " derived from this passphrase; default kdf is PBKDF2\n"
3b563487 147 "--locality [reject-locality-4][,allow-set-locality]\n"
4a565414 148 " : reject-locality-4: reject any command in locality 4\n"
3b563487 149 " allow-set-locality: accept SetLocality command\n"
db608775 150 "--pid file=<path>|fd=<filedescriptor>\n"
bc525ccd 151 " : write the process ID into the given file\n"
b82eb7e7
ET
152 "--tpmstate dir=<dir>[,mode=0...]|backend-uri=<uri>\n"
153 " : set the directory or uri where the TPM's state will be written\n"
bc525ccd 154 " into; the TPM_PATH environment variable can be used\n"
b82eb7e7 155 " instead dir option;\n"
2bc601bb 156 " mode allows a user to set the file mode bits of the state files;\n"
640f1fab 157 " the default mode is 0640;\n"
8047b5d6 158 "--server [type=tcp][,port=port[,bindaddr=address[,ifname=ifname]]][,fd=fd][,disconnect]\n"
7c0a033f
SB
159 " : Expect TCP connections on the given port;\n"
160 " if fd is provided, packets will be read from it directly;\n"
161 " the disconnect parameter closes the connection after\n"
16eb0ff2
SB
162 " sending a response back to the client; the TCP socket is\n"
163 " bound to 127.0.0.1 by default and other bind addresses\n"
164 " can be given with the bindaddr parameter\n"
f34e01a5 165 "--server type=unixio[,path=path][,fd=fd][,mode=0...][,uid=uid][,gid=gid]\n"
73823529 166 " : Expect UnixIO connections on the given path; if fd is\n"
e6bc4bdf 167 " provided, packets will be read from it directly;\n"
2bc601bb 168 " mode allows a user to set the file mode bits of the socket; the\n"
682fe581 169 " value must be given in octal number format;\n"
f34e01a5 170 " uid and gid set the ownership of the Unixio socket's file;\n"
e6bc4bdf 171 "--flags [not-need-init][,startup-clear|startup-state|startup-deactivated|startup-none]\n"
63ab6c3c
SB
172 " : not-need-init: commands can be sent without needing to\n"
173 " send an INIT via control channel;\n"
e6bc4bdf 174 " startup-...: send Startup command with this type;\n"
bb420d74 175 "-r|--runas <user>: change to the given user\n"
fbc596ab 176 "--tpm2 : choose TPM2 functionality\n"
07dfd958
SB
177#ifdef WITH_SECCOMP
178# ifndef SCMP_ACT_LOG
179 "--seccomp action=none|kill\n"
180# else
181 "--seccomp action=none|kill|log\n"
182# endif
183 " : Choose the action of the seccomp profile when a\n"
184 " blacklisted syscall is executed; default is kill\n"
185#endif
11114ba7
SB
186 "--print-capabilites\n"
187 " : print capabilities and terminate\n"
5bc59a74
ET
188 "--print-states\n"
189 " : print existing TPM states and terminate\n"
f163b202
SB
190 "-h|--help : display this help screen and terminate\n"
191 "\n",
192 prgname, iface);
193}
194
321a22cc
SB
195static void swtpm_cleanup(struct ctrlchannel *cc, struct server *server)
196{
197 pidfile_remove();
198 ctrlchannel_free(cc);
199 server_free(server);
200 log_global_free();
fc36ef35 201 tpmstate_global_free();
8f57999d 202 SWTPM_NVRAM_Shutdown();
321a22cc
SB
203}
204
f163b202
SB
205int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
206{
207 TPM_RESULT rc = 0;
208 int daemonize = FALSE;
11114ba7 209 int opt, longindex, ret;
f163b202
SB
210 struct stat statbuf;
211 struct mainLoopParams mlp = {
510f1848 212 .cc = NULL,
f163b202 213 .flags = 0,
7c0a033f 214 .fd = -1,
4a565414 215 .locality_flags = 0,
32694853 216 .tpmversion = TPMLIB_TPM_VERSION_1_2,
e6bc4bdf 217 .startupType = _TPM_ST_NONE,
f163b202 218 };
4716d35a 219 struct server *server = NULL;
f163b202
SB
220 unsigned long val;
221 char *end_ptr;
222 char buf[20];
223 char *keydata = NULL;
84259c17 224 char *migkeydata = NULL;
f163b202 225 char *logdata = NULL;
b2151737 226 char *piddata = NULL;
4a565414 227 char *localitydata = NULL;
bc525ccd 228 char *tpmstatedata = NULL;
9ddc6998 229 char *ctrlchdata = NULL;
4716d35a 230 char *serverdata = NULL;
63ab6c3c 231 char *flagsdata = NULL;
07dfd958 232 char *seccompdata = NULL;
bb420d74 233 char *runas = NULL;
63ab6c3c 234 bool need_init_cmd = true;
f163b202
SB
235#ifdef DEBUG
236 time_t start_time;
237#endif
07dfd958 238 unsigned int seccomp_action;
3a3a9f5b 239 bool printcapabilities = false;
5bc59a74 240 bool printstates = false;
f163b202
SB
241 static struct option longopts[] = {
242 {"daemon" , no_argument, 0, 'd'},
243 {"help" , no_argument, 0, 'h'},
244 {"port" , required_argument, 0, 'p'},
f163b202 245 {"fd" , required_argument, 0, 'f'},
93edca48 246 {"server" , required_argument, 0, 'c'},
bb420d74 247 {"runas" , required_argument, 0, 'r'},
f163b202 248 {"terminate" , no_argument, 0, 't'},
4a565414 249 {"locality" , required_argument, 0, 'L'},
f163b202
SB
250 {"log" , required_argument, 0, 'l'},
251 {"key" , required_argument, 0, 'k'},
84259c17 252 {"migration-key", required_argument, 0, 'K'},
b2151737 253 {"pid" , required_argument, 0, 'P'},
bc525ccd 254 {"tpmstate" , required_argument, 0, 's'},
9ddc6998 255 {"ctrl" , required_argument, 0, 'C'},
63ab6c3c 256 {"flags" , required_argument, 0, 'F'},
fbc596ab 257 {"tpm2" , no_argument, 0, '2'},
07dfd958
SB
258#ifdef WITH_SECCOMP
259 {"seccomp" , required_argument, 0, 'S'},
260#endif
11114ba7
SB
261 {"print-capabilities"
262 , no_argument, 0, 'a'},
5bc59a74 263 {"print-states", no_argument, 0, 'e'},
f163b202
SB
264 {NULL , 0 , 0, 0 },
265 };
266
cba81569
SB
267 log_set_prefix("swtpm: ");
268
f163b202 269 while (TRUE) {
bb420d74 270 opt = getopt_long(argc, argv, "dhp:f:tr:", longopts, &longindex);
f163b202
SB
271
272 if (opt == -1)
273 break;
274
275 switch (opt) {
276 case 'd':
277 daemonize = TRUE;
98d1d126
NW
278 if (daemonize_prep() == -1) {
279 logprintf(STDERR_FILENO,
280 "Could not prepare to daemonize: %s\n", strerror(errno));
281 exit(EXIT_FAILURE);
282 }
f163b202
SB
283 break;
284
285 case 'p':
6fc8fb9f 286 errno = 0;
f163b202
SB
287 val = strtoul(optarg, &end_ptr, 0);
288 if (val != (unsigned int)val || errno || end_ptr[0] != '\0') {
cba81569
SB
289 logprintf(STDERR_FILENO,
290 "Cannot parse socket port number '%s'.\n",
291 optarg);
4fd2d23b 292 exit(EXIT_FAILURE);
f163b202
SB
293 }
294 if (val >= 0x10000) {
cba81569 295 logprintf(STDERR_FILENO, "Port is outside valid range.\n");
4fd2d23b 296 exit(EXIT_FAILURE);
f163b202
SB
297 }
298 snprintf(buf, sizeof(buf), "%lu", val);
299 if (setenv("TPM_PORT", buf, 1) != 0) {
cba81569
SB
300 logprintf(STDERR_FILENO,
301 "Could not set port: %s\n", strerror(errno));
4fd2d23b 302 exit(EXIT_FAILURE);
f163b202 303 }
c310f1d7 304 serverdata = "type=tcp,disconnect";
f163b202
SB
305 break;
306
f163b202 307 case 'f':
3f37cc3e 308 errno = 0;
f163b202
SB
309 val = strtoul(optarg, &end_ptr, 10);
310 if (val != (unsigned int)val || errno || end_ptr[0] != '\0') {
cba81569
SB
311 logprintf(STDERR_FILENO,
312 "Cannot parse socket file descriptor.\n");
4fd2d23b 313 exit(EXIT_FAILURE);
f163b202
SB
314 }
315 mlp.fd = val;
316 if (fstat(mlp.fd, &statbuf) != 0) {
cba81569
SB
317 logprintf(STDERR_FILENO, "Cannot stat file descriptor: %s\n",
318 strerror(errno));
4fd2d23b 319 exit(EXIT_FAILURE);
f163b202 320 }
1e029685
SB
321 /*
322 * test for wrong file types; anonymous fd's do not seem to be any of the wrong
323 * ones but are also not character devices
324 */
b20eafa7
SB
325 if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode) ||
326 S_ISBLK(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) {
cba81569
SB
327 logprintf(STDERR_FILENO,
328 "Given file descriptor type is not supported.\n");
4fd2d23b 329 exit(EXIT_FAILURE);
f163b202 330 }
0a0885cf
AV
331 mlp.flags |= MAIN_LOOP_FLAG_TERMINATE | MAIN_LOOP_FLAG_USE_FD |
332 MAIN_LOOP_FLAG_KEEP_CONNECTION;
87d56f93 333
f163b202
SB
334 SWTPM_IO_SetSocketFD(mlp.fd);
335
336 break;
337
7c0a033f 338 case 'c':
4716d35a 339 serverdata = optarg;
7c0a033f
SB
340 break;
341
f163b202
SB
342 case 't':
343 mlp.flags |= MAIN_LOOP_FLAG_TERMINATE;
344 break;
345
346 case 'k':
347 keydata = optarg;
348 break;
349
84259c17
SB
350 case 'K':
351 migkeydata = optarg;
352 break;
353
f163b202
SB
354 case 'l':
355 logdata = optarg;
356 break;
357
b2151737
SB
358 case 'P':
359 piddata = optarg;
360 break;
361
bc525ccd
SB
362 case 's':
363 tpmstatedata = optarg;
364 break;
365
9ddc6998
SB
366 case 'C':
367 ctrlchdata = optarg;
368 break;
369
4a565414
SB
370 case 'L':
371 localitydata = optarg;
372 break;
373
63ab6c3c
SB
374 case 'F':
375 flagsdata = optarg;
376 break;
377
fbc596ab 378 case '2':
32694853 379 mlp.tpmversion = TPMLIB_TPM_VERSION_2;
fbc596ab
SB
380 break;
381
f163b202
SB
382 case 'h':
383 usage(stdout, prgname, iface);
384 exit(EXIT_SUCCESS);
385
11114ba7 386 case 'a':
3a3a9f5b
SB
387 printcapabilities = true;
388 break;
11114ba7 389
5bc59a74
ET
390 case 'e':
391 printstates = true;
392 break;
393
bb420d74
SB
394 case 'r':
395 runas = optarg;
396 break;
397
07dfd958
SB
398 case 'S':
399 seccompdata = optarg;
400 break;
401
f163b202
SB
402 default:
403 usage(stderr, prgname, iface);
404 exit(EXIT_FAILURE);
405 }
406 }
407
f1766b31
SB
408 if (optind < argc) {
409 logprintf(STDERR_FILENO,
410 "Unknown parameter '%s'\n", argv[optind]);
4fd2d23b 411 exit(EXIT_FAILURE);
f1766b31
SB
412 }
413
15ff0d96
ET
414 /* change process ownership before accessing files */
415 if (runas) {
416 if (change_process_owner(runas) < 0)
417 exit(EXIT_FAILURE);
418 }
419
420 if (handle_log_options(logdata) < 0)
421 exit(EXIT_FAILURE);
422
83764896
SB
423 if (mlp.fd >= 0 && mlp.fd < 3) {
424 /* no std{in,out,err} */
425 logprintf(STDERR_FILENO,
426 "Error: Cannot accept file descriptors with values 0, 1, or 2\n");
4fd2d23b 427 exit(EXIT_FAILURE);
83764896
SB
428 }
429
ccaf99f1
MAL
430 if (printcapabilities) {
431 /*
432 * Choose the TPM version so that getting/setting buffer size works.
433 * Ignore failure, for backward compatibility when TPM 1.2 is disabled.
434 */
435 TPMLIB_ChooseTPMVersion(mlp.tpmversion);
436 ret = capabilities_print_json(false);
437 exit(ret ? EXIT_FAILURE : EXIT_SUCCESS);
438 }
439
fbc596ab
SB
440 if (TPMLIB_ChooseTPMVersion(mlp.tpmversion) != TPM_SUCCESS) {
441 logprintf(STDERR_FILENO,
442 "Error: Could not choose TPM version.\n");
4fd2d23b 443 exit(EXIT_FAILURE);
fbc596ab
SB
444 }
445
f34e01a5
SB
446 if (handle_ctrlchannel_options(ctrlchdata, &mlp.cc) < 0 ||
447 handle_server_options(serverdata, &server) < 0) {
448 goto exit_failure;
449 }
450
2d3deaef 451 tpmstate_set_version(mlp.tpmversion);
fbc596ab 452
5bc59a74
ET
453 if (printstates) {
454 if (handle_tpmstate_options(tpmstatedata) < 0)
455 goto exit_failure;
456 if (tpmstatedata == NULL) {
457 logprintf(STDERR_FILENO,
458 "Error: --tpmstate option is required for --print-states\n");
459 goto exit_failure;
460 }
89f25f91 461 ret = SWTPM_NVRAM_PrintJson();
5bc59a74
ET
462 if (ret == 0)
463 goto exit_success;
464 else
465 goto exit_failure;
466 }
467
15ff0d96 468 if (handle_key_options(keydata) < 0 ||
84259c17 469 handle_migration_key_options(migkeydata) < 0 ||
bc525ccd 470 handle_pid_options(piddata) < 0 ||
4a565414 471 handle_locality_options(localitydata, &mlp.locality_flags) < 0 ||
7c0a033f 472 handle_tpmstate_options(tpmstatedata) < 0 ||
07dfd958 473 handle_seccomp_options(seccompdata, &seccomp_action) < 0 ||
e6bc4bdf
SB
474 handle_flags_options(flagsdata, &need_init_cmd,
475 &mlp.startupType) < 0) {
510f1848
SB
476 goto exit_failure;
477 }
f163b202 478
4716d35a
SB
479 if (server) {
480 if (server_get_fd(server) >= 0) {
75f9f0d3 481 mlp.fd = server_set_fd(server, -1);
7c0a033f
SB
482 SWTPM_IO_SetSocketFD(mlp.fd);
483 }
484
485 mlp.flags |= MAIN_LOOP_FLAG_KEEP_CONNECTION;
4716d35a 486 if ((server_get_flags(server) & SERVER_FLAG_DISCONNECT))
c2d04f53 487 mlp.flags &= ~MAIN_LOOP_FLAG_KEEP_CONNECTION;
7c0a033f 488
4716d35a 489 if ((server_get_flags(server) & SERVER_FLAG_FD_GIVEN))
7c0a033f
SB
490 mlp.flags |= MAIN_LOOP_FLAG_TERMINATE | MAIN_LOOP_FLAG_USE_FD;
491 }
492
b2151737 493 if (pidfile_write(getpid()) < 0) {
510f1848 494 goto exit_failure;
b2151737
SB
495 }
496
f163b202
SB
497 setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe */
498
499#ifdef DEBUG
500 /* initialization */
501 start_time = time(NULL);
502#endif
503
504 TPM_DEBUG("main: Initializing TPM at %s", ctime(&start_time));
505
fbc596ab 506 tpmlib_debug_libtpms_parameters(mlp.tpmversion);
f163b202 507
7f46fa86
SB
508 if ((rc = tpmlib_register_callbacks(&callbacks)))
509 goto error_no_tpm;
510
63ab6c3c 511 if (!need_init_cmd) {
32694853 512 if ((rc = tpmlib_start(0, mlp.tpmversion)))
63ab6c3c
SB
513 goto error_no_tpm;
514 tpm_running = true;
515 }
1bebb6be
SB
516
517 if (install_sighandlers(notify_fd, sigterm_handler) < 0)
518 goto error_no_sighandlers;
519
07dfd958
SB
520 if (create_seccomp_profile(false, seccomp_action) < 0)
521 goto error_seccomp_profile;
522
98d1d126
NW
523 if (daemonize) {
524 daemonize_finish();
525 }
526
7f46fa86 527 rc = mainLoop(&mlp, notify_fd[0]);
1bebb6be 528
07dfd958 529error_seccomp_profile:
869df69f 530 uninstall_sighandlers();
bd247379 531
1bebb6be
SB
532error_no_sighandlers:
533 TPMLIB_Terminate();
f163b202 534
1bebb6be 535error_no_tpm:
f163b202
SB
536 close(notify_fd[0]);
537 notify_fd[0] = -1;
538 close(notify_fd[1]);
539 notify_fd[1] = -1;
540
321a22cc 541 swtpm_cleanup(mlp.cc, server);
510f1848 542
f163b202
SB
543 /* Fatal initialization errors cause the program to abort */
544 if (rc == 0) {
4fd2d23b 545 exit(EXIT_SUCCESS);
f163b202
SB
546 }
547 else {
548 TPM_DEBUG("main: TPM initialization failure %08x, exiting\n", rc);
4fd2d23b 549 exit(EXIT_FAILURE);
f163b202 550 }
510f1848
SB
551
552exit_failure:
321a22cc 553 swtpm_cleanup(mlp.cc, server);
510f1848 554
4fd2d23b 555 exit(EXIT_FAILURE);
5bc59a74
ET
556
557exit_success:
558 swtpm_cleanup(mlp.cc, server);
559
560 exit(EXIT_SUCCESS);
f163b202 561}