I'm working on a web application but I need to call certain proprietary C++ library functions. As I understand native methods are not thread safe, it is therefore possible that an access Violation in native code can crash application server JVM. (Tomcat). This native API is very small part of the overall web application functionality, I would say only 5% of users will ever access this functionality. No matter how thorough application is tested ( I don't have access to native source code), there is a risk of a potential bug in native library can bring down whole application server logging out users and potentially downtime.
So the question - which strategy is better?
1) Should I wrap native library in a separate process so that main web server is not impacted by a bug in native code. I can probably use UNIX sockets to communicate to this separate process from my web server. ( Avoiding overhead of TCP socket). If this happens fix the problem as quickly as possible and accept downtime for 5% of users.
Or
2) Bite the bullet and continue to use JNI in servlet container. ( With a risk of potential downtime for everyone)
Regards,
Rohit
It depends:
Take into account, that if a function is not thread-safe, that not necessarily means that it will crash if called from multiple-threads. It might simply return completely wrong results.
If your application cannot overcome it somehow, then you have no other options, you need to serialize access to the native code.
If you are sure that the only side-effect of calling the not-thread safe function is that it can crash, then you need to make sure that the crash does not results in other type of errors, like inconsistent data in your application in the back-end (database corruption, etc.). (You may use transactions to prevent this.)
If your application is able to overcome all of the above, then a 3rd piece of information is still needed:
You need to study how much downtime/crash your users tolerate. If they tolerate the possible down-times, then go ahead and do not care about the crashes, you can safely "bite the bullet", because it won't harm your users or your application.
In all other cases you have to serialize access to the native functions.
Wrapping them into a process might be a good idea, but you have to make sure that the function(s) can be run ONLY in one thread at a time. So probably you need to implement some mechanism to make the other threads/servlets wait until one of them finished calling the function(s).
Related
I'm interested in using JMX to monitor/configure a simple Java Client/Server application. For example, we would capture any network exceptions that occur in a Java program.
Can MBeans be extended in this way? Or are they limited to more concrete get & set functions?
So far, I've looked in Notifications and Monitor MBeans
Thanks
Well I would say that it's definitely doable. I was using JMX in an Apache Wicket application earlier with custom MBeans. Anyway MBeans is just a wrapper around some logic in your server application. So you can take the data directly from your application.
If you want to take an example how is this done in a working application you might want to checkout this:
https://github.com/apache/wicket/blob/master/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/MarkupSettings.java
The class basically holds a reference to the application and asks for data directly form the server app.
When the server starts up, then it registers all the MBeans through an initializer class:
https://github.com/apache/wicket/blob/master/wicket-jmx/src/main/java/org/apache/wicket/jmx/Initializer.java
Then every time when you take a look in your MBean server you will see the latest up-to-date information coming directly from the app.
There are some caveats though. One caveat is that Java in general doesn't provide any good abstraction to capture all Exceptions of a given type coming from any source of the application. You can register your catch-all exception handler but as far as I can remember it doesn't work perfectly.
What I was doing when I had to do something like this, I was using AspectJ to register an all catch place to handle exceptions. I was using compile time weaving to reduce the performance implication but I am not sure how much does it affect the overall performance (if it affects at all).
¯\_(ツ)_/¯
The other caveat is that JMX connections are usually difficult to set up in an enterprise environment. If you have to log-in through two hops just to arrive to the production servers because there are firewalls everywhere than your monitoring connection will definitely fail and you need to keep buying beer to your sysadmin and convince your manager that this is not imposing any security risk. :)
There is one thing though. You say
to monitor/configure a simple Java Client/Server application
You want to configure / monitor the clients as well? I've never done that. I am not sure that's even possible.
I am looking for ways to monitor disk activity in a Java, closed-source, commercial, desktop application. In particular, what I'd like to do is monitor how frequently the app is accessing database/disk - it would appear as "HDD led" indicator in the app and would work exactly the same (so, essentially real-time activity monitoring). I would also like to have as little as possible external libraries.
What I've found so far, doesn't seem too encouraging - I haven't seen the exact examples of anything like that and the best hits I've managed to dig either reference huge frameworks (like Sigar) or libraries like JPicus (which doesn't support Java7 and doesn't seem like it'd support my case). JMX instrumentation doesn't seem to support this either, so I am pretty much open for any ideas/suggestions.
The tech stack is - Java7, Eclipse RCP, SQL Server 2008.
EDIT: To make matters totally clear, I want to monitor disk I/O activity of a Java program with a pure, platform agnostic Java solution.
If you want to know how to monitor the disk I/O activity of a windows process: please ask that question on server fault.
If you want to know how to monitor disk I/O activity of a Java program with a pure, platform agnostic Java solution: There is none, especially meeting your requirements. Technically the only option would be to wrap all I/O operations with instrumented code, which is rather costly.
You could replace the implementation of FileInputStream/FileOutputStream with classes in an extension directory. If that isn't picked up early enough, try setting java.system.class.loader to your own classloader that can intercept requests for those classes.
I have an application which is scheduler running different threads.
The application may load new Runnable classes and run them.
Currently the application is in production, that is it's running on remote server.
My team consists of 3 people developing Runnable classes.
When the class is ready, it's uploaded to server and loaded to scheduler.
I would like to give my team the ability to debug specific threads.
That is: person A may debug threads of Runnable A, B-B, and so on.
Giving them the full access to the remote JVM is not a solution, because
the developers are not allowed to see the system core, and each others solutions.
So my question is: how to allow multiple remote debugging with thread specific connections?
Preferable IDE: Eclipse
EDIT:
It's possible to connect remotely to specific thread with jdb
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jdb.html
Here is an example: http://www.itec.uni-klu.ac.at/~harald/CSE/Content/debugging.html
1) Find your thread with jdb threads
2) Put breakpoint and enter the wanted thread
Still the security issue stays.
One solution was to compile protected code without debug symbols, but it will only protect the core, allow seeing each other's threads.
So, next step - digging Security Manager. Maybe there's privilege layer suitable for my situation.
I'm not sure I've got a good answer to your question, but let's see how it pans out.
As I understand it you want to allow different developers to debug their class alone, and their class runs as a thread as part of a single Java process.
On the face of it that sort of runs counter to the nature of debugging in that normally you have access to everything in the process. I don't imagine that Java is any different to any other language in this respect (I'm no Java programmer).
So how about running the classes in separate Java processes. That way I presume the standard Eclipse tools would allow each developer to remote attach and debug their class.
However I presume that these classes need to interact with each other in some way, otherwise you wouldn't be asking your question in the first place. And running each class in a separate process (JVM) sounds like a bad thing as far as interaction is concerned.
So how about a different form of interaction where tbe process boundary between each class doesn't really matter that much? You could look at using JCSP which, as far as I can tell, doesn't really care if two threads are in the same process or not.
It's a completely different interaction model, based solely on synchronous message passing. You get some nice fringe benefits - scalability is suddenly no longer a massive problem, and it allows you to dodge many pitfalls normally associated with multithreaded programs (deadlock, etc). However if you've already written a large amount of code, adopting JCSP is probably a significant rewrite.
Is that anywhere near the mark? Good luck.
I am curious about what automatic methods may be used to determine if a Java app running on a Windows or PC is malware. (I don't really even know what exploits are available to such an app. Is there someplace I can learn about the risks?) If I have the source code, are there specific packages or classes that could be used more harmfully than others? Perhaps they could suggest malware?
Update: Thanks for the replies. I was interested in knowing if this would be possible, and it basically sounds totally infeasible. Good to know.
If it's not even possible to automatically determine whether a program terminates, I don't think you'll get much leverage in automatically determining whether an app does "naughty stuff".
Part of the problem of course is defining what constitutes malware, but the majority is simply that deducing proofs about the behaviour of other programs is surprisingly difficult/impossible. You may have some luck spotting particular patterns, but on the whole you can't be confident (and I suspect it's provably impossible) that you've caught all possible attack vectors.
And in the general sphere, catching 95% of vectors isn't really worthwhile when the attackers simply concentrate on the remaining 5%.
Well, there's always the fundamental philosophical question: what is a malware? It's code that was intended to do damage, or at least code that doesn't do what it claims to. How do you plan to judge intent based on libraries it uses?
Having said that, if you at least roughly know what the program is supposed to do, you can indeed find suspicious packages, things the program wouldn't normally need to access. Like network connections when the program is meant to run as a desktop app. But then the network connection could just be part of an autoupdate feature. (Is autoupdate itself a malware? Sometimes it feels like it is.)
Another indicator is if a program that ostensibly doesn't need any special privileges, refuses to run in a sandbox. And the biggest threat is if it tries to load a native library when it shouldn't need one.
But all these only make sense if you know what the code is supposed to do. An antivirus package might use very similar techniques to viruses, the only difference is what's on the label.
Here is a general outline for how you can bound the possible actions your java application can take. Basically you are testing to see if the java application is 'inert' (can't take harmful actions) and thus it probably not mallware.
This won't necessarily tell you mallware or not, as others have pointed out. The app could still do annoying things like pop-up windows. Perhaps the best indication, is to see if the application is digitally signed by an author you trust; if not -- be afraid.
You can disassemble the class files to determine which Java APIs the application uses; you are looking for points where the java app uses the OS. Since java uses a virtual machine, there are well defined points where a java application could take potentially harmful actions -- these are the 'gateways' to various OS calls (for example opening a socket or reading a file).
Its difficult to enumerate all the APIs, different functions which execute the same OS action should require the same Permission. But java's docs don't provide an exhaustive list.
Does the java app use any native libraries -- if so its a big red flag.
The JVM does not offer the ability to run arbitrary code, or use native system APIs; in particular it does not offer the ability to modify the registry (a typical action of PC mallware). The only way a java application can do this is via native libraries. Typically there is no need for a normal application written in java to use native code (unless it needs to use devices).
Check for System.loadLibrary() or System.load() or Runtime.loadLibrary() or Runtime.load(). This is how the VM loads native libraries.
Does it use the network or file system?
Look for use of java.io, java.net.
Does it make system calls (via Runtime.exec())
You can check for the use of java.lang.Runtime.exec() or ProcessBuilder.exec().
Does it try to control the keyboard / mouse?
You could also run the application in a restricted policy JVM (the instructions/tools for doing this are not as simple as they should be) and see what fails (see Oracle's security tutorial) -- note that disassembly is the only way to be sure, just because the app doesn't do anything harmful once, doesn't mean it won't in the future.
This definitely is not easy, and I was surprised to find how many places one needs to look at (for example several java functions load native libraries, not just one).
Under the Java security model it is possible to block most dangerous actions from untrusted classes, but the last time I checked (a few years ago now) it was still possible for untrusted code to perform a denial of service attack by continually allocating memory until the JVM crashes with an OutOfMemoryException. Looking now, I can't see any improvement in the situation.
I have a requirement to run untrusted code from 3rd parties inside a Java application and I'd like to know if it is possible to somehow restrict the heap/stack space that a class or thread can allocate in the Java security model. Thus preventing memory allocation based DoS attacks. I know about -Xss, but as I understand it that restricts all threads, most of which need no restriction.
I have also considered creating a container for the untrusted code that will run in its own JVM and communicate with the main app through sockets, or doing some static analysis on the untrusted code. However, these both sound like more effort than I hoped, although if someone knows of a trick or opensource library for this I'm interested.
So, is there a way to restrict the amount of memory than a thread can allocate to itself or some other way of preventing memory allocation denial of service attacks in Java?
There is currently no way to do this with standard APIs in Java.
More people have been interested in this and there is a JSR underway for this called Resource Consumption Management API which may be something to look into.
You will need to run the untrusted code in a separate process. There may still be ways to DoS, for instance on old versions of Windows you could easily use up all GDI resources (not tried recently, not now we have Swing).