diff options
| author | Lars Ingebrigtsen | 2021-12-14 09:29:06 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-12-14 09:29:13 +0100 |
| commit | 8c0f9be0d1ace6437d4c604b9af79b7b0006dec4 (patch) | |
| tree | b664ec843fc4c1f420812023edd9eaa160e312a2 /src/sqlite.c | |
| parent | b8e6beaab01e9c7eaf5cdc12a34987402fb9b72f (diff) | |
| download | emacs-8c0f9be0d1ace6437d4c604b9af79b7b0006dec4.tar.gz emacs-8c0f9be0d1ace6437d4c604b9af79b7b0006dec4.zip | |
Only allow SQLite extensions from an allowlist
* src/sqlite.c (Fsqlite_load_extension): Only allow extensions
from an allowlist.
Diffstat (limited to 'src/sqlite.c')
| -rw-r--r-- | src/sqlite.c | 36 |
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, | |||
| 591 | doc: /* Load an SQlite MODULE into DB. | 591 | doc: /* Load an SQlite MODULE into DB. |
| 592 | MODULE should be the name of an SQlite module's file, a | 592 | MODULE should be the name of an SQlite module's file, a |
| 593 | shared library in the system-dependent format and having a | 593 | shared library in the system-dependent format and having a |
| 594 | system-dependent file-name extension. */) | 594 | system-dependent file-name extension. |
| 595 | |||
| 596 | Only modules on Emacs' list of allowed modules can be loaded. */) | ||
| 595 | (Lisp_Object db, Lisp_Object module) | 597 | (Lisp_Object db, Lisp_Object module) |
| 596 | { | 598 | { |
| 597 | check_sqlite (db, false); | 599 | check_sqlite (db, false); |
| 598 | CHECK_STRING (module); | 600 | CHECK_STRING (module); |
| 599 | Lisp_Object module_encoded = ENCODE_FILE (Fexpand_file_name (module, Qnil)); | ||
| 600 | 601 | ||
| 601 | sqlite3 *sdb = XSQLITE (db)->db; | 602 | /* Add names of useful and free modules here. */ |
| 602 | int result = sqlite3_load_extension (sdb, SSDATA (module_encoded), | 603 | const char *allowlist[3] = { "pcre", "csvtable", NULL }; |
| 603 | NULL, NULL); | 604 | char *name = SSDATA (Ffile_name_nondirectory (module)); |
| 605 | /* Possibly skip past a common prefix. */ | ||
| 606 | const char *prefix = "libsqlite3_mod_"; | ||
| 607 | if (!strncmp (name, prefix, strlen (prefix))) | ||
| 608 | name += strlen (prefix); | ||
| 609 | |||
| 610 | bool do_allow = false; | ||
| 611 | for (const char **allow = allowlist; *allow; allow++) | ||
| 612 | { | ||
| 613 | if (strlen (*allow) < strlen (name) | ||
| 614 | && !strncmp (*allow, name, strlen (*allow)) | ||
| 615 | && (!strcmp (name + strlen (*allow), ".so") | ||
| 616 | || !strcmp (name + strlen (*allow), ".DLL"))) | ||
| 617 | { | ||
| 618 | do_allow = true; | ||
| 619 | break; | ||
| 620 | } | ||
| 621 | } | ||
| 622 | |||
| 623 | if (!do_allow) | ||
| 624 | xsignal (Qerror, build_string ("Module name not on allowlist")); | ||
| 625 | |||
| 626 | int result = sqlite3_load_extension | ||
| 627 | (XSQLITE (db)->db, | ||
| 628 | SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))), | ||
| 629 | NULL, NULL); | ||
| 604 | if (result == SQLITE_OK) | 630 | if (result == SQLITE_OK) |
| 605 | return Qt; | 631 | return Qt; |
| 606 | return Qnil; | 632 | return Qnil; |