Re: Re: NOP ATHROW hack defeated !
Rémi Forax <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
On 05/06/2011 09:26 AM, Charles Oliver Nutter wrote: > I may have been mistakend about the exact errors below...will update shortly. > > - Charlie If you want the exact line number, you can use all/asm-debug-all-4.0.jar Rémi > On Fri, May 6, 2011 at 2:17 AM, Charles Oliver Nutter > <[email protected]> wrote: >> Sorry for the delay. This appears to cause failures due to invalid >> classfiles in JRuby, at about the place where it blew up because of >> the dead code before: >> >> ~/projects/jruby ➔ jruby -Xjruby.invokedynamic=false test/testCompiler.rb >> ..........................................................................................................................................FF........................................ >> -------------------------------------------------------------------------------- >> FAILED 139 unexpected exception java.lang.ClassFormatError: Invalid >> code attribute name index 65 in class file testCompiler135-- >> test/testCompiler.rb:474:in `(root)' >> FAILED 140 unexpected exception java.lang.ClassFormatError: Truncated >> class file-- test/testCompiler.rb:489:in `(root)' >> -------------------------------------------------------------------------------- >> Tests: 180. (Ok: 178; Failed: 2) >> >> Attempting to output the bytecode it produces yields an >> ArrayIndexOutOfBoundsException in most cases I attempted to >> investigate. Here's the actual exceptions it's raising (sorry, I don't >> know how to build an ASM that has line numbers): >> >> ~/projects/jruby ➔ jruby -X+C -d -e "def foo; begin; return 4; rescue; >> end; return 3; end; foo" >> warning: could not compile: -e; full trace follows >> java.lang.ClassFormatError: Invalid code attribute name index 65 in >> class file ruby/__dash_e__ >> at java.lang.ClassLoader.defineClass1(Native Method) >> at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) >> at java.lang.ClassLoader.defineClass(ClassLoader.java:616) >> at org.jruby.util.JRubyClassLoader.defineClass(JRubyClassLoader.java:76) >> at org.jruby.compiler.impl.StandardASMCompiler.loadClass(StandardASMCompiler.java:219) >> at org.jruby.Ruby.tryCompile(Ruby.java:655) >> at org.jruby.Ruby.tryCompile(Ruby.java:627) >> at org.jruby.Ruby.runNormally(Ruby.java:567) >> at org.jruby.Ruby.runFromMain(Ruby.java:424) >> at org.jruby.Main.doRunFromMain(Main.java:278) >> at org.jruby.Main.internalRun(Main.java:198) >> at org.jruby.Main.run(Main.java:164) >> at org.jruby.Main.run(Main.java:148) >> at org.jruby.Main.main(Main.java:128) >> RuntimeError: could not compile and compile mode is 'force': -e >> >> ~/projects/jruby ➔ jruby -X+C -d -e "begin; x = while true; break 5; >> end; ensure; end" >> warning: could not compile: -e; full trace follows >> java.lang.ClassFormatError: Invalid code attribute name index 55 in >> class file ruby/__dash_e__ >> at java.lang.ClassLoader.defineClass1(Native Method) >> at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) >> at java.lang.ClassLoader.defineClass(ClassLoader.java:616) >> at org.jruby.util.JRubyClassLoader.defineClass(JRubyClassLoader.java:76) >> at org.jruby.compiler.impl.StandardASMCompiler.loadClass(StandardASMCompiler.java:219) >> at org.jruby.Ruby.tryCompile(Ruby.java:655) >> at org.jruby.Ruby.tryCompile(Ruby.java:627) >> at org.jruby.Ruby.runNormally(Ruby.java:567) >> at org.jruby.Ruby.runFromMain(Ruby.java:424) >> at org.jruby.Main.doRunFromMain(Main.java:278) >> at org.jruby.Main.internalRun(Main.java:198) >> at org.jruby.Main.run(Main.java:164) >> at org.jruby.Main.run(Main.java:148) >> at org.jruby.Main.main(Main.java:128) >> RuntimeError: could not compile and compile mode is 'force': -e >> >> If you want to reproduce this, replace the ASM jars in JRuby's >> build_lib, rebuild, and run the above command lines or >> test/testCompiler.rb. >> >> - Charlie >> >> On Sun, May 1, 2011 at 10:15 AM, Eric Bruneton<[email protected]> wrote: >>> 01/05/2011 16:16, Rémi Forax wrote: >>>> On 05/01/2011 11:09 AM, Eric Bruneton wrote: >>>>> 30/04/2011 10:20, Eric Bruneton wrote: >>>>>> 29/04/2011 03:04, Rémi Forax wrote: >>>>>>> Charles Nutter (a JRuby guy) was able to generate a code that defeat >>>>>>> the infamous NOP ... ATHROW hack. >>>>>>> >>>>>>> see http://asm.ow2.org/doc/developer-guide.html#deadcode >>>>>>> for the background. >>>>>>> >>>>>>> Basically, when a code is dead, not reachable, ASM replaces the >>>>>>> offending code by >>>>>>> NOP ... ATHROW and generate a dedicated stackmap: [] >>>>>>> [java/lang/Throwable]. >>>>>>> But if the unreachable code is in a try/catch, we create a path >>>>>>> where no >>>>>>> local variable >>>>>>> are available anymore. So the split verifier will reject the >>>>>>> bytecode if >>>>>>> a local variable is used in the exception handler of the try/catch. >>>>>>> >>>>>>> The program below generates a bytecode which is rejected by the split >>>>>>> verifier. >>>>>>> [forax@localhost asm4-test]$ java deadcode >>>>>>> Exception in thread "main" java.lang.VerifyError: Stack map does not >>>>>>> match the one at exception handler 7 in method >>>>>>> deadcode.foo(Ljava/lang/Object;)V at offset 3 >>>>>>> at java.lang.Class.getDeclaredMethods0(Native Method) >>>>>>> at java.lang.Class.privateGetDeclaredMethods(Class.java:2440) >>>>>>> at java.lang.Class.getMethod0(Class.java:2683) >>>>>>> at java.lang.Class.getMethod(Class.java:1618) >>>>>>> at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:484) >>>>>>> at >>>>>>> sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:476) >>>>>>> >>>>>>> >>>>>>> Eric, do you see a solution for that ? >>>>>> I think we can find which locals to put in the stackmap frame generated >>>>>> for a dead block by using the locals from the first frame of the >>>>>> innermost exception handler for this block(*) (if any). Using the >>>>>> innermost handler is necessary to get the most specific types for these >>>>>> locals (the other handlers will necessarily have these types or super >>>>>> types of these types in their stackmap frames, since they handle more >>>>>> code). Also, since dead blocks are handled after the fix point algorithm >>>>>> is finished, we have the final frames for the exception handlers at this >>>>>> point. >>>>>> >>>>>> The only problem is that exception handlers do not have to be properly >>>>>> nested (nothing enforces this in the specification, although compilers >>>>>> always generate nested handlers because Java try/catch are nested by >>>>>> construction). And in this case the "innermost handler" is not well >>>>>> defined. >>>>> there is another solution, which is simpler and works in all cases (I >>>>> think): remove the exception handlers for deadcode (see attached patch). >>>>> >>>>> Eric >>>> It seems the patch was too shy to show up :) >>> oups! here it is >>> >>> Eric >>>
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws