CLR Crash.

For instance, you have pluggable application which runs set of assemblies (plugins), each in separate "sandbox" domain. Next code block included within "malicious" plugin causes application to crash:

classSomePlugin

{

privatedelegatevoidDoSomething();

public staticvoid SomeMethod()

{

try

{

Activator.CreateInstance(typeof (DoSomething),newobject[] {null,null});

}

catch

{

}

}

}

Try-catch block above does not help. Error text says (FatalExecutionEngineError), that problems are caused by pinvoke, or COM, or it is bug in CLR. Code provided above is simple and shows possible problems while playing with reflection.

Is there any way to handle such kind of error?

[1697 byte] By [VitalyLiptchinsky] at [2008-1-10]
# 1

Hi

as per the CLR design you can cannot handle exception such as . ExecutionEngine , StackOverflow and outofmemory exceptions cannot be handled... even if you write the catch block it will execute the catch block but at the last statement in catch block, the exception is again rethorwn automatically by the CLR system.

So that it ultimately travels to the CLR when clr takes the final decision. In most cases it just stop executing the application and may unlaod AppDomain in which exception occurs. Try putting this code in place of catch block..just hanlde the exception and print that message

try

{

....

}

catch(Exception ex)

{

Console.WriteLine(ex.tostring());

if(ex.innerexception !=null)

{

console.writeline(ex.innerexception.tostring());

}

} ///exception (if ExecutionEngine,StackOverflow,Outofmemroy) will be rethorwn here

hope this helps you.....

PravinChandankhede at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 2

One more thing to note.....

in case of these three exception .. there is no gurantee that the code in catch block will execute.... system may reject to run code... so this code will just be trial and error...

PravinChandankhede at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 3

Hi Pravin,

I am aware, that ExecutionEngineException, StackOverflowException, OutOfMemoryException as well as ThreadAbortException are always rethrown. I've tried to check your solution first of all... Even finally block is not executed.

Below is provided new code block which demonstrates, that not only application domain where code is executed is unloaded, but entire process fails:

class Program

{

static void Main(string[] args)

{

AppDomain newDomain = AppDomain.CreateDomain("NewDomain");

ObjectHandle oh = newDomain.CreateInstance(Assembly.GetExecutingAssembly().FullName, "CLRCrashApp.SomeClass");

((SomeClass)oh.Unwrap()).DoSomething();

}

}

public class SomeClass : MarshalByRefObject

{

private delegate void DoSomethingDelegate();

public SomeClass() : base()

{

}

public void DoSomething()

{

Console.WriteLine("AppDomain is: {0}", AppDomain.CurrentDomain.FriendlyName);

try

{

Activator.CreateInstance(typeof(DoSomethingDelegate), new object[] { null, null });

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

if (ex.InnerException != null)

{

Console.WriteLine(ex.InnerException.ToString());

}

}

finally

{

Console.WriteLine("Finally is executing...");

}

}

}

All I want to say is that such behavior is not good as for me. Creating of simple delegate with wrong parameters should not cause CLR crash. Currently I do not see any way to prevent or handle such malicious code.
VitalyLiptchinsky at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 4
This blog post by the author of the V3.5 System.Addin pretty much acknowledges your problem.
nobugz at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 5
I've updated code above and added UnhandledException event handler (according to the approach). No luck. Error is still unhandled and entire process fails. Below is provided updated code block:

class Program

{

static void Main(string[] args)

{

AppDomain newDomain = AppDomain.CreateDomain("NewDomain");

newDomain.UnhandledException += new UnhandledExceptionEventHandler(newDomain_UnhandledException);

ObjectHandle oh = newDomain.CreateInstance(Assembly.GetExecutingAssembly().FullName, "CLRCrashApp.SomeClass");

((SomeClass)oh.Unwrap()).DoSomething();

}

static void newDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)

{

Console.WriteLine("Unhandled exception has occured in NewDomain");

}

}

public class SomeClass : MarshalByRefObject

{

private delegate void DoSomethingDelegate();

public SomeClass() : base()

{

}

public void DoSomething()

{

Console.WriteLine("AppDomain is: {0}", AppDomain.CurrentDomain.FriendlyName);

try

{

Activator.CreateInstance(typeof(DoSomethingDelegate), new object[] { null, null });

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

if (ex.InnerException != null)

{

Console.WriteLine(ex.InnerException.ToString());

}

}

finally

{

Console.WriteLine("Finally is executed.");

}

}

}

Any other ideas?

VitalyLiptchinsky at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 6
Vitaly Liptchinsky wrote:
I've updated code above and added UnhandledException event handler (according to the approach). No luck. Error is still unhandled and entire process fails. Below is provided updated code block:

class Program

{

static void Main(string[] args)

{

AppDomain newDomain = AppDomain.CreateDomain("NewDomain");

newDomain.UnhandledException += new UnhandledExceptionEventHandler(newDomain_UnhandledException);

ObjectHandle oh = newDomain.CreateInstance(Assembly.GetExecutingAssembly().FullName, "CLRCrashApp.SomeClass");

((SomeClass)oh.Unwrap()).DoSomething();

}

static void newDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)

{

Console.WriteLine("Unhandled exception has occured in NewDomain");

}

}

public class SomeClass : MarshalByRefObject

{

private delegate void DoSomethingDelegate();

public SomeClass() : base()

{

}

public void DoSomething()

{

Console.WriteLine("AppDomain is: {0}", AppDomain.CurrentDomain.FriendlyName);

try

{

Activator.CreateInstance(typeof(DoSomethingDelegate), new object[] { null, null });

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

if (ex.InnerException != null)

{

Console.WriteLine(ex.InnerException.ToString());

}

}

finally

{

Console.WriteLine("Finally is executed.");

}

}

}

Any other ideas?

I still haven't received an answer how to prevent such malicious attack on CLR host....

VitalyLiptchinsky at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...

.NET Development

Site Classified