/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include <stdlib.h>
#include <unistd.h>
#include "env-util.h"
#include "errno-util.h"
#include "initrd-util.h"
#include "log.h"
-#include "parse-util.h"
static int saved_in_initrd = -1;
saved_in_initrd = value;
}
-bool in_first_boot(void) {
- static int first_boot = -1;
+int in_first_boot(void) {
+ static int first_boot_env_parse_cached = -1;
int r;
- if (first_boot >= 0)
- return first_boot;
+ if (first_boot_env_parse_cached >= 0)
+ return first_boot_env_parse_cached;
- const char *e = secure_getenv("SYSTEMD_FIRST_BOOT");
- if (e) {
- r = parse_boolean(e);
- if (r < 0)
- log_debug_errno(r, "Failed to parse $SYSTEMD_FIRST_BOOT, ignoring: %m");
- else
- return (first_boot = r);
- }
+ r = secure_getenv_bool("SYSTEMD_FIRST_BOOT");
+ if (r >= 0)
+ return (first_boot_env_parse_cached = r);
+ if (r != -ENXIO)
+ log_debug_errno(r, "Failed to parse $SYSTEMD_FIRST_BOOT, ignoring: %m");
+ /* This is not cached and must *never* be cached, other parts of systemd write it to signal
+ * an update to the first-boot state. */
r = RET_NERRNO(access("/run/systemd/first-boot", F_OK));
- if (r < 0 && r != -ENOENT)
- log_debug_errno(r, "Failed to check if /run/systemd/first-boot exists, assuming no: %m");
- return r >= 0;
+ if (r >= 0)
+ return true;
+ if (r == -ENOENT)
+ return false;
+
+ return log_debug_errno(r, "Failed to check /run/systemd/first-boot: %m");
}
bool in_initrd(void);
void in_initrd_force(bool value);
-bool in_first_boot(void);
+int in_first_boot(void);
#include "fd-util.h"
#include "format-table.h"
#include "fs-util.h"
+#include "initrd-util.h"
#include "io-util.h"
#include "log.h"
#include "main-func.h"
/* Don't credit the random seed if we are in first-boot mode, because we are supposed to start from
* scratch. This is a safety precaution for cases where people ship "golden" images with empty
* /etc but populated /var that contains a random seed. */
- r = RET_NERRNO(access("/run/systemd/first-boot", F_OK));
- if (r == -ENOENT)
+ r = in_first_boot();
+ if (r == 0)
/* All is good, we are not in first-boot mode. */
return CREDIT_ENTROPY_YES_PLEASE;
if (r < 0) {
if (r < 0)
return r;
- return in_first_boot() == r;
+ return (in_first_boot() > 0) == r;
}
static int condition_test_environment(Condition *c, char **env) {
* exists yet); the decision itself is made in credential_boot_policy_accepts_null(). */
CredentialBootPolicy policy = query_credential_boot_policy();
- bool first_boot = in_first_boot(), have_tpm2 = efi_has_tpm2(), secure_boot = is_efi_secure_boot();
+
+ bool have_tpm2 = efi_has_tpm2(), secure_boot = is_efi_secure_boot();
+ /* in_first_boot() can return <0 on error: use the safe default in this case (not-first-boot). */
+ bool first_boot = in_first_boot() > 0;
if (!credential_boot_policy_accepts_null(policy, first_boot, have_tpm2, secure_boot))
return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON),