summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK.Takata <kentkt@csc.jp>2022-02-12 11:18:37 +0000
committerBram Moolenaar <Bram@vim.org>2022-02-12 11:18:37 +0000
commitd68b2fc034fa3c824e0d4d53745cfe9eb8c5ecd6 (patch)
tree8e4c621d0b2d4ea58df053cb0a1432c91d502390
parent18f7593e57730e6de7c2cf47c87e44252cfbb61e (diff)
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.c79
-rw-r--r--src/evalfunc.c6
-rw-r--r--src/gui_dwrite.cpp6
-rw-r--r--src/if_cscope.c3
-rw-r--r--src/os_win32.c7
-rw-r--r--src/proto/crypt.pro1
-rw-r--r--src/proto/os_win32.pro2
-rw-r--r--src/version.c6
8 files changed, 79 insertions, 31 deletions
diff --git a/src/crypt.c b/src/crypt.c
index e5d0d9167b..d66e50cc48 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 db0d1ceedb..31205ea5ae 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 83acdab1ad..62d23e7277 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 f8d4dc6df2..f373952dd8 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 682fdf2bcf..fbf666598f 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 682fe4533b..d6c7b7ffde 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 dac2b7142f..b3c85b7183 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 8919e59e41..2476818eb5 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,