]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.4354: dynamic loading of libsodium not handled properly v8.2.4354
authorK.Takata <kentkt@csc.jp>
Sat, 12 Feb 2022 11:18:37 +0000 (11:18 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 12 Feb 2022 11:18:37 +0000 (11:18 +0000)
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)

src/crypt.c
src/evalfunc.c
src/gui_dwrite.cpp
src/if_cscope.c
src/os_win32.c
src/proto/crypt.pro
src/proto/os_win32.pro
src/version.c

index e5d0d9167b1a1af879652b16b3da6e3cf7c93ce6..d66e50cc48a8bdb39ade85834a1b4624a2cd2609 100644 (file)
@@ -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
index db0d1ceedbfb67ff2d9cba4eb1e9703abdd080da..31205ea5ae245b850964c5c8a424c8b8b28b9263 100644 (file)
@@ -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();
index 83acdab1ad959647c922ddf70e79178442b532ff..62d23e72773b52fa82876541f2fc2764725de305 100644 (file)
@@ -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();
index f8d4dc6df2d6c6ac87a19800c1f2d1067a88b157..f373952dd890f3f838402a98cc2aa18e50d83e14 100644 (file)
@@ -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);
index 682fdf2bcf1b4e4ba099581387cd9b8cabcb12a0..fbf666598f6a454faa88f86f8b841c33458bd90c 100644 (file)
@@ -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;
 }
index 682fe4533bfcc90f783bf9137cb4c95afcfdf063..d6c7b7ffde906854da496081a6d72c37066ebfa1 100644 (file)
@@ -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);
index dac2b7142fb351b9440eb220715c75d6bcba53f9..b3c85b71830ecb05fb8234530363a1f98e0ab50a 100644 (file)
@@ -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);
index 8919e59e41324902341fd2fe316e856740863550..2476818eb5427d2a8297b77351fbec36bbb365b6 100644 (file)
@@ -548,7 +548,11 @@ static char *(features[]) =
        "-smartindent",
 #endif
 #ifdef FEAT_SODIUM
+# ifdef DYNAMIC_SODIUM
+       "+sodium/dyn",
+# else
        "+sodium",
+# endif
 #else
        "-sodium",
 #endif
@@ -746,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4354,
 /**/
     4353,
 /**/