From: Yu Watanabe Date: Wed, 10 Apr 2019 08:50:27 +0000 (+0900) Subject: util: extend unhexmem() to accept secure flag X-Git-Tag: v243-rc1~561^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7088befb17283ac7a8185eb916acb00c6219ac83;p=thirdparty%2Fsystemd.git util: extend unhexmem() to accept secure flag When the flag is set, buffer is cleared on failure. This is a continuation of 2432d09c7a7115004b16eb11bf81ffeeb32d15ad. --- diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 132439fd1c5..5e425b0231d 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -108,10 +108,12 @@ static int unhex_next(const char **p, size_t *l) { return r; } -int unhexmem(const char *p, size_t l, 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(ret); assert(ret_len); @@ -121,7 +123,8 @@ int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) { l = strlen(p); /* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */ - buf = malloc((l + 1) / 2 + 1); + buf_size = (l + 1) / 2 + 1; + buf = malloc(buf_size); if (!buf) return -ENOMEM; @@ -131,12 +134,16 @@ int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) { a = unhex_next(&x, &l); if (a == -EPIPE) /* End of string */ break; - if (a < 0) - return a; + if (a < 0) { + r = a; + goto on_failure; + } b = unhex_next(&x, &l); - if (b < 0) - return b; + if (b < 0) { + r = b; + goto on_failure; + } *(z++) = (uint8_t) a << 4 | (uint8_t) b; } @@ -147,6 +154,12 @@ int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) { *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 diff --git a/src/basic/hexdecoct.h b/src/basic/hexdecoct.h index fa6013ee750..dfdff1e9bb0 100644 --- a/src/basic/hexdecoct.h +++ b/src/basic/hexdecoct.h @@ -18,7 +18,10 @@ char hexchar(int x) _const_; int unhexchar(char c) _const_; char *hexmem(const void *p, size_t l); -int unhexmem(const char *p, size_t l, void **mem, size_t *len); +int unhexmem_full(const char *p, size_t l, bool secure, void **mem, size_t *len); +static inline int unhexmem(const char *p, size_t l, void **mem, size_t *len) { + return unhexmem_full(p, l, false, mem, len); +} char base32hexchar(int x) _const_; int unbase32hexchar(char c) _const_;