Allow to track loop iterations using a user defined code call#114
Allow to track loop iterations using a user defined code call#114maximburyak wants to merge 1 commit intopaulbartrum:masterfrom
Conversation
|
The idea is that this delegate that we inject allow us to verify that the scripts isn't doing BAD THINGS. See fuller discussion of this and the implications of what it enables here: |
|
Very interesting, thanks. Being robust to badly behaving and actively malicious scripts is definitely of interest to quite a few people, but I've resisted doing anything about it because the only truly robust method is to run the malicious code in a separate OS process. Unfortunately, this solution is difficult and in a lot of cases (e.g. UWP) it's not even possible. So a solution like yours would definitely be useful as a kind of middle ground, even if it's not 100% robust. |
|
@paulbartrum We actually tested a bunch of other stuff, including injecting our code on every branch instruction, but that seemed too intrusive. Note that we assume that actually handling the policy such as timeout / # of allocations is done by the supplied delegate. Can you think about a way this will still open us some issues? |
|
You're hooking into the built-in loop statements, but there are many other ways to execute lots of code. Some I can think of:
|
| if (EmitOnLoopIteration.Target != null) | ||
| { | ||
| generator.LoadArgument(0); | ||
| generator.LoadField(typeof(ScriptEngine).GetField(nameof(ScriptEngine.OnLoopIterationCallTarget))); |
There was a problem hiding this comment.
The GetField call can be in ReflectionHelpers.
| /// </summary> | ||
| public bool EnableILAnalysis { get; set; } | ||
|
|
||
| public Action EmitOnLoopIteration { get; set; } |
| // Emit on loop iteration (before loop's branch call) | ||
| //_________________________________________________________________________________________ | ||
| private Action _onLoopIterationCall; | ||
| public Action OnLoopIterationCall |
| OnLoopIterationCallTarget = OnLoopIterationCall?.Target; | ||
| } | ||
| } | ||
| public object OnLoopIterationCallTarget; |
There was a problem hiding this comment.
Can this be a property that returns OnLoopIterationCall?.Target?
There was a problem hiding this comment.
The idea was to reduce further the amount of work required. In particular, avoid a call in favor of a field load
There was a problem hiding this comment.
Yeah, good point, keep it a field then.
| OnLoopIterationCallTarget = OnLoopIterationCall?.Target; | ||
| } | ||
| } | ||
| public object OnLoopIterationCallTarget; |
| @@ -0,0 +1,207 @@ | |||
| using System; | |||
There was a problem hiding this comment.
Move this file under the Core folder please.
| public void OnLoopCallWithInstanceMethodInDebug() | ||
| { | ||
| var engine = new ScriptEngine(); | ||
| engine.EnableDebugging = true; |
There was a problem hiding this comment.
Don't use this property, it doesn't work in .NET core.
|
Hi, (I originally created code of the I think that you should also check the delegate when user-defined functions are invoked, in order to handle the function func(n) {
if (n < 15) {
func(n + 1);
func(n + 1);
func(n + 1);
func(n + 1);
func(n + 1);
func(n + 1);
}
}
func(1); |
No description provided.