From afb2ef21bc46e116ec939164fdb5efb77cd88536 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 18 Apr 2024 14:54:29 +0100 Subject: [PATCH] util: don't return system allocated strings in realpath realpath(3) _may_ allocate strings (if the second param is NULL) using the system allocator. However, callers need an assurance that they can free memory using git__free. If we made realpath do an allocation, then make sure that we strdup it into our allocator's memory. More importantly, avoid this behavior by always providing a buffer to p_realpath invocations. --- src/util/unix/realpath.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/util/unix/realpath.c b/src/util/unix/realpath.c index 9e31a63b9..e1d2adb8d 100644 --- a/src/util/unix/realpath.c +++ b/src/util/unix/realpath.c @@ -16,17 +16,35 @@ char *p_realpath(const char *pathname, char *resolved) { - char *ret; - if ((ret = realpath(pathname, resolved)) == NULL) + char *result; + + if ((result = realpath(pathname, resolved)) == NULL) return NULL; #ifdef __OpenBSD__ /* The OpenBSD realpath function behaves differently, * figure out if the file exists */ - if (access(ret, F_OK) < 0) - ret = NULL; + if (access(ret, F_OK) < 0) { + if (!resolved) + free(result); + + return NULL; + } #endif - return ret; + + /* + * If resolved == NULL, the system has allocated the result + * string. We need to strdup this into _our_ allocator pool + * so that callers can free it with git__free. + */ + if (!resolved) { + char *dup = git__strdup(result); + free(result); + + result = dup; + } + + return result; } #endif