Skip to content

Commit d68b2fc

Browse files
k-takatabrammool
authored andcommitted
patch 8.2.4354: dynamic loading of libsodium not handled properly
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)
1 parent 18f7593 commit d68b2fc

File tree

8 files changed

+79
-31
lines changed

8 files changed

+79
-31
lines changed

src/crypt.c

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,22 @@ typedef struct {
162162

163163

164164
# ifdef DYNAMIC_SODIUM
165+
# ifdef MSWIN
166+
# define SODIUM_PROC FARPROC
167+
# define load_dll vimLoadLib
168+
# define symbol_from_dll GetProcAddress
169+
# define close_dll FreeLibrary
170+
# define load_dll_error GetWin32Error
171+
# else
172+
# error Dynamic loading of libsodium is not supported for now.
173+
//# define HINSTANCE void*
174+
//# define SODIUM_PROC void*
175+
//# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
176+
//# define symbol_from_dll dlsym
177+
//# define close_dll dlclose
178+
//# define load_dll_error dlerror
179+
# endif
180+
165181
# define sodium_init load_sodium
166182
# define sodium_free dll_sodium_free
167183
# define sodium_malloc dll_sodium_malloc
@@ -214,53 +230,72 @@ static void (*dll_randombytes_buf)(void * const buf, const size_t size);
214230

215231
static struct {
216232
const char *name;
217-
FARPROC *ptr;
233+
SODIUM_PROC *ptr;
218234
} sodium_funcname_table[] = {
219-
{"sodium_init", (FARPROC*)&dll_sodium_init},
220-
{"sodium_free", (FARPROC*)&dll_sodium_free},
221-
{"sodium_malloc", (FARPROC*)&dll_sodium_malloc},
222-
{"sodium_memzero", (FARPROC*)&dll_sodium_memzero},
223-
{"sodium_mlock", (FARPROC*)&dll_sodium_mlock},
224-
{"sodium_munlock", (FARPROC*)&dll_sodium_munlock},
225-
{"crypto_secretstream_xchacha20poly1305_init_push", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_init_push},
226-
{"crypto_secretstream_xchacha20poly1305_push", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_push},
227-
{"crypto_secretstream_xchacha20poly1305_init_pull", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_init_pull},
228-
{"crypto_secretstream_xchacha20poly1305_pull", (FARPROC*)&dll_crypto_secretstream_xchacha20poly1305_pull},
229-
{"crypto_pwhash", (FARPROC*)&dll_crypto_pwhash},
230-
{"randombytes_buf", (FARPROC*)&dll_randombytes_buf},
235+
{"sodium_init", (SODIUM_PROC*)&dll_sodium_init},
236+
{"sodium_free", (SODIUM_PROC*)&dll_sodium_free},
237+
{"sodium_malloc", (SODIUM_PROC*)&dll_sodium_malloc},
238+
{"sodium_memzero", (SODIUM_PROC*)&dll_sodium_memzero},
239+
{"sodium_mlock", (SODIUM_PROC*)&dll_sodium_mlock},
240+
{"sodium_munlock", (SODIUM_PROC*)&dll_sodium_munlock},
241+
{"crypto_secretstream_xchacha20poly1305_init_push", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_init_push},
242+
{"crypto_secretstream_xchacha20poly1305_push", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_push},
243+
{"crypto_secretstream_xchacha20poly1305_init_pull", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_init_pull},
244+
{"crypto_secretstream_xchacha20poly1305_pull", (SODIUM_PROC*)&dll_crypto_secretstream_xchacha20poly1305_pull},
245+
{"crypto_pwhash", (SODIUM_PROC*)&dll_crypto_pwhash},
246+
{"randombytes_buf", (SODIUM_PROC*)&dll_randombytes_buf},
231247
{NULL, NULL}
232248
};
233249

234250
static int
235-
load_sodium(void)
251+
sodium_runtime_link_init(int verbose)
236252
{
237-
static HANDLE hsodium = NULL;
253+
static HINSTANCE hsodium = NULL;
254+
const char *libname = "libsodium.dll";
238255
int i;
239256

240257
if (hsodium != NULL)
241-
return 0;
258+
return OK;
242259

243-
hsodium = vimLoadLib("libsodium.dll");
260+
hsodium = load_dll(libname);
244261
if (hsodium == NULL)
245262
{
246-
// TODO: Show error message.
247-
return -1;
263+
if (verbose)
264+
semsg(_(e_could_not_load_library_str_str), libname, load_dll_error());
265+
return FAIL;
248266
}
249267

250268
for (i = 0; sodium_funcname_table[i].ptr; ++i)
251269
{
252-
if ((*sodium_funcname_table[i].ptr = GetProcAddress(hsodium,
270+
if ((*sodium_funcname_table[i].ptr = symbol_from_dll(hsodium,
253271
sodium_funcname_table[i].name)) == NULL)
254272
{
255273
FreeLibrary(hsodium);
256274
hsodium = NULL;
257-
// TODO: Show error message.
258-
return -1;
275+
if (verbose)
276+
semsg(_(e_could_not_load_library_function_str), sodium_funcname_table[i].name);
277+
return FAIL;
259278
}
260279
}
280+
return OK;
281+
}
282+
283+
static int
284+
load_sodium(void)
285+
{
286+
if (sodium_runtime_link_init(TRUE) == FAIL)
287+
return -1;
261288
return dll_sodium_init();
262289
}
263290
# endif
291+
292+
# if defined(DYNAMIC_SODIUM) || defined(PROTO)
293+
int
294+
sodium_enabled(int verbose)
295+
{
296+
return sodium_runtime_link_init(verbose) == OK;
297+
}
298+
# endif
264299
#endif
265300

266301
#define CRYPT_MAGIC_LEN 12 // cannot change

src/evalfunc.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5997,7 +5997,7 @@ f_has(typval_T *argvars, typval_T *rettv)
59975997
#endif
59985998
},
59995999
{"sodium",
6000-
#ifdef FEAT_SODIUM
6000+
#if defined(FEAT_SODIUM) && !defined(DYNAMIC_SODIUM)
60016001
1
60026002
#else
60036003
0
@@ -6318,6 +6318,10 @@ f_has(typval_T *argvars, typval_T *rettv)
63186318
else if (STRICMP(name, "tcl") == 0)
63196319
n = tcl_enabled(FALSE);
63206320
#endif
6321+
#ifdef DYNAMIC_SODIUM
6322+
else if (STRICMP(name, "sodium") == 0)
6323+
n = sodium_enabled(FALSE);
6324+
#endif
63216325
#if defined(FEAT_TERMINAL) && defined(MSWIN)
63226326
else if (STRICMP(name, "terminal") == 0)
63236327
n = terminal_enabled();

src/gui_dwrite.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
#endif
6060

6161
#ifdef DYNAMIC_DIRECTX
62-
extern "C" HINSTANCE vimLoadLib(char *name);
62+
extern "C" HINSTANCE vimLoadLib(const char *name);
6363

6464
typedef int (WINAPI *PGETUSERDEFAULTLOCALENAME)(LPWSTR, int);
6565
typedef HRESULT (WINAPI *PD2D1CREATEFACTORY)(D2D1_FACTORY_TYPE,
@@ -1212,8 +1212,8 @@ DWrite_Init(void)
12121212
{
12131213
#ifdef DYNAMIC_DIRECTX
12141214
// Load libraries.
1215-
hD2D1DLL = vimLoadLib(const_cast<char*>("d2d1.dll"));
1216-
hDWriteDLL = vimLoadLib(const_cast<char*>("dwrite.dll"));
1215+
hD2D1DLL = vimLoadLib("d2d1.dll");
1216+
hDWriteDLL = vimLoadLib("dwrite.dll");
12171217
if (hD2D1DLL == NULL || hDWriteDLL == NULL)
12181218
{
12191219
DWrite_Final();

src/if_cscope.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,10 +1371,7 @@ cs_insert_filelist(
13711371
char *winmsg = GetWin32Error();
13721372

13731373
if (winmsg != NULL)
1374-
{
13751374
(void)semsg(cant_msg, winmsg);
1376-
LocalFree(winmsg);
1377-
}
13781375
else
13791376
// subst filename if can't get error text
13801377
(void)semsg(cant_msg, fname);

src/os_win32.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ unescape_shellxquote(char_u *p, char_u *escaped)
520520
* Load library "name".
521521
*/
522522
HINSTANCE
523-
vimLoadLib(char *name)
523+
vimLoadLib(const char *name)
524524
{
525525
HINSTANCE dll = NULL;
526526

@@ -8279,15 +8279,20 @@ resize_console_buf(void)
82798279
char *
82808280
GetWin32Error(void)
82818281
{
8282+
static char *oldmsg = NULL;
82828283
char *msg = NULL;
8284+
82838285
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
82848286
NULL, GetLastError(), 0, (LPSTR)&msg, 0, NULL);
8287+
if (oldmsg != NULL)
8288+
LocalFree(oldmsg);
82858289
if (msg != NULL)
82868290
{
82878291
// remove trailing \r\n
82888292
char *pcrlf = strstr(msg, "\r\n");
82898293
if (pcrlf != NULL)
82908294
*pcrlf = '\0';
8295+
oldmsg = msg;
82918296
}
82928297
return msg;
82938298
}

src/proto/crypt.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* crypt.c */
2+
int sodium_enabled(int verbose);
23
int crypt_method_nr_from_name(char_u *name);
34
int crypt_method_nr_from_magic(char *ptr, int len);
45
int crypt_works_inplace(cryptstate_T *state);

src/proto/os_win32.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* os_win32.c */
2-
HINSTANCE vimLoadLib(char *name);
2+
HINSTANCE vimLoadLib(const char *name);
33
int mch_is_gui_executable(void);
44
HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname);
55
void *get_dll_import_func(HINSTANCE hInst, const char *funcname);

src/version.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,11 @@ static char *(features[]) =
548548
"-smartindent",
549549
#endif
550550
#ifdef FEAT_SODIUM
551+
# ifdef DYNAMIC_SODIUM
552+
"+sodium/dyn",
553+
# else
551554
"+sodium",
555+
# endif
552556
#else
553557
"-sodium",
554558
#endif
@@ -746,6 +750,8 @@ static char *(features[]) =
746750

747751
static int included_patches[] =
748752
{ /* Add new patch number below this line */
753+
/**/
754+
4354,
749755
/**/
750756
4353,
751757
/**/

0 commit comments

Comments
 (0)