1
0
mirror of https://github.com/systemd/systemd.git synced 2025-08-29 01:49:55 +03:00

Merge pull request #12047 from poettering/cryptsetup-fixlets

some small cryptsetup, ask-password and allocation fixlets
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2019-03-20 13:02:34 +01:00
committed by GitHub
5 changed files with 48 additions and 25 deletions

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <malloc.h>
#include <stdint.h>
#include <string.h>
@ -27,6 +28,9 @@ void* memdup_suffix0(const void *p, size_t l) {
/* The same as memdup() but place a safety NUL byte after the allocated memory */
if (_unlikely_(l == SIZE_MAX)) /* prevent overflow */
return NULL;
ret = malloc(l + 1);
if (!ret)
return NULL;
@ -45,19 +49,23 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
if (*allocated >= need)
return *p;
newalloc = MAX(need * 2, 64u / size);
a = newalloc * size;
/* check for overflows */
if (a < size * need)
if (_unlikely_(need > SIZE_MAX/2)) /* Overflow check */
return NULL;
newalloc = need * 2;
if (size_multiply_overflow(newalloc, size))
return NULL;
a = newalloc * size;
if (a < 64) /* Allocate at least 64 bytes */
a = 64;
q = realloc(*p, a);
if (!q)
return NULL;
*p = q;
*allocated = newalloc;
*allocated = _unlikely_(size == 0) ? newalloc : malloc_usable_size(q) / size;
return q;
}

View File

@ -156,8 +156,8 @@ void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size);
(void*)memset(_new_, 0, _xsize_); \
})
/* Takes inspiration from Rusts's Option::take() method: reads and returns a pointer, but at the same time resets it to
* NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */
/* Takes inspiration from Rust's Option::take() method: reads and returns a pointer, but at the same time
* resets it to NULL. See: https://doc.rust-lang.org/std/option/enum.Option.html#method.take */
#define TAKE_PTR(ptr) \
({ \
typeof(ptr) _ptr_ = (ptr); \

View File

@ -77,3 +77,8 @@ static inline void* explicit_bzero_safe(void *p, size_t l) {
#else
void *explicit_bzero_safe(void *p, size_t l);
#endif
/* Use with _cleanup_ to erase a single 'char' when leaving scope */
static inline void erase_char(char *p) {
explicit_bzero_safe(p, sizeof(char));
}

View File

@ -612,6 +612,24 @@ static int help(void) {
return 0;
}
static uint32_t determine_flags(void) {
uint32_t flags = 0;
if (arg_readonly)
flags |= CRYPT_ACTIVATE_READONLY;
if (arg_discards)
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (arg_same_cpu_crypt)
flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
if (arg_submit_from_crypt_cpus)
flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
return flags;
}
static int run(int argc, char *argv[]) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
int r;
@ -676,17 +694,7 @@ static int run(int argc, char *argv[]) {
return 0;
}
if (arg_readonly)
flags |= CRYPT_ACTIVATE_READONLY;
if (arg_discards)
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (arg_same_cpu_crypt)
flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
if (arg_submit_from_crypt_cpus)
flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
flags = determine_flags();
if (arg_timeout == USEC_INFINITY)
until = 0;

View File

@ -77,13 +77,18 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
if (n < 0)
return -errno;
if (n < m)
break;
explicit_bzero_safe(p, n);
free(p);
if (m > LONG_MAX / 2) /* overflow check */
return -ENOMEM;
m *= 2;
if ((long) (size_t) m != m) /* make sure that this still fits if converted to size_t */
return -ENOMEM;
free(p);
}
l = strv_parse_nulstr(p, n);
@ -306,9 +311,9 @@ int ask_password_tty(
};
for (;;) {
_cleanup_(erase_char) char c;
int sleep_for = -1, k;
ssize_t n;
char c;
if (until > 0) {
usec_t y;
@ -452,9 +457,6 @@ int ask_password_tty(
dirty = true;
}
/* Let's forget this char, just to not keep needlessly copies of key material around */
c = 'x';
}
x = strndup(passphrase, p);