diff --git a/src/basic/alloc-util.c b/src/basic/alloc-util.c index b540dcddf58..948389f276c 100644 --- a/src/basic/alloc-util.c +++ b/src/basic/alloc-util.c @@ -25,16 +25,31 @@ #include "util.h" void* memdup(const void *p, size_t l) { - void *r; + void *ret; - assert(p); + assert(l == 0 || p); - r = malloc(l); - if (!r) + ret = malloc(l); + if (!ret) return NULL; - memcpy(r, p, l); - return r; + memcpy(ret, p, l); + return ret; +} + +void* memdup_suffix0(const void*p, size_t l) { + void *ret; + + assert(l == 0 || p); + + /* The same as memdup() but place a safety NUL byte after the allocated memory */ + + ret = malloc(l + 1); + if (!ret) + return NULL; + + *((uint8_t*) mempcpy(ret, p, l)) = 0; + return ret; } void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) { diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index a44dd473c11..0a89691baed 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -36,6 +36,8 @@ #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) +#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n))) + #define malloc0(n) (calloc(1, (n))) static inline void *mfree(void *memory) { @@ -52,6 +54,7 @@ static inline void *mfree(void *memory) { }) void* memdup(const void *p, size_t l) _alloc_(2); +void* memdup_suffix0(const void*p, size_t l) _alloc_(2); static inline void freep(void *p) { free(*(void**) p); @@ -84,6 +87,13 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, si return memdup(p, size * need); } +_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) { + if (size_multiply_overflow(size, need)) + return NULL; + + return memdup_suffix0(p, size * need); +} + void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size); void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size); diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 02ae4265c6b..54516cfb961 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -95,13 +95,12 @@ static int parse_field(const void *data, size_t length, const char *field, char return 0; nl = length - fl; - buf = new(char, nl+1); + + + buf = newdup_suffix0(char, (const char*) data + fl, nl); if (!buf) return log_oom(); - memcpy(buf, (const char*) data + fl, nl); - buf[nl] = 0; - free(*target); *target = buf;