Only allow SQLite extensions from an allowlist

* src/sqlite.c (Fsqlite_load_extension): Only allow extensions
from an allowlist.
This commit is contained in:
Lars Ingebrigtsen 2021-12-14 09:29:06 +01:00
parent b8e6beaab0
commit 8c0f9be0d1
2 changed files with 63 additions and 5 deletions

View file

@ -591,16 +591,42 @@ DEFUN ("sqlite-load-extension", Fsqlite_load_extension,
doc: /* Load an SQlite MODULE into DB.
MODULE should be the name of an SQlite module's file, a
shared library in the system-dependent format and having a
system-dependent file-name extension. */)
system-dependent file-name extension.
Only modules on Emacs' list of allowed modules can be loaded. */)
(Lisp_Object db, Lisp_Object module)
{
check_sqlite (db, false);
CHECK_STRING (module);
Lisp_Object module_encoded = ENCODE_FILE (Fexpand_file_name (module, Qnil));
sqlite3 *sdb = XSQLITE (db)->db;
int result = sqlite3_load_extension (sdb, SSDATA (module_encoded),
NULL, NULL);
/* Add names of useful and free modules here. */
const char *allowlist[3] = { "pcre", "csvtable", NULL };
char *name = SSDATA (Ffile_name_nondirectory (module));
/* Possibly skip past a common prefix. */
const char *prefix = "libsqlite3_mod_";
if (!strncmp (name, prefix, strlen (prefix)))
name += strlen (prefix);
bool do_allow = false;
for (const char **allow = allowlist; *allow; allow++)
{
if (strlen (*allow) < strlen (name)
&& !strncmp (*allow, name, strlen (*allow))
&& (!strcmp (name + strlen (*allow), ".so")
|| !strcmp (name + strlen (*allow), ".DLL")))
{
do_allow = true;
break;
}
}
if (!do_allow)
xsignal (Qerror, build_string ("Module name not on allowlist"));
int result = sqlite3_load_extension
(XSQLITE (db)->db,
SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))),
NULL, NULL);
if (result == SQLITE_OK)
return Qt;
return Qnil;

View file

@ -182,4 +182,36 @@
(sqlite-close db)
(should-error (sqlite-select db "select * from test6"))))
(ert-deftest sqlite-load-extension ()
(skip-unless (sqlite-available-p))
(let (db)
(setq db (sqlite-open))
(should-error
(sqlite-load-extension db "/usr/lib/sqlite3/notpcre.so"))
(should-error
(sqlite-load-extension db "/usr/lib/sqlite3/n"))
(should-error
(sqlite-load-extension db "/usr/lib/sqlite3/"))
(should-error
(sqlite-load-extension db "/usr/lib/sqlite3"))
(should
(memq
(sqlite-load-extension db "/usr/lib/sqlite3/pcre.so")
'(nil t)))
(should-error
(sqlite-load-extension
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_notcsvtable.so"))
(should-error
(sqlite-load-extension
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtablen.so"))
(should-error
(sqlite-load-extension
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable"))
(should
(memq
(sqlite-load-extension
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")
'(nil t)))))
;;; sqlite-tests.el ends here