NegativeArraySizeException merging frames during replaceAsmInstructions

Eirik Bjørsnøs (via asm Mailing List) <[email protected]> Wed, 16 Mar 2022 20:59:38 +0100
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <CA+pBWhsxX=gf2dkDhjBeBEhqL7MTHw95dVYdk5OAdSWWHG9PPg@mail.gmail.com>
This is a multi-part message in MIME format...

------------=_1647460793-5912-6
Content-Type: multipart/alternative; boundary="000000000000295c0405da5b5bbf"

--000000000000295c0405da5b5bbf
Content-Type: text/plain; charset="UTF-8"

Hi,

I'm observing a NASE during toByteArray/replaceAsmInstructions while
instrumenting byte code in a Java agent I'm working on.

I have been able to create a standalone reproducer [1] which provokes the
following conditions:

1: One of the methods in the class should incude a Label which returns
false from the Label.resolve method. This is because the label is a forward
reference with a relative offset larger than Short.MAX_VALUE, hence
ASMs hasAsmInstructions is set to true. This seems necessary to force a
call to replaceAsmInstructions which triggers frame processing.

2: Another method of the class is instrumented with a trycatchblock which
wraps the body of the method This catch block handler simply ATHROWs the
Throwable. This seems necessary to create the conditions where the frame
merge throws NASE.

Here's the stack trace cased by the minimal reproducer:

Exception in thread "main" java.lang.NegativeArraySizeException: -1
at org.objectweb.asm.Frame.merge(Frame.java:1222)
at org.objectweb.asm.CurrentFrame.execute(CurrentFrame.java:53)
at org.objectweb.asm.MethodWriter.visitInsn(MethodWriter.java:868)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:2213)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1514)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:744)
at
org.objectweb.asm.ClassWriter.replaceAsmInstructions(ClassWriter.java:755)
at org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:718)
at
com.example.asmnase.ReplaceAsmInstructionsNASE.main(ReplaceAsmInstructionsNASE.java:37)

The following Gist contains the reproducer:

https://gist.github.com/eirbjo/3eb8ca755f2a399ac8e5def6f43439e5

Note that the instrumentation produces valid class files which are verified
and loaded by the JVM. It's only in the abnormal case of large relative
forward references that ASM throws this exception. So I think the produced
byte code is valid and there might be a bug in ASM here.

What do you think?

Cheers,
Eirik.

--000000000000295c0405da5b5bbf
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><br></div><div>Hi,</div><div><br></div><div>I&#39;m o=
bserving a NASE during toByteArray/replaceAsmInstructions while instrumenti=
ng byte code in a Java agent I&#39;m working on.</div><div><br></div><div>I=
 have been able to create a standalone reproducer [1] which provokes the fo=
llowing conditions:</div><div><br></div><div>1: One of the methods in the c=
lass should incude a Label which returns false from the Label.resolve metho=
d. This is because the label is a forward reference with a relative offset =
larger than=C2=A0Short.MAX_VALUE, hence ASMs=C2=A0hasAsmInstructions is set=
 to true. This seems necessary to force a call to=C2=A0replaceAsmInstructio=
ns which triggers frame processing.</div><div><br></div><div>2: Another met=
hod of the class is instrumented with a trycatchblock which wraps the body =
of the method This catch block handler simply ATHROWs the Throwable. This s=
eems necessary to create the conditions where the frame merge throws NASE.<=
/div><div><br></div><div>Here&#39;s the stack trace cased by the minimal re=
producer:</div><div><br></div>Exception in thread &quot;main&quot; java.lan=
g.NegativeArraySizeException: -1<br>	at org.objectweb.asm.Frame.merge(Frame=
.java:1222)<br>	at org.objectweb.asm.CurrentFrame.execute(CurrentFrame.java=
:53)<br>	at org.objectweb.asm.MethodWriter.visitInsn(MethodWriter.java:868)=
<br>	at org.objectweb.asm.ClassReader.readCode(ClassReader.java:2213)<br>	a=
t org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1514)<br>	at or=
g.objectweb.asm.ClassReader.accept(ClassReader.java:744)<br>	at org.objectw=
eb.asm.ClassWriter.replaceAsmInstructions(ClassWriter.java:755)<br>	at org.=
objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:718)<br>	at com.exam=
ple.asmnase.ReplaceAsmInstructionsNASE.main(ReplaceAsmInstructionsNASE.java=
:37)<br><div><br></div><div>The following Gist contains the reproducer:</di=
v><div><br></div><div><a href=3D"https://gist.github.com/eirbjo/3eb8ca755f2=
a399ac8e5def6f43439e5">https://gist.github.com/eirbjo/3eb8ca755f2a399ac8e5d=
ef6f43439e5</a></div><div><br></div><div>Note that the instrumentation prod=
uces valid class files which are verified and loaded by the JVM. It&#39;s o=
nly in the abnormal case of large relative forward references that ASM thro=
ws this exception. So I think the produced byte code is valid and there mig=
ht be a bug in ASM here.=C2=A0</div><div><br></div><div>What do you think?<=
/div><div><br></div><div>Cheers,</div><div>Eirik.</div></div>

--000000000000295c0405da5b5bbf--

------------=_1647460793-5912-6
Content-Type: text/plain; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: 8bit


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

------------=_1647460793-5912-6--