sammccall added a comment.

In D92155#2419346 <https://reviews.llvm.org/D92155#2419346>, @psionic12 wrote:

>> clangd (and other clang tools) get deployed in environments where all access 
>> to the filesystem goes through a llvm::vfs::Filesystem, and all filenames 
>> referred to in the compile command are within that virtual filesystem rather 
>> than the real one.
>> (Again, this isn't an issue if we require these paths to be specified on the 
>> *clangd* startup command line, as opposed to the clang flags that form the 
>> compile command)
>
> Yes I know how clang manager files through vfs, it just that loading 
> libraries does not involve vfs at all, the path of a lib is passed directly 
> to the system level API (eg, dlopen on Linux, System::Load on Windows), so I 
> still can't understand what you are concerning,

This is exactly the problem, filenames specified in *clang* flags are 
*supposed* to be read from the VFS. (In practice this probably just means we'd 
need to disable this feature in environments where VFS is used)

> Or, could you help to point out what's the difference between passing a 
> plugin path through *clangd* startup command line and through clang flags?

Sure. TL;DR is: clangd flags are configured by the user, user can be fully 
responsible for security/stability.
clang flags are configured by the project. If they're bad, we can e.g. give bad 
diagnostics, but can't crash or compromise security.

More detail:

In the simplest possible case, clangd is configured as follows:

1. user downloads clangd binary
2. user installs an LSP plugin for their editor, and configures the plugin to 
use /usr/bin/clangd for C++ files. clangd starts when the editor does
3. the build system for $PROJECT generates $PROJECT/compile_commands.json
4. when the user opens $PROJECT/src/foo.cpp in the editor, it notifies clangd. 
clangd searches for $PROJECT/compile_commands.json, finds the clang arguments, 
and uses them to parse foo.cpp

*clangd* command-line flags would be added explicitly by the user at step 2. We 
can reasonably ask the user to be aware/responsible for security/stability 
implications of doing this, including with their particular clangd version. We 
can also ask them to run `clangd --check` without the plugin flag to test 
whether the plugin is causing a stability problem.

*clang* command-line flags are added implicitly in step 3. Or they could simply 
be checked into the repository - nothing ensures they were generated locally by 
the build system. The point is in typical usage they are not controlled by the 
user directly, and from a security perspective are not trusted (as safely 
opening files from untrusted repos is a reasonable expectation). So if we're 
loading plugins based on instructions in clang command-line flags, clangd bears 
most of the responsibility for making sure that's safe and correct (and I don't 
see a way to do that).



================
Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3905
+    std::string Error;
+    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), 
&Error))
+      Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error;
----------------
psionic12 wrote:
> sammccall wrote:
> > psionic12 wrote:
> > > sammccall wrote:
> > > > is this threadsafe on all platforms?
> > > While I can't tell, clang driver use this for a while and seems no 
> > > problem, could you help to point out what's the worst case your concerned 
> > > about?
> > clang-driver isn't multithreaded, so wouldn't show up problems here.
> > 
> > I'm concerned that if thread A loads plugin X, thread B loads plugin X, and 
> > thread C loads plugin Y, all concurrently and using this code path, whether 
> > they will all load correctly.
> > 
> > In clangd these threads could correspond to two open files and a 
> > background-index worker.
> > 
> > (I don't know much about dynamic loading, this may be totally fine)
> In this case I can make sure multiple thread works just fine with 
> `LoadLibraryPermanently`, I checked all the dynamic loading API on most 
> platforms and all of the are thread-safe(it's rare to see system APIs which 
> are not thread safe, to me).
That sounds good! I do see mutexes in the posix implementation so I guess the 
LLVM wrapper is intended to be threadsafe.


================
Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3914
+    if (P->getActionType() == PluginASTAction::ReplaceAction) {
+      Res.getFrontendOpts().ProgramAction = clang::frontend::PluginAction;
+      Res.getFrontendOpts().ActionName = Plugin.getName().str();
----------------
psionic12 wrote:
> sammccall wrote:
> > psionic12 wrote:
> > > sammccall wrote:
> > > > we can't support replacement of the main action in clangd. What's the 
> > > > plan there - ignore the plugin?
> > > Could you help to explain why action replacements are not supported? 
> > > 
> > > As far as I know, replacement of actions is related with Actions, which 
> > > does not have directly relationship with clangd,
> > Clangd uses some custom FrontendActions (different ones for different ways 
> > we're parsing the file) to implement its features (e.g. track which parts 
> > of the AST are part of the main-file without deserializing the preamble, 
> > and to do indexing).
> > If you replace these actions, normal features will not work.
> > 
> > e.g.:
> > - 
> > https://github.com/llvm/llvm-project/blob/4df8efce80e373dd1e05bd4910c796a0c91383e7/clang-tools-extra/clangd/ParsedAST.cpp#L97
> > - 
> > https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clangd/index/IndexAction.cpp#L206
> > 
> > If we replace these with the plugin's action, clangd won't work 
> I think this is the part I didn't expected, seems a standalone action loading 
> logic needs to exist.
> 
> I'll try to come up a patch which has standalone plugin loading and guard it 
> with experimental checking.
It seems plugins can run before/after/replace the main action.

I wonder if it'd break things to silently "promote" a replace plugin to e.g. an 
after one, which I guess would solve this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92155/new/

https://reviews.llvm.org/D92155

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to