17615

How to implement a native code sandbox?

Question:

I'm writting a Windows Java application that needs to call unsafe native code, and I need to prevent this code from having access to Java objects and JVM data structures, otherwise it might crash the JVM or hack into sensitive data. Before you ask, this native code is previously verified - it can only call a few APIs and cannot have certain instructions, so we know it won't VirtualProtect itself or other memory regions to gain more access and mess around.

Anyway, my first attempt was to wrap this code into a separate process (sandbox) and use IPC to talk with Java. There's a JNI DLL that does IPC stuff on Java side. Basically, every time we need to run unsafe native code, our Java app calls a JNI function that wakes up the sandbox using an auto-reset Windows Event, and then awaits completion. The sandbox runs unsafe native code and wakes up the JVM using another auto-reset Windows Event, and life continues. It would be perfect if it weren't so slow.

The problem is that unsafe native code can contain some functions that perform very quick calculations and can be called millions of times from Java, hence the call overhead should be minimum. But this overhead is huge because JVM wakes-up sandbox with a Windows Event, and vice-versa when the sandbox returns. This process is 8x the time of an in-process (non-IPC) solution, where unsafe native code is wrapped in JNI DLL (and hence the call happens in the same thread, in the same time slice).

My first guess is that when JVM wakes-up the sandbox, Windows only puts the sandbox thread on the ready set, so it runs only after some milliseconds. And the same happens when the sandbox returns. Not to count for two (possibly expensive) context switches.

Microsoft documentation <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms685100(v=vs.85).aspx" rel="nofollow">here</a> says the following:

<blockquote>

If a higher-priority thread becomes available to run, the system ceases to execute the lower-priority thread (without allowing it to finish using its time slice), and assigns a full time slice to the higher-priority thread.

</blockquote>

To test this theory, I assigned THREAD_PRIORITY_TIME_CRITICAL to the sandbox thread. There was some gains. Performance went from 8x to 5x the time of the in-process (non-IPC) solution. But I need more, otherwise this Java app might not get a change to go into production!

You can help me in two ways:

<ul><li>

Tell me if there's a faster method to wake-up another process, such as forcing a context switch or performing an inter-process procedure call.

</li> <li>

Tell me how can I protect JVM while running unsafe native code in-process. I heard that Google Native Client does this, but I only found <a href="https://sites.google.com/a/chromium.org/dev/nativeclient/reference/anatomy-of-a-sys" rel="nofollow">this documentation</a>. If you know more, please provide links to more detailed information about how this is implemented.

</li> </ul>

Answer1:

I solved the problem by performing JVM-sandbox interactions using <a href="http://en.wikipedia.org/wiki/Spinlock" rel="nofollow">spinlock</a> over a <a href="http://en.wikipedia.org/wiki/Shared_memory" rel="nofollow">shared memory</a> variable accessed from JVM through <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html" rel="nofollow">file mapping</a>. <a href="https://stackoverflow.com/questions/11386528/how-to-make-a-fast-context-switch-from-one-process-to-another" rel="nofollow">This question</a> explains how to implement in a C++ environment. Porting to Java is easy with MappedByteBuffer.

Recommend

  • NodeJs delay each promise within Promise.all()
  • What does async/await do?
  • Linux kernel idle loop
  • Android/Google Play - Can an App Update While it Is Running
  • command issued via C# opens another command prompt
  • How to explain semaphore processing operation?
  • No OpenID endpoint found - Relying Party Timeout Option
  • Dropping support for JRE 1.3
  • Why dsofile.dll still need Office Installation?
  • HTMLcollection 0 list length, [n] returns undefined, converting to an array returns an empty array
  • Theme in user control
  • Spring Integration debounce/deduplicate
  • Use allowDiskUse in criteria query with Grails and the MongoDB plugin?
  • How to extract a number from a string [duplicate]
  • Obtain actual browser URL in PHP
  • Cryptic error when trying to run POW
  • “A GKScore must specify a leaderboard.”
  • How to add the custom button on google's(device) native application in android?
  • Javascript focus remove text highlight
  • Can long-polling be achieved in Restlet by just making the thread sleep?
  • What is the default HTTP verb in WebApi ? GET or POST?
  • Hibernate to update table schema
  • Multiple producers single consumer locking schema
  • Tell Git to stop prompting me for conflicts when none really exist?
  • Ember.js model to be organised as a tree structure
  • ViewController With Transparent Background Entering Current ViewController With Push Transition
  • Jackson Parser: ignore deserializing for type mismatch
  • d3 v4 drag and drop with TypeScript
  • JQuery Internet Explorer and ajaxstop
  • OpenGL ES texture problem, 4 duplicate columns and horizontal lines (Android)
  • Change multiple background-images with jQuery
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • Opengl-es onTouchEvents problem or a draw problem? [closed]
  • Perl system calls when running as another user using sudo
  • Trying to switch camera back to front but getting exception
  • How can I estimate amount of memory left with calling System.gc()?
  • Linking SubReports Without LinkChild/LinkMaster
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?