On 8/3/26 21:40, ski n wrote:
[...]
This library however isn't really a sandbox, but works more with
intecepton, than really with isolation. Though you can use blacklisting/
whitelisting approaches, but those are not long term solutions.
I think better solutions have already been proposed here.
To add to this information, Gilles Duboscq, researcher at Oracle writese:
"For JVM languages there is Espresso <https://www.graalvm.org/latest/
reference-manual/espresso/> which is a Truffle implementation of the JVM.
Sandboxing it presents some challenges though, especially around native
code: by default espresso uses the standard java and native code of
OpenJDK for its standard library.
To truly sandbox espresso, this native should either itself be sandboxed
or not used as all and Truffle APIs used instead.
We did some experiments in that direction already though, with a "no-
native" mode that can already run some simple workloads.
Combining this with Polyglot Isolates could be a path forward for using
this sandboxing with JVM languages."
All of our Groovy are dynamically run, so we use JIT, but native is also
something to consider.
Paul is currently trying to improve the usage as Groovy for native
compilation.
I spend some time looking at Espresso and found a few things that are
insteresting.
* Espresso and probably Truffel itself has a notion of host code and
guest code.
* Espresso replaces a lot of JDK calls in the guest with its own code.
This is done using substitutions, not by modifying the JDK
* Espresso builds it list of substitutions at build time of Espresso
* guest code can not and is not supposed to influence that mechanism
And for Groovy as guest going the way of substitutions this concludes to
Groovy would have to be extending Espresso with Substitutions in
Espresso itself, registering them at build time of Espresso.
So unless we essentially form Espresso or make a Groovy variant of
Espresso in which we add our own Substitutions this would not work.
Though I do think it would be possible to do this. In the end I think we
would have to change the bytecode of the SubstitutionsCollector, which
is a generated class. Licensing could become an issue, though.
The question is what we would even achieve? All method call operations,
including the invokedynamic we use could be replaced at runtime with
Espresso/Truffle logic and nodes. Espresso even replaces calls to native
methods. Then any runtime compiled or precompiled Groovy program/script
run as guest would be affected. Essentially that is the Jenkins idea,
just on a different level.
What this solution would not be able is of course to limit VM parameters
like memory consumption. The guest can be seen as running in a
lightweight JVM, which is the one that would have to be restricted from
using too much CPU/Memory.
And while the Espresso approach would be a more complete solution then
the Jenkins idea it made me think that we probably have everything we
need to achieve something similar. Almost all significant calls go
through out invokedynamic mechanism, which means there is a central
method, that is called to provide the JIT with a MethodHandles graph,
used to actually do the method execution. That method is called a
bootstrap method (just explaining for people that have no idea how
invokedynamic works). The logic behind the bootstrap method is a runtime
implementation detail and changing this would not require changes to
Groovy code. We could then in theory implement some kind of
restrictions. Currently supported would be method calls, property get,
and extended casts.
But it does not solve all cases, not even all cases of method calls.
Static compilation bypasses this. AST Transforms could add bytecode that
implements normal method calls (that is part of what static compilation
does) and thus bypass this. Library code is not under our control with
this, unless it is written in Groovy. If you somehow manage to spawn a
Groovy in Groovy (technically possible with some class loader magic) you
could probably bypass this. Even if you forbid static compilation,
precompiled code with static compilation would be like any other library
not affected, since this is on the compiler level and the compiler is
already done for the library. And of course the worst thing, grapes
could introduce who knows what (though that can be controlled). I am
just trying to say, that this mechanism looks like it could do the Job,
and probably would carry far, but by itself it is no reliable solution -
unless you require everything in source, no library usage beyond what
you control (especially no grapes), no AST transforms, beyond the
builtin ones and no direct usage of Class loaders. Maybe that would then
work out...
But there are probably holes in this shield. As I said the Espresso
variant would be much more complete just by its nature already.
bye Jochen