ccan
ccan copied to clipboard
`tal_strdup(ctx, NULL)` returns uninitialized string
There is an edge case in tal_strdup
that results in the return of an unterminated string to the caller.
tal_strdup(ctx, NULL)
https://github.com/rustyrussell/ccan/blob/cd56b18ae87de6981b88abbe52544d8cc9f8aa0e/ccan/tal/str/str.h#L19
tal_strdup_(ctx, NULL, "char[]")
https://github.com/rustyrussell/ccan/blob/cd56b18ae87de6981b88abbe52544d8cc9f8aa0e/ccan/tal/str/str.c#L15-L19
tal_dup_arr_label(ctx, char, NULL, 1, 0, "char[]")
https://github.com/rustyrussell/ccan/blob/cd56b18ae87de6981b88abbe52544d8cc9f8aa0e/ccan/tal/tal.h#L407-L410
(char *) tal_dup_(ctx, NULL, 1, 1, 0, false, "char[]")
https://github.com/rustyrussell/ccan/blob/cd56b18ae87de6981b88abbe52544d8cc9f8aa0e/ccan/tal/tal.c#L814-L854
p = NULL;
size = 1;
n = 1;
extra = 0;
nullok = false;
label = "char[]";
nbytes = 1;
if (false && NULL == NULL) ; // branch not taken
if (!adjust_size(&nbytes, 1)) ; // branch not taken
if (1 + 0 < 1) ; // branch not taken
if (taken(NULL)) ; // branch not taken
ret = tal_alloc_arr_(ctx, 1, 1 + 0, false, "char[]");
https://github.com/rustyrussell/ccan/blob/cd56b18ae87de6981b88abbe52544d8cc9f8aa0e/ccan/tal/tal.c#L500-L507
size = 1
count = 1
clear = false
label = "char[]"
if (!adjust_size(&size, 1)) ; // branch not taken
ret = /*return*/ tal_alloc_(ctx, 1, false, "char[]");
if (ret && NULL) ; // branch not taken
// memcpy(ret, p, nbytes);
return ret;
So at the end of this call chain, we return a pointer to a buffer of size 1 whose sole byte has never been initialized, and we're claiming that this pointer points to a NUL-terminated string. That's bad! ☹️