From 97e51c0285109ebb6bf8be3d1e21cb0bd5058e5a Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Fri, 17 Jun 2022 19:55:11 -0400 Subject: [PATCH] Avoid overwriting buffers with long pathnames Reported, with initial patch, by Gisle Vanem * src/main.c (find_and_set_default_shell) [W32]: Pass search_token directly to w32ify: no need to make a copy first. When we need to construct a path, use snprintf() to be sure we don't overwrite the locally-allocated buffer. * src/w32/pathstuff.c (w32ify) [W32]: Use the malloc version of _fullpath(), followed by strncpy(), to avoid overwriting buffers. --- src/main.c | 14 +++++++------- src/w32/pathstuff.c | 12 ++++++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index 5912b06c..3dcdfd00 100644 --- a/src/main.c +++ b/src/main.c @@ -941,7 +941,6 @@ find_and_set_default_shell (const char *token) char *atoken = 0; const char *search_token; const char *tokend; - PATH_VAR(sh_path); extern const char *default_shell; if (!token) @@ -965,8 +964,7 @@ find_and_set_default_shell (const char *token) { batch_mode_shell = 1; unixy_shell = 0; - sprintf (sh_path, "%s", search_token); - default_shell = xstrdup (w32ify (sh_path, 0)); + default_shell = xstrdup (w32ify (search_token, 0)); DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"), default_shell)); sh_found = 1; @@ -980,8 +978,7 @@ find_and_set_default_shell (const char *token) else if (_access (search_token, 0) == 0) { /* search token path was found */ - sprintf (sh_path, "%s", search_token); - default_shell = xstrdup (w32ify (sh_path, 0)); + default_shell = xstrdup (w32ify (search_token, 0)); DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"), default_shell)); sh_found = 1; @@ -1001,9 +998,11 @@ find_and_set_default_shell (const char *token) while (ep && *ep) { + PATH_VAR (sh_path); + *ep = '\0'; - sprintf (sh_path, "%s/%s", p, search_token); + snprintf (sh_path, GET_PATH_MAX, "%s/%s", p, search_token); if (_access (sh_path, 0) == 0) { default_shell = xstrdup (w32ify (sh_path, 0)); @@ -1025,7 +1024,8 @@ find_and_set_default_shell (const char *token) /* be sure to check last element of Path */ if (p && *p) { - sprintf (sh_path, "%s/%s", p, search_token); + PATH_VAR (sh_path); + snprintf (sh_path, GET_PATH_MAX, "%s/%s", p, search_token); if (_access (sh_path, 0) == 0) { default_shell = xstrdup (w32ify (sh_path, 0)); diff --git a/src/w32/pathstuff.c b/src/w32/pathstuff.c index edd1e45e..afee0a4a 100644 --- a/src/w32/pathstuff.c +++ b/src/w32/pathstuff.c @@ -100,13 +100,17 @@ w32ify(const char *filename, int resolve) char *p; if (resolve) - _fullpath(w32_path, filename, sizeof (w32_path)); + { + char *fp = _fullpath (NULL, filename, sizeof (w32_path)); + strncpy (w32_path, fp, sizeof (w32_path)); + free (fp); + } else - strncpy(w32_path, filename, sizeof (w32_path)); + strncpy(w32_path, filename, sizeof (w32_path)); for (p = w32_path; p && *p; p++) - if (*p == '\\') - *p = '/'; + if (*p == '\\') + *p = '/'; return w32_path; }