如何实现本机代码沙箱? [英] How to implement a native code sandbox?

查看:325
本文介绍了如何实现本机代码沙箱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个Windows Java应用程序,该应用程序需要调用不安全的本机代码,并且我需要防止该代码访问Java对象和JVM数据结构,否则可能会使JVM崩溃或入侵敏感数据.在您询问之前,此本机代码已经过验证-它只能调用几个API并且不能具有某些指令,因此我们知道它不会通过VirtualProtect本身或其他内存区域来获得更多访问权限.

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.

无论如何,我的第一个尝试是将这段代码包装到一个单独的进程(沙盒)中,并使用IPC与Java进行通信.有一个JNI DLL在Java端执行IPC任务.基本上,每次我们需要运行不安全的本机代码时,我们的Java应用程序都会调用JNI函数,该函数使用自动重置的Windows事件唤醒沙盒,然后等待完成.沙箱将运行不安全的本机代码,并使用另一个自动重置的Windows事件唤醒JVM,并且生命将继续.如果不是那么慢,那将是完美的.

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.

问题在于,不安全的本机代码可以包含执行非常快速的计算的某些函数,并且可以从Java调用数百万次,因此,调用开销应该最小.但是这种开销是巨大的,因为JVM会通过Windows事件唤醒沙箱,反之亦然.此过程是进程内(非IPC)解决方案时间的8倍,在解决方案中,不安全的本机代码包装在JNI DLL中(因此,调用发生在同一线程中,在同一时间段内).

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).

我的第一个猜测是,当JVM唤醒沙箱时,Windows仅将沙箱线程放在就绪集上,因此它仅在几毫秒后运行.当沙盒返回时,也会发生同样的情况.不算两个(可能是昂贵的)上下文切换.

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文档此处表示以下内容:

Microsoft documentation here says the following:

如果有更高优先级的线程可以运行,系统将停止执行较低优先级的线程(不允许其使用其时间片完成),并为较高优先级的线程分配一个完整的时间片. /p>

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.

为了检验该理论,我向沙盒线程分配了THREAD_PRIORITY_TIME_CRITICAL.有一些收获.性能是处理中(非IPC)解决方案时间的8倍至5倍.但是我还需要更多,否则此Java应用程序可能无法更改才能投入生产!

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:

  • 请告诉我是否有一种更快的方法来唤醒另一个进程,例如强制执行上下文切换或执行进程间过程调用.

  • 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.

告诉我如何在进程中运行不安全的本机代码时保护JVM.我听说Google Native Client会这样做,但是我只发现本文档.如果您了解更多信息,请提供有关如何实现此功能的更多详细信息的链接.

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 this documentation. If you know more, please provide links to more detailed information about how this is implemented.

推荐答案

我通过使用共享内存变量通过 spinlock href ="http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html" rel ="nofollow noreferrer">文件映射. 此问题说明了如何在C ++环境中实现.通过MappedByteBuffer可以轻松移植到Java.

I solved the problem by performing JVM-sandbox interactions using spinlock over a shared memory variable accessed from JVM through file mapping. This question explains how to implement in a C++ environment. Porting to Java is easy with MappedByteBuffer.

这篇关于如何实现本机代码沙箱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆