diff options
author | K.Takata <kentkt@csc.jp> | 2022-02-12 11:18:37 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-02-12 11:18:37 +0000 |
commit | d68b2fc034fa3c824e0d4d53745cfe9eb8c5ecd6 (patch) | |
tree | 8e4c621d0b2d4ea58df053cb0a1432c91d502390 | |
parent | 18f7593e57730e6de7c2cf47c87e44252cfbb61e (diff) | |
download | vim-git-d68b2fc034fa3c824e0d4d53745cfe9eb8c5ecd6.tar.gz |
patch 8.2.4354: dynamic loading of libsodium not handled properlyv8.2.4354
Problem: Dynamic loading of libsodium not handled properly.
Solution: Fix has() and :version. Show an error message when loading fails.
Fix memory leaks. (Ken Takata, closes #9754)
-rw-r--r-- | src/crypt.c | 79 | ||||
-rw-r--r-- | src/evalfunc.c | 6 | ||||
-rw-r--r-- | src/gui_dwrite.cpp | 6 | ||||
-rw-r--r-- | src/if_cscope.c | 3 | ||||
-rw-r--r-- | src/os_win32.c | 7 | ||||
-rw-r--r-- | src/proto/crypt.pro | 1 | ||||
-rw-r--r-- | src/proto/os_win32.pro | 2 | ||||
-rw-r--r-- | src/version.c | 6 |
8 files changed, 79 insertions, 31 deletions
diff --git a/src/crypt.c b/src/crypt.c index e5d0d9167..d66e50cc4 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -162,6 +162,22 @@ typedef struct { # ifdef DYNAMIC_SODIUM +# ifdef MSWIN +# define SODIUM_PROC FARPROC +# define load_dll vimLoadLib +# define symbol_from_dll GetProcAddress +# define close_dll FreeLibrary +# define load_dll_error GetWin32Error +# else +# error Dynamic loading of libsodium is not supported for now. +//# define HINSTANCE void* +//# define SODIUM_PROC void* +//# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL) +//# define symbol_from_dll dlsym +//# define close_dll dlclose +//# define load_dll_error dlerror +# endif + # define sodium_init load_sodium # define sodium_free dll_sodium_free # define sodium_malloc dll_sodium_malloc @@ -214,53 +230,72 @@ static void (*dll_randombytes_buf)(void * const buf, const size_t size); static struct { const char *name; - FARPROC *ptr; + SODIUM_PROC *ptr; } sodium_funcname_table[] = { - {"sodium_init", (FARPROC*)&dll_sodium_init}, - {"sodium_free", (FARPROC*)&dll_sodium_free}, - {"sodium_malloc", (FARPROC*)&dll_sodium_malloc}, - {"sodium_memzero", (FARPROC*)&dll_sodium_memzero}, - {"sodium_mlock", (FARPROC*)&dll_sodium_mlock}, - {"sodium_munlock", (FARPROC*)&dll_sodium_munlock}, - {"crypto_secretstream_xchacha20poly1305_init_push", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_init_push}, - {"crypto_secretstream_xchacha20poly1305_push", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_push}, - {"crypto_secretstream_xchacha20poly1305_init_pull", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_init_pull}, - {"crypto_secretstream_xchacha20poly1305_pull", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_pull}, - {"crypto_pwhash", (FARPROC*)&dll_crypto_pwhash}, - {"randombytes_buf", (FARPROC*)&dll_randombytes_buf}, + {"sodium_init", (SODIUM_PROC*)&dll_sodium_init}, + {"sodium_free", (SODIUM_PROC*)&dll_sodium_free}, + {"sodium_malloc", (SODIUM_PROC*)&dll_sodium_malloc}, + {"sodium_memzero", (SODIUM_PROC*)&dll_sodium_memzero}, + {"sodium_mlock", (SODIUM_PROC*)&dll_sodium_mlock}, + {"sodium_munlock", (SODIUM_PROC*)&dll_sodium_munlock}, + {"crypto_secretstream_xchacha20poly1305_init_push", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_init_push}, + {"crypto_secretstream_xchacha20poly1305_push", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_push}, + {"crypto_secretstream_xchacha20poly1305_init_pull", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_init_pull}, + {"crypto_secretstream_xchacha20poly1305_pull", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_pull}, + {"crypto_pwhash", (SODIUM_PROC*)&dll_crypto_pwhash}, + {"randombytes_buf", (SODIUM_PROC*)&dll_randombytes_buf}, {NULL, NULL} }; static int -load_sodium(void) +sodium_runtime_link_init(int verbose) { - static HANDLE hsodium = NULL; + static HINSTANCE hsodium = NULL; + const char *libname = "libsodium.dll"; int i; if (hsodium != NULL) - return 0; + return OK; - hsodium = vimLoadLib("libsodium.dll"); + hsodium = load_dll(libname); if (hsodium == NULL) { - // TODO: Show error message. - return -1; + if (verbose) + semsg(_(e_could_not_load_library_str_str), libname, load_dll_error()); + return FAIL; } for (i = 0; sodium_funcname_table[i].ptr; ++i) { - if ((*sodium_funcname_table[i].ptr = GetProcAddress(hsodium, + if ((*sodium_funcname_table[i].ptr = symbol_from_dll(hsodium, sodium_funcname_table[i].name)) == NULL) { FreeLibrary(hsodium); hsodium = NULL; - // TODO: Show error message. - return -1; + if (verbose) + semsg(_(e_could_not_load_library_function_str), sodium_funcname_table[i].name); + return FAIL; } } + return OK; +} + + static int +load_sodium(void) +{ + if (sodium_runtime_link_init(TRUE) == FAIL) + return -1; return dll_sodium_init(); } # endif + +# if defined(DYNAMIC_SODIUM) || defined(PROTO) + int +sodium_enabled(int verbose) +{ + return sodium_runtime_link_init(verbose) == OK; +} +# endif #endif #define CRYPT_MAGIC_LEN 12 // cannot change diff --git a/src/evalfunc.c b/src/evalfunc.c index db0d1ceed..31205ea5a 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -5997,7 +5997,7 @@ f_has(typval_T *argvars, typval_T *rettv) #endif }, {"sodium", -#ifdef FEAT_SODIUM +#if defined(FEAT_SODIUM) && !defined(DYNAMIC_SODIUM) 1 #else 0 @@ -6318,6 +6318,10 @@ f_has(typval_T *argvars, typval_T *rettv) else if (STRICMP(name, "tcl") == 0) n = tcl_enabled(FALSE); #endif +#ifdef DYNAMIC_SODIUM + else if (STRICMP(name, "sodium") == 0) + n = sodium_enabled(FALSE); +#endif #if defined(FEAT_TERMINAL) && defined(MSWIN) else if (STRICMP(name, "terminal") == 0) n = terminal_enabled(); diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp index 83acdab1a..62d23e727 100644 --- a/src/gui_dwrite.cpp +++ b/src/gui_dwrite.cpp @@ -59,7 +59,7 @@ #endif #ifdef DYNAMIC_DIRECTX -extern "C" HINSTANCE vimLoadLib(char *name); +extern "C" HINSTANCE vimLoadLib(const char *name); typedef int (WINAPI *PGETUSERDEFAULTLOCALENAME)(LPWSTR, int); typedef HRESULT (WINAPI *PD2D1CREATEFACTORY)(D2D1_FACTORY_TYPE, @@ -1212,8 +1212,8 @@ DWrite_Init(void) { #ifdef DYNAMIC_DIRECTX // Load libraries. - hD2D1DLL = vimLoadLib(const_cast<char*>("d2d1.dll")); - hDWriteDLL = vimLoadLib(const_cast<char*>("dwrite.dll")); + hD2D1DLL = vimLoadLib("d2d1.dll"); + hDWriteDLL = vimLoadLib("dwrite.dll"); if (hD2D1DLL == NULL || hDWriteDLL == NULL) { DWrite_Final(); diff --git a/src/if_cscope.c b/src/if_cscope.c index f8d4dc6df..f373952dd 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -1371,10 +1371,7 @@ cs_insert_filelist( char *winmsg = GetWin32Error(); if (winmsg != NULL) - { (void)semsg(cant_msg, winmsg); - LocalFree(winmsg); - } else // subst filename if can't get error text (void)semsg(cant_msg, fname); diff --git a/src/os_win32.c b/src/os_win32.c index 682fdf2bc..fbf666598 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -520,7 +520,7 @@ unescape_shellxquote(char_u *p, char_u *escaped) * Load library "name". */ HINSTANCE -vimLoadLib(char *name) +vimLoadLib(const char *name) { HINSTANCE dll = NULL; @@ -8279,15 +8279,20 @@ resize_console_buf(void) char * GetWin32Error(void) { + static char *oldmsg = NULL; char *msg = NULL; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, (LPSTR)&msg, 0, NULL); + if (oldmsg != NULL) + LocalFree(oldmsg); if (msg != NULL) { // remove trailing \r\n char *pcrlf = strstr(msg, "\r\n"); if (pcrlf != NULL) *pcrlf = '\0'; + oldmsg = msg; } return msg; } diff --git a/src/proto/crypt.pro b/src/proto/crypt.pro index 682fe4533..d6c7b7ffd 100644 --- a/src/proto/crypt.pro +++ b/src/proto/crypt.pro @@ -1,4 +1,5 @@ /* crypt.c */ +int sodium_enabled(int verbose); int crypt_method_nr_from_name(char_u *name); int crypt_method_nr_from_magic(char *ptr, int len); int crypt_works_inplace(cryptstate_T *state); diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro index dac2b7142..b3c85b718 100644 --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -1,5 +1,5 @@ /* os_win32.c */ -HINSTANCE vimLoadLib(char *name); +HINSTANCE vimLoadLib(const char *name); int mch_is_gui_executable(void); HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname); void *get_dll_import_func(HINSTANCE hInst, const char *funcname); diff --git a/src/version.c b/src/version.c index 8919e59e4..2476818eb 100644 --- a/src/version.c +++ b/src/version.c @@ -548,7 +548,11 @@ static char *(features[]) = "-smartindent", #endif #ifdef FEAT_SODIUM +# ifdef DYNAMIC_SODIUM + "+sodium/dyn", +# else "+sodium", +# endif #else "-sodium", #endif @@ -747,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4354, +/**/ 4353, /**/ 4352, |