]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: use CLEANUP_ERASE() at various places
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Jan 2023 11:39:58 +0000 (12:39 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 16 Jan 2023 14:44:43 +0000 (15:44 +0100)
Let's use this new macro wherever it makes sense, as it allows us to
shorten or clean-up paths, and makes it less likely to miss a return
path.

src/home/homework-fscrypt.c
src/shared/ask-password-api.c
src/shared/creds-util.c
src/shared/ethtool-util.c
src/shared/tpm2-util.c

index afe3447d62a906016aeca35f2594114bbc46faed..8b7fdda5b1adbefc8466dec365c1ca35017e48fd 100644 (file)
@@ -58,10 +58,10 @@ static int fscrypt_upload_volume_key(
         };
         memcpy(key.raw, volume_key, volume_key_size);
 
+        CLEANUP_ERASE(key);
+
         /* Upload to the kernel */
         serial = add_key("logon", description, &key, sizeof(key), where);
-        explicit_bzero_safe(&key, sizeof(key));
-
         if (serial < 0)
                 return log_error_errno(errno, "Failed to install master key in keyring: %m");
 
@@ -124,20 +124,18 @@ static int fscrypt_slot_try_one(
          *      resulting hash.
          */
 
+        CLEANUP_ERASE(derived);
+
         if (PKCS5_PBKDF2_HMAC(
                             password, strlen(password),
                             salt, salt_size,
                             0xFFFF, EVP_sha512(),
-                            sizeof(derived), derived) != 1) {
-                r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
-                goto finish;
-        }
+                            sizeof(derived), derived) != 1)
+                return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
 
         context = EVP_CIPHER_CTX_new();
-        if (!context) {
-                r = log_oom();
-                goto finish;
-        }
+        if (!context)
+                return log_oom();
 
         /* We use AES256 in counter mode */
         assert_se(cc = EVP_aes_256_ctr());
@@ -145,13 +143,8 @@ static int fscrypt_slot_try_one(
         /* We only use the first half of the derived key */
         assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
 
-        if (EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)  {
-                r = log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
-                goto finish;
-        }
-
-        /* Flush out the derived key now, we don't need it anymore */
-        explicit_bzero_safe(derived, sizeof(derived));
+        if (EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
 
         decrypted_size = encrypted_size + EVP_CIPHER_key_length(cc) * 2;
         decrypted = malloc(decrypted_size);
@@ -184,10 +177,6 @@ static int fscrypt_slot_try_one(
                 *ret_decrypted_size = decrypted_size;
 
         return 0;
-
-finish:
-        explicit_bzero_safe(derived, sizeof(derived));
-        return r;
 }
 
 static int fscrypt_slot_try_many(
@@ -413,20 +402,18 @@ static int fscrypt_slot_set(
         if (r < 0)
                 return log_error_errno(r, "Failed to generate salt: %m");
 
+        CLEANUP_ERASE(derived);
+
         if (PKCS5_PBKDF2_HMAC(
                             password, strlen(password),
                             salt, sizeof(salt),
                             0xFFFF, EVP_sha512(),
-                            sizeof(derived), derived) != 1) {
-                r = log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
-                goto finish;
-        }
+                            sizeof(derived), derived) != 1)
+                return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
 
         context = EVP_CIPHER_CTX_new();
-        if (!context) {
-                r = log_oom();
-                goto finish;
-        }
+        if (!context)
+                return log_oom();
 
         /* We use AES256 in counter mode */
         cc = EVP_aes_256_ctr();
@@ -434,13 +421,8 @@ static int fscrypt_slot_set(
         /* We only use the first half of the derived key */
         assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
 
-        if (EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)  {
-                r = log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
-                goto finish;
-        }
-
-        /* Flush out the derived key now, we don't need it anymore */
-        explicit_bzero_safe(derived, sizeof(derived));
+        if (EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
 
         encrypted_size = volume_key_size + EVP_CIPHER_key_length(cc) * 2;
         encrypted = malloc(encrypted_size);
@@ -477,10 +459,6 @@ static int fscrypt_slot_set(
         log_info("Written key slot %s.", label);
 
         return 0;
-
-finish:
-        explicit_bzero_safe(derived, sizeof(derived));
-        return r;
 }
 
 int home_create_fscrypt(
index dc3d70bf1f37362faf3203a5e2ef96656f053fc7..fe06f418144d4c067af5e2d7e88cf752f741c3a5 100644 (file)
@@ -258,6 +258,8 @@ int ask_password_plymouth(
         if (r < 0)
                 return r;
 
+        CLEANUP_ERASE(buffer);
+
         pollfd[POLL_SOCKET].fd = fd;
         pollfd[POLL_SOCKET].events = POLLIN;
         pollfd[POLL_INOTIFY].fd = notify;
@@ -271,20 +273,16 @@ int ask_password_plymouth(
                 else
                         timeout = USEC_INFINITY;
 
-                if (flag_file && access(flag_file, F_OK) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
+                if (flag_file && access(flag_file, F_OK) < 0)
+                        return -errno;
 
                 r = ppoll_usec(pollfd, notify >= 0 ? 2 : 1, timeout);
                 if (r == -EINTR)
                         continue;
                 if (r < 0)
-                        goto finish;
-                if (r == 0) {
-                        r = -ETIME;
-                        goto finish;
-                }
+                        return r;
+                if (r == 0)
+                        return -ETIME;
 
                 if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
                         (void) flush_fd(notify);
@@ -297,13 +295,10 @@ int ask_password_plymouth(
                         if (ERRNO_IS_TRANSIENT(errno))
                                 continue;
 
-                        r = -errno;
-                        goto finish;
-                }
-                if (k == 0) {
-                        r = -EIO;
-                        goto finish;
+                        return -errno;
                 }
+                if (k == 0)
+                        return -EIO;
 
                 p += k;
 
@@ -315,14 +310,12 @@ int ask_password_plymouth(
                                  * with a normal password request */
                                 packet = mfree(packet);
 
-                                if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
-                                        r = -ENOMEM;
-                                        goto finish;
-                                }
+                                if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
+                                        return -ENOMEM;
 
                                 r = loop_write(fd, packet, n+1, true);
                                 if (r < 0)
-                                        goto finish;
+                                        return r;
 
                                 flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
                                 p = 0;
@@ -330,8 +323,7 @@ int ask_password_plymouth(
                         }
 
                         /* No password, because UI not shown */
-                        r = -ENOENT;
-                        goto finish;
+                        return -ENOENT;
 
                 } else if (IN_SET(buffer[0], 2, 9)) {
                         uint32_t size;
@@ -343,35 +335,25 @@ int ask_password_plymouth(
 
                         memcpy(&size, buffer+1, sizeof(size));
                         size = le32toh(size);
-                        if (size + 5 > sizeof(buffer)) {
-                                r = -EIO;
-                                goto finish;
-                        }
+                        if (size + 5 > sizeof(buffer))
+                                return -EIO;
 
                         if (p-5 < size)
                                 continue;
 
                         l = strv_parse_nulstr(buffer + 5, size);
-                        if (!l) {
-                                r = -ENOMEM;
-                                goto finish;
-                        }
+                        if (!l)
+                                return -ENOMEM;
 
                         *ret = l;
                         break;
 
-                } else {
+                } else
                         /* Unknown packet */
-                        r = -EIO;
-                        goto finish;
-                }
+                        return -EIO;
         }
 
-        r = 0;
-
-finish:
-        explicit_bzero_safe(buffer, sizeof(buffer));
-        return r;
+        return 0;
 }
 
 #define NO_ECHO "(no echo) "
@@ -433,6 +415,8 @@ int ask_password_tty(
                         return -errno;
         }
 
+        CLEANUP_ERASE(passphrase);
+
         /* If the caller didn't specify a TTY, then use the controlling tty, if we can. */
         if (ttyfd < 0)
                 ttyfd = cttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC);
@@ -636,7 +620,6 @@ int ask_password_tty(
         }
 
         x = strndup(passphrase, p);
-        explicit_bzero_safe(passphrase, sizeof(passphrase));
         if (!x) {
                 r = -ENOMEM;
                 goto finish;
@@ -896,6 +879,8 @@ int ask_password_agent(
                         goto finish;
                 }
 
+                CLEANUP_ERASE(passphrase);
+
                 cmsg_close_all(&msghdr);
 
                 if (n == 0) {
@@ -920,7 +905,6 @@ int ask_password_agent(
                                 l = strv_new("");
                         else
                                 l = strv_parse_nulstr(passphrase+1, n-1);
-                        explicit_bzero_safe(passphrase, n);
                         if (!l) {
                                 r = -ENOMEM;
                                 goto finish;
index a68837b70bdd1f9007cf822f066a2275f7ae0d69..2ee62cd404050afe5cff4fc13be841348373be26 100644 (file)
@@ -215,7 +215,6 @@ static int make_credential_host_secret(
                 void **ret_data,
                 size_t *ret_size) {
 
-        struct credential_host_secret_format buf;
         _cleanup_free_ char *t = NULL;
         _cleanup_close_ int fd = -EBADF;
         int r;
@@ -239,21 +238,23 @@ static int make_credential_host_secret(
         if (r < 0)
                 log_debug_errno(r, "Failed to set file attributes for secrets file, ignoring: %m");
 
-        buf = (struct credential_host_secret_format) {
+        struct credential_host_secret_format buf = {
                 .machine_id = machine_id,
         };
 
+        CLEANUP_ERASE(buf);
+
         r = crypto_random_bytes(buf.data, sizeof(buf.data));
         if (r < 0)
-                goto finish;
+                goto fail;
 
         r = loop_write(fd, &buf, sizeof(buf), false);
         if (r < 0)
-                goto finish;
+                goto fail;
 
         if (fsync(fd) < 0) {
                 r = -errno;
-                goto finish;
+                goto fail;
         }
 
         warn_not_encrypted(fd, flags, dirname, fn);
@@ -261,17 +262,17 @@ static int make_credential_host_secret(
         if (t) {
                 r = rename_noreplace(dfd, t, dfd, fn);
                 if (r < 0)
-                        goto finish;
+                        goto fail;
 
                 t = mfree(t);
         } else if (linkat(fd, "", dfd, fn, AT_EMPTY_PATH) < 0) {
                 r = -errno;
-                goto finish;
+                goto fail;
         }
 
         if (fsync(dfd) < 0) {
                 r = -errno;
-                goto finish;
+                goto fail;
         }
 
         if (ret_data) {
@@ -280,7 +281,7 @@ static int make_credential_host_secret(
                 copy = memdup(buf.data, sizeof(buf.data));
                 if (!copy) {
                         r = -ENOMEM;
-                        goto finish;
+                        goto fail;
                 }
 
                 *ret_data = copy;
@@ -289,13 +290,12 @@ static int make_credential_host_secret(
         if (ret_size)
                 *ret_size = sizeof(buf.data);
 
-        r = 0;
+        return 0;
 
-finish:
+fail:
         if (t && unlinkat(dfd, t, 0) < 0)
                 log_debug_errno(errno, "Failed to remove temporary credential key: %m");
 
-        explicit_bzero_safe(&buf, sizeof(buf));
         return r;
 }
 
index e2b2ca235298b23af3b47f77bb60b5d21bd88c81..e978b8bf7ea34871e04c083ef2f833047bcfc9d7 100644 (file)
@@ -434,6 +434,8 @@ int ethtool_set_wol(
 
         strscpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname);
 
+        CLEANUP_ERASE(ecmd);
+
         if (ioctl(*ethtool_fd, SIOCETHTOOL, &ifr) < 0)
                 return -errno;
 
@@ -466,16 +468,11 @@ int ethtool_set_wol(
                 need_update = true;
         }
 
-        if (!need_update) {
-                explicit_bzero_safe(&ecmd, sizeof(ecmd));
+        if (!need_update)
                 return 0;
-        }
 
         ecmd.cmd = ETHTOOL_SWOL;
-        r = RET_NERRNO(ioctl(*ethtool_fd, SIOCETHTOOL, &ifr));
-
-        explicit_bzero_safe(&ecmd, sizeof(ecmd));
-        return r;
+        return RET_NERRNO(ioctl(*ethtool_fd, SIOCETHTOOL, &ifr));
 }
 
 int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netdev_ring_param *ring) {
index ba8dfb041d8b07ffb2e177b19cc6326c8359b159..2b34e4fd65d840a6c63167b27ea6fb479bd4b995 100644 (file)
@@ -735,13 +735,14 @@ static void hash_pin(const char *pin, size_t len, TPM2B_AUTH *auth) {
 
         assert(auth);
         assert(pin);
+
         auth->size = SHA256_DIGEST_SIZE;
 
+        CLEANUP_ERASE(hash);
+
         sha256_init_ctx(&hash);
         sha256_process_bytes(pin, len, &hash);
         sha256_finish_ctx(&hash, auth->buffer);
-
-        explicit_bzero_safe(&hash, sizeof(hash));
 }
 
 static int tpm2_make_encryption_session(
@@ -773,11 +774,11 @@ static int tpm2_make_encryption_session(
         if (pin) {
                 TPM2B_AUTH auth = {};
 
+                CLEANUP_ERASE(auth);
+
                 hash_pin(pin, strlen(pin), &auth);
 
                 rc = sym_Esys_TR_SetAuth(c, bind_key, &auth);
-                /* ESAPI knows about it, so clear it from our memory */
-                explicit_bzero_safe(&auth, sizeof(auth));
                 if (rc != TSS2_RC_SUCCESS)
                         return log_error_errno(
                                                SYNTHETIC_ERRNO(ENOTRECOVERABLE),
@@ -1369,8 +1370,8 @@ int tpm2_seal(const char *device,
         static const TPML_PCR_SELECTION creation_pcr = {};
         _cleanup_(erase_and_freep) void *secret = NULL;
         _cleanup_free_ void *blob = NULL, *hash = NULL;
-        TPM2B_SENSITIVE_CREATE hmac_sensitive;
         ESYS_TR primary = ESYS_TR_NONE, session = ESYS_TR_NONE;
+        TPM2B_SENSITIVE_CREATE hmac_sensitive;
         TPMI_ALG_PUBLIC primary_alg;
         TPM2B_PUBLIC hmac_template;
         TPMI_ALG_HASH pcr_bank;
@@ -1410,6 +1411,8 @@ int tpm2_seal(const char *device,
 
         start = now(CLOCK_MONOTONIC);
 
+        CLEANUP_ERASE(hmac_sensitive);
+
         r = tpm2_context_init(device, &c);
         if (r < 0)
                 return r;
@@ -1498,7 +1501,6 @@ int tpm2_seal(const char *device,
         }
 
         secret = memdup(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
-        explicit_bzero_safe(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
         if (!secret) {
                 r = log_oom();
                 goto finish;
@@ -1559,7 +1561,6 @@ int tpm2_seal(const char *device,
         r = 0;
 
 finish:
-        explicit_bzero_safe(&hmac_sensitive, sizeof(hmac_sensitive));
         primary = tpm2_flush_context_verbose(c.esys_context, primary);
         session = tpm2_flush_context_verbose(c.esys_context, session);
         return r;