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:
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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); \
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user