summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2021-12-14 09:29:06 +0100
committerLars Ingebrigtsen <larsi@gnus.org>2021-12-14 09:29:13 +0100
commit8c0f9be0d1ace6437d4c604b9af79b7b0006dec4 (patch)
treeb664ec843fc4c1f420812023edd9eaa160e312a2 /src
parentb8e6beaab01e9c7eaf5cdc12a34987402fb9b72f (diff)
downloademacs-8c0f9be0d1ace6437d4c604b9af79b7b0006dec4.tar.gz
Only allow SQLite extensions from an allowlist
* src/sqlite.c (Fsqlite_load_extension): Only allow extensions from an allowlist.
Diffstat (limited to 'src')
-rw-r--r--src/sqlite.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/sqlite.c b/src/sqlite.c
index 248ad478d57..428b84b21e7 100644
--- a/src/sqlite.c
+++ b/src/sqlite.c
@@ -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;