From 1beeaf3b71aed763d5fc7a9ee044d675f8906e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20B=C3=B6sz=C3=B6rm=C3=A9nyi?= Date: Sun, 18 Jul 2021 10:28:37 +0200 Subject: [PATCH] fix(dracut-install): tweaks to get_real_file() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix potential memory leaks in two locations and use _exit(EXIT_FAILURE) if asprintf(&abspath, ...) fails. Signed-off-by: Zoltán Böszörményi --- src/install/dracut-install.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/install/dracut-install.c b/src/install/dracut-install.c index 00a4f5867a..6feb778216 100644 --- a/src/install/dracut-install.c +++ b/src/install/dracut-install.c @@ -419,7 +419,7 @@ static char *get_real_file(const char *src, bool fullyresolve) char linktarget[PATH_MAX + 1]; ssize_t linksz; _cleanup_free_ char *fullsrcpath; - char *abspath = NULL; + char *abspath = NULL; /* this is returned from the function, don't _cleanup_free_ */ struct stat sb; if (sysrootdirlen) { @@ -455,30 +455,39 @@ static char *get_real_file(const char *src, bool fullyresolve) log_debug("get_real_file: readlink('%s') returns '%s'", fullsrcpath, linktarget); if (linktarget[0] == '/') { - if (asprintf(&abspath, "%s%s", (sysrootdirlen ? sysrootdir : ""), linktarget) < 0) - return NULL; + if (asprintf(&abspath, "%s%s", (sysrootdirlen ? sysrootdir : ""), linktarget) < 0) { + log_error("Out of memory!"); + _exit(EXIT_FAILURE); + } } else { _cleanup_free_ char *fullsrcdir = strdup(fullsrcpath); if (!fullsrcdir) { log_error("Out of memory!"); - return NULL; + _exit(EXIT_FAILURE); } fullsrcdir[dir_len(fullsrcdir)] = '\0'; - if (asprintf(&abspath, "%s/%s", fullsrcdir, linktarget) < 0) - return NULL; + if (asprintf(&abspath, "%s/%s", fullsrcdir, linktarget) < 0) { + log_error("Out of memory!"); + _exit(EXIT_FAILURE); + } } if (fullyresolve) { struct stat st; if (lstat(abspath, &st) < 0) { - if (errno != ENOENT) + if (errno != ENOENT) { + free(abspath); return NULL; + } + } + if (S_ISLNK(st.st_mode)) { + char *tmp = get_real_file(abspath, fullyresolve); + free(abspath); + abspath = tmp; } - if (S_ISLNK(st.st_mode)) - return get_real_file(abspath, fullyresolve); } log_debug("get_real_file('%s') => '%s'", src, abspath);