Merge pull request #26004 from poettering/cleanuo-erase-moar
tree-wide: use CLEANUP_ERASE() at many places
This commit is contained in:
+46
-68
@@ -110,12 +110,17 @@ static int unhex_next(const char **p, size_t *l) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int unhexmem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_len) {
|
||||
int unhexmem_full(
|
||||
const char *p,
|
||||
size_t l,
|
||||
bool secure,
|
||||
void **ret,
|
||||
size_t *ret_len) {
|
||||
|
||||
_cleanup_free_ uint8_t *buf = NULL;
|
||||
size_t buf_size;
|
||||
const char *x;
|
||||
uint8_t *z;
|
||||
int r;
|
||||
|
||||
assert(p || l == 0);
|
||||
|
||||
@@ -128,22 +133,20 @@ int unhexmem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
CLEANUP_ERASE_PTR(secure ? &buf : NULL, buf_size);
|
||||
|
||||
for (x = p, z = buf;;) {
|
||||
int a, b;
|
||||
|
||||
a = unhex_next(&x, &l);
|
||||
if (a == -EPIPE) /* End of string */
|
||||
break;
|
||||
if (a < 0) {
|
||||
r = a;
|
||||
goto on_failure;
|
||||
}
|
||||
if (a < 0)
|
||||
return a;
|
||||
|
||||
b = unhex_next(&x, &l);
|
||||
if (b < 0) {
|
||||
r = b;
|
||||
goto on_failure;
|
||||
}
|
||||
if (b < 0)
|
||||
return b;
|
||||
|
||||
*(z++) = (uint8_t) a << 4 | (uint8_t) b;
|
||||
}
|
||||
@@ -156,12 +159,6 @@ int unhexmem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_
|
||||
*ret = TAKE_PTR(buf);
|
||||
|
||||
return 0;
|
||||
|
||||
on_failure:
|
||||
if (secure)
|
||||
explicit_bzero_safe(buf, buf_size);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* https://tools.ietf.org/html/rfc4648#section-6
|
||||
@@ -765,12 +762,17 @@ static int unbase64_next(const char **p, size_t *l) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int unbase64mem_full(const char *p, size_t l, bool secure, void **ret, size_t *ret_size) {
|
||||
int unbase64mem_full(
|
||||
const char *p,
|
||||
size_t l,
|
||||
bool secure,
|
||||
void **ret,
|
||||
size_t *ret_size) {
|
||||
|
||||
_cleanup_free_ uint8_t *buf = NULL;
|
||||
const char *x;
|
||||
uint8_t *z;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
assert(p || l == 0);
|
||||
|
||||
@@ -785,60 +787,44 @@ int unbase64mem_full(const char *p, size_t l, bool secure, void **ret, size_t *r
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
CLEANUP_ERASE_PTR(secure ? &buf : NULL, len);
|
||||
|
||||
for (x = p, z = buf;;) {
|
||||
int a, b, c, d; /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
|
||||
|
||||
a = unbase64_next(&x, &l);
|
||||
if (a == -EPIPE) /* End of string */
|
||||
break;
|
||||
if (a < 0) {
|
||||
r = a;
|
||||
goto on_failure;
|
||||
}
|
||||
if (a == INT_MAX) { /* Padding is not allowed at the beginning of a 4ch block */
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
if (a < 0)
|
||||
return a;
|
||||
if (a == INT_MAX) /* Padding is not allowed at the beginning of a 4ch block */
|
||||
return -EINVAL;
|
||||
|
||||
b = unbase64_next(&x, &l);
|
||||
if (b < 0) {
|
||||
r = b;
|
||||
goto on_failure;
|
||||
}
|
||||
if (b == INT_MAX) { /* Padding is not allowed at the second character of a 4ch block either */
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
if (b < 0)
|
||||
return b;
|
||||
if (b == INT_MAX) /* Padding is not allowed at the second character of a 4ch block either */
|
||||
return -EINVAL;
|
||||
|
||||
c = unbase64_next(&x, &l);
|
||||
if (c < 0) {
|
||||
r = c;
|
||||
goto on_failure;
|
||||
}
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
d = unbase64_next(&x, &l);
|
||||
if (d < 0) {
|
||||
r = d;
|
||||
goto on_failure;
|
||||
}
|
||||
if (d < 0)
|
||||
return d;
|
||||
|
||||
if (c == INT_MAX) { /* Padding at the third character */
|
||||
|
||||
if (d != INT_MAX) { /* If the third character is padding, the fourth must be too */
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
if (d != INT_MAX) /* If the third character is padding, the fourth must be too */
|
||||
return -EINVAL;
|
||||
|
||||
/* b == 00YY0000 */
|
||||
if (b & 15) {
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
if (b & 15)
|
||||
return -EINVAL;
|
||||
|
||||
if (l > 0) { /* Trailing rubbish? */
|
||||
r = -ENAMETOOLONG;
|
||||
goto on_failure;
|
||||
}
|
||||
if (l > 0) /* Trailing rubbish? */
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
|
||||
break;
|
||||
@@ -846,15 +832,11 @@ int unbase64mem_full(const char *p, size_t l, bool secure, void **ret, size_t *r
|
||||
|
||||
if (d == INT_MAX) {
|
||||
/* c == 00ZZZZ00 */
|
||||
if (c & 3) {
|
||||
r = -EINVAL;
|
||||
goto on_failure;
|
||||
}
|
||||
if (c & 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (l > 0) { /* Trailing rubbish? */
|
||||
r = -ENAMETOOLONG;
|
||||
goto on_failure;
|
||||
}
|
||||
if (l > 0) /* Trailing rubbish? */
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||
@@ -868,18 +850,14 @@ int unbase64mem_full(const char *p, size_t l, bool secure, void **ret, size_t *r
|
||||
|
||||
*z = 0;
|
||||
|
||||
assert((size_t) (z - buf) <= len);
|
||||
|
||||
if (ret_size)
|
||||
*ret_size = (size_t) (z - buf);
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(buf);
|
||||
|
||||
return 0;
|
||||
|
||||
on_failure:
|
||||
if (secure)
|
||||
explicit_bzero_safe(buf, len);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void hexdump(FILE *f, const void *p, size_t s) {
|
||||
|
||||
@@ -29,6 +29,8 @@ static inline void *explicit_bzero_safe(void *p, size_t l) {
|
||||
#endif
|
||||
|
||||
struct VarEraser {
|
||||
/* NB: This is a pointer to memory to erase in case of CLEANUP_ERASE(). Pointer to pointer to memory
|
||||
* to erase in case of CLEANUP_ERASE_PTR() */
|
||||
void *p;
|
||||
size_t size;
|
||||
};
|
||||
@@ -38,5 +40,27 @@ static inline void erase_var(struct VarEraser *e) {
|
||||
}
|
||||
|
||||
/* Mark var to be erased when leaving scope. */
|
||||
#define CLEANUP_ERASE(var) \
|
||||
_cleanup_(erase_var) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { .p = &var, .size = sizeof(var) }
|
||||
#define CLEANUP_ERASE(var) \
|
||||
_cleanup_(erase_var) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { \
|
||||
.p = &(var), \
|
||||
.size = sizeof(var), \
|
||||
}
|
||||
|
||||
static inline void erase_varp(struct VarEraser *e) {
|
||||
|
||||
/* Very similar to erase_var(), but assumes `p` is a pointer to a pointer whose memory shall be destructed. */
|
||||
if (!e->p)
|
||||
return;
|
||||
|
||||
explicit_bzero_safe(*(void**) e->p, e->size);
|
||||
}
|
||||
|
||||
/* Mark pointer so that memory pointed to is erased when leaving scope. Note: this takes a pointer to the
|
||||
* specified pointer, instead of just a copy of it. This is to allow callers to invalidate the pointer after
|
||||
* use, if they like, disabling our automatic erasure (for example because they succeeded with whatever they
|
||||
* wanted to do and now intend to return the allocated buffer to their caller without it being erased). */
|
||||
#define CLEANUP_ERASE_PTR(ptr, sz) \
|
||||
_cleanup_(erase_varp) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { \
|
||||
.p = (ptr), \
|
||||
.size = (sz), \
|
||||
}
|
||||
|
||||
+18
-40
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
+12
-12
@@ -216,7 +216,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;
|
||||
@@ -245,21 +244,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);
|
||||
@@ -267,17 +268,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) {
|
||||
@@ -286,7 +287,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;
|
||||
@@ -295,13 +296,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -322,6 +322,13 @@ TEST(base64mem_linebreak) {
|
||||
assert_se(decoded_size == n);
|
||||
assert_se(memcmp(data, decoded, n) == 0);
|
||||
|
||||
/* Also try in secure mode */
|
||||
decoded = mfree(decoded);
|
||||
decoded_size = 0;
|
||||
assert_se(unbase64mem_full(encoded, SIZE_MAX, /* secure= */ true, &decoded, &decoded_size) >= 0);
|
||||
assert_se(decoded_size == n);
|
||||
assert_se(memcmp(data, decoded, n) == 0);
|
||||
|
||||
for (size_t j = 0; j < (size_t) l; j++)
|
||||
assert_se((encoded[j] == '\n') == (j % (m + 1) == m));
|
||||
}
|
||||
@@ -446,7 +453,17 @@ static void test_unbase64mem_one(const char *input, const char *output, int ret)
|
||||
size_t size = 0;
|
||||
|
||||
assert_se(unbase64mem(input, SIZE_MAX, &buffer, &size) == ret);
|
||||
if (ret >= 0) {
|
||||
assert_se(size == strlen(output));
|
||||
assert_se(memcmp(buffer, output, size) == 0);
|
||||
assert_se(((char*) buffer)[size] == 0);
|
||||
}
|
||||
|
||||
/* also try in secure mode */
|
||||
buffer = mfree(buffer);
|
||||
size = 0;
|
||||
|
||||
assert_se(unbase64mem_full(input, SIZE_MAX, /* secure=*/ true, &buffer, &size) == ret);
|
||||
if (ret >= 0) {
|
||||
assert_se(size == strlen(output));
|
||||
assert_se(memcmp(buffer, output, size) == 0);
|
||||
|
||||
Reference in New Issue
Block a user