# HG changeset patch # User Bram Moolenaar # Date 1550861112 -3600 # Node ID b9098585d9452229b24497aa0381a366f137dbaf # Parent 00844735e9361a78295b2b1b9f2801adf00cdc9f patch 8.1.0976: dosinstall still has buffer overflow problems commit https://github.com/vim/vim/commit/e4963c543ddcfc4845fa0d42893b6a4e1aa27c47 Author: Bram Moolenaar Date: Fri Feb 22 19:41:08 2019 +0100 patch 8.1.0976: dosinstall still has buffer overflow problems Problem: Dosinstall still has buffer overflow problems. Solution: Adjust buffer sizes. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/4002) diff --git a/src/dosinst.c b/src/dosinst.c --- a/src/dosinst.c +++ b/src/dosinst.c @@ -388,7 +388,7 @@ get_vim_env(void) /* First get $VIMRUNTIME. If it's set, remove the tail. */ vim = getenv("VIMRUNTIME"); - if (vim != NULL && *vim != 0 && strlen(vim) < BUFSIZE) + if (vim != NULL && *vim != 0 && strlen(vim) < sizeof(buf)) { strcpy(buf, vim); remove_tail(buf); @@ -411,7 +411,7 @@ get_vim_env(void) /* NSIS also uses GetTempPath(), thus we should get the same directory * name as where NSIS will look for vimini.ini. */ - GetTempPath(BUFSIZE, fname); + GetTempPath(sizeof(fname) - 12, fname); add_pathsep(fname); strcat(fname, "vimini.ini"); @@ -456,7 +456,7 @@ window_cb(HWND hwnd, LPARAM lparam) static int run_silent_uninstall(char *uninst_exe) { - char vimrt_dir[MAX_PATH]; + char vimrt_dir[BUFSIZE]; char temp_uninst[BUFSIZE]; char temp_dir[MAX_PATH]; char buf[BUFSIZE * 2 + 10]; @@ -506,7 +506,7 @@ uninstall_check(int skip_question) char *uninstall_key = "software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; char subkey_name_buff[BUFSIZE]; char temp_string_buffer[BUFSIZE-2]; - DWORD local_bufsize = BUFSIZE; + DWORD local_bufsize; FILETIME temp_pfiletime; DWORD key_index; char input; @@ -521,12 +521,14 @@ uninstall_check(int skip_question) KEY_WOW64_64KEY | KEY_READ, &key_handle); CHECK_REG_ERROR(code); - for (key_index = 0; - RegEnumKeyEx(key_handle, key_index, subkey_name_buff, &local_bufsize, - NULL, NULL, NULL, &temp_pfiletime) != ERROR_NO_MORE_ITEMS; - key_index++) + key_index = 0; + while (TRUE) { - local_bufsize = BUFSIZE; + local_bufsize = sizeof(subkey_name_buff); + if (RegEnumKeyEx(key_handle, key_index, subkey_name_buff, &local_bufsize, + NULL, NULL, NULL, &temp_pfiletime) == ERROR_NO_MORE_ITEMS) + break; + if (strncmp("Vim", subkey_name_buff, 3) == 0) { /* Open the key named Vim* */ @@ -535,10 +537,10 @@ uninstall_check(int skip_question) CHECK_REG_ERROR(code); /* get the DisplayName out of it to show the user */ + local_bufsize = sizeof(temp_string_buffer); code = RegQueryValueEx(uninstall_key_handle, "displayname", 0, &value_type, (LPBYTE)temp_string_buffer, &local_bufsize); - local_bufsize = BUFSIZE; CHECK_REG_ERROR(code); allow_silent = 0; @@ -568,9 +570,9 @@ uninstall_check(int skip_question) fflush(stdout); /* get the UninstallString */ + local_bufsize = sizeof(temp_string_buffer); code = RegQueryValueEx(uninstall_key_handle, "uninstallstring", 0, &value_type, (LPBYTE)temp_string_buffer, &local_bufsize); - local_bufsize = BUFSIZE; CHECK_REG_ERROR(code); /* Remember the directory, it is used as the default for NSIS. */ @@ -683,6 +685,8 @@ uninstall_check(int skip_question) RegCloseKey(uninstall_key_handle); } + + key_index++; } RegCloseKey(key_handle); @@ -1826,7 +1830,7 @@ create_shortcut( /* translate the (possibly) multibyte shortcut filename to windows * Unicode so it can be used as a file name. */ - MultiByteToWideChar(CP_ACP, 0, shortcut_name, -1, wsz, BUFSIZE); + MultiByteToWideChar(CP_ACP, 0, shortcut_name, -1, wsz, sizeof(wsz)/sizeof(wsz[0])); /* set the attributes */ shelllink_ptr->lpVtbl->SetPath(shelllink_ptr, shortcut_target); @@ -2135,7 +2139,7 @@ install_OLE_register(void) * result in "to[]". */ static void -dir_remove_last(const char *path, char to[BUFSIZE]) +dir_remove_last(const char *path, char to[MAX_PATH]) { char c; long last_char_to_copy; @@ -2206,7 +2210,7 @@ init_homedir(void) if (homepath == NULL || *homepath == NUL) homepath = "\\"; if (homedrive != NULL - && strlen(homedrive) + strlen(homepath) < MAX_PATH) + && strlen(homedrive) + strlen(homepath) < sizeof(buf)) { sprintf(buf, "%s%s", homedrive, homepath); if (buf[0] != NUL) @@ -2234,10 +2238,9 @@ init_homedir(void) buf[p - (var + 1)] = NUL; exp = getenv(buf); if (exp != NULL && *exp != NUL - && strlen(exp) + strlen(p) < MAX_PATH) + && strlen(exp) + strlen(p) < sizeof(buf)) { - _snprintf(buf, MAX_PATH, "%s%s", exp, p + 1); - buf[MAX_PATH - 1] = NUL; + sprintf(buf, "%s%s", exp, p + 1); var = buf; } } @@ -2351,10 +2354,11 @@ init_directories_choice(void) // Check if the "compiler" directory already exists. That's a good // indication that the plugin directories were already created. - if (getenv("HOME") != NULL) + p = getenv("HOME"); + if (p != NULL) { vimfiles_dir_choice = (int)vimfiles_dir_home; - sprintf(tmp_dirname, "%s\\vimfiles\\compiler", getenv("HOME")); + sprintf(tmp_dirname, "%s\\vimfiles\\compiler", p); if (stat(tmp_dirname, &st) == 0) vimfiles_dir_choice = (int)vimfiles_dir_none; } diff --git a/src/dosinst.h b/src/dosinst.h --- a/src/dosinst.h +++ b/src/dosinst.h @@ -59,7 +59,7 @@ char *searchpath(char *name); /* ---------------------------------------- */ -#define BUFSIZE 512 /* long enough to hold a file name path */ +#define BUFSIZE (MAX_PATH*2) /* long enough to hold a file name path */ #define NUL 0 #define FAIL 0 @@ -93,15 +93,15 @@ int interactive; /* non-zero when runni static void * alloc(int len) { - char *s; + void *p; - s = malloc(len); - if (s == NULL) + p = malloc(len); + if (p == NULL) { printf("ERROR: out of memory\n"); exit(1); } - return (void *)s; + return p; } /* @@ -512,7 +512,7 @@ char *sysdrive; /* system drive or "c:\ do_inits(char **argv) { /* Find out the full path of our executable. */ - if (my_fullpath(installdir, argv[0], BUFSIZE) == NULL) + if (my_fullpath(installdir, argv[0], sizeof(installdir)) == NULL) { printf("ERROR: Cannot get name of executable\n"); myexit(1); diff --git a/src/uninstal.c b/src/uninstal.c --- a/src/uninstal.c +++ b/src/uninstal.c @@ -60,11 +60,10 @@ reg_delete_key(HKEY hRootKey, const char * Returns non-zero when it's found. */ static int -popup_gvim_path(char *buf) +popup_gvim_path(char *buf, DWORD bufsize) { HKEY key_handle; DWORD value_type; - DWORD bufsize = BUFSIZE; int r; /* Open the key where the path to gvim.exe is stored. */ @@ -87,11 +86,10 @@ popup_gvim_path(char *buf) * Returns non-zero when it's found. */ static int -openwith_gvim_path(char *buf) +openwith_gvim_path(char *buf, DWORD bufsize) { HKEY key_handle; DWORD value_type; - DWORD bufsize = BUFSIZE; int r; /* Open the key where the path to gvim.exe is stored. */ @@ -209,7 +207,7 @@ batfile_thisversion(char *path) fd = fopen(path, "r"); if (fd != NULL) { - while (fgets(line, BUFSIZE, fd) != NULL) + while (fgets(line, sizeof(line), fd) != NULL) { for (p = line; *p != 0; ++p) /* don't accept "vim60an" when looking for "vim60". */ @@ -335,7 +333,7 @@ main(int argc, char *argv[]) printf("This program will remove the following items:\n"); - if (popup_gvim_path(popup_path)) + if (popup_gvim_path(popup_path, sizeof(popup_path))) { printf(" - the \"Edit with Vim\" entry in the popup menu\n"); printf(" which uses \"%s\"\n", popup_path); @@ -349,7 +347,7 @@ main(int argc, char *argv[]) remove_openwith(); } } - else if (openwith_gvim_path(popup_path)) + else if (openwith_gvim_path(popup_path, sizeof(popup_path))) { printf(" - the Vim \"Open With...\" entry in the popup menu\n"); printf(" which uses \"%s\"\n", popup_path); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -780,6 +780,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 976, +/**/ 975, /**/ 974,