简体   繁体   中英

How can I secure the plugins I load?

Let's say my piece of code scans the directory ./plugins and loads .dll s/ .so s with a known symbol ("function" here) in order to extend its functionnality, like this:

main.c

 #include <stdlib.h> #include <dirent.h> #include <string.h> #include <stdio.h> #include <dlfcn.h> int main(void) { DIR *dir; struct dirent *entry; dir = opendir("./plugins"); if (dir == NULL) return -1; while ((entry = readdir(dir)) != NULL) { void *handle; char path[PATH_MAX]; int (*function)(char *); if (strstr(entry->d_name, ".so") == NULL) continue; if (snprintf(path, sizeof(path), "./%s", entry->d_name) >= sizeof(path)) continue; handle = dlopen(path, RTLD_LAZY); if (handle == NULL) continue; // Better: report the error with `dlerror()' function = (int (*)(char *)) dlsym(handle, "function"); if (function != NULL) fprintf(stdout, "function: %d\\n", function("example")); else fprintf(stderr, "symbol-not-found: %s\\n", entry->d_name); dlclose(handle); } closedir(dir); return 0; } 

This could lead to a major security issue : If my application runs as root, or has admin privileges, that means any unprivileged attacker can execute code as a privileged user by producing a shared object containing a function named as the known symbol (here, function ).

What can I do to secure my plugins folder? How can I check if the shared objects I load are secure?

This is a follow-up of this question .

The only thing you can do in this case is to only allow a privileged user to write files in the plugin directory.

The moment you call dlopen on an unknown file you have already lost. Notice that you don't even need to call a function from it, a call to dlopen is enough since the shared object can have constructors that will be run automatically wether you want it or not.

You can't check if the shared objects are secure. To do that would be equivalent to solving the halting problem.

I believe you cannot secure your plugin in the general case. A malicious user could do arbitrary things in its plugin (including emitting some C code at runtime then forking a compilation of it and dlopen -ing, JIT compiling machine code in memory, etc...). Remember that dlopen -ed (or mmap -ed) plugins are sharing the virtual address space of the process running their loading program.

My MELT [meta-] plugin for the GCC compiler is doing exactly that: generating C or C++ code at runtime, compiling it on the fly, dlopen -ing it. But it is not malicious.

Notice that (as answered by Art ), dlopen(3) is running arbitrary initialization plugin code ( before you do any dlsym to retrieve a function from its "function" name). Read about __attribute__((constructor)) in GCC .

If you are extremely ambitious (years of work, worth a PhD...) you might generate the code of the plugin while doing some code proof or sound static analysis on it.

(Since you are like me near Paris, France, look into the works of Xavier Leroy -INRIA- eg CompCert , Emmanuel Chailloux -LIP6-, Julia Lavall & Coccinelle -LIP6-; read also about Frama-C & GCC MELT ; but understand that there is no silver bullet ....; you could send me an email mentioning the URL of your question)

Read also about the halting problem , Rice's theorem , trusted computing base and proof-carrying code . Your request is undecidable or at least intractable .

You could consider some dual approach: have a trusted procedure to "sign" or "stamp" good plugins (so the sysadmin is in charge of telling that such and such plugin is good), and only dlopen a plugin when it has been "certified" or simply "human-approved" somehow. Perhaps as simple as keeping a (trusted and safe) database or text association between trusted plugin names and their md5 signatures, and computing the checksum then checking that before the dlopen ...

A good heuristic when programming is to ask very often to oneself: Am I trying to solve the halting problem? J.Pitrat's blog has interesting insights....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM