<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">One concern that we have is
        that unrestricted access to bytecode of loaded classes may
        constitute an attack vector for malicious code.  <br>
        <br>
        While we don't recommend people program like this:<br>
        <br>
            boolean checkPassword(String pw) { <br>
                return "s00perSeekrit".equals(pw);<br>
            }<br>
        <br>
        arbitrary access to bytecode will compromise the "security" of
        this code in ways that the author might not have reasonably
        forseen.  <br>
        <br>
        <br>
      </font></font><br>
    <div class="moz-cite-prefix">On 2/9/2023 1:24 PM, Dan Heidinga
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAJq4Gi4nj96y_6E5ZpNqnG0enj6EWqT12QNWBJTy6OEWbD6NWg@mail.gmail.com">
      
      <div dir="ltr">
        <div>Thanks for confirming, Gary.</div>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Thu, Feb 9, 2023 at 11:59
            AM Gary Frost <<a href="mailto:gary.frost@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">gary.frost@oracle.com</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div class="msg-7567829150639208625">
              <div dir="ltr">
                <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">Dan<br>
                  <br>
                  I have indeed used JVMTI (and Java) agents for this.
                  In the case of JVMTI by keeping a
                  std::map<std::string,byte[]>, and providing a
                  JNI call to get the bytes.
                  <br>
                  <br>
                  It works well for cases where we know the set of
                  classes we want bytes for at JVM 'launch time' , or
                  there is something in the class (name match? constant
                  pool entry?) that we can trigger to prune the size of
                  the map.    Otherwise we are forced to retain a map
                  for all classes, just in case. <br>
                  <br>
                  And of course who knew whether our JVMTI agent was the
                  last 'actor' in the chain of possible mutators to play
                  with the bytes.</div>
              </div>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>Can you expand on the use case for getting the current
            bytes from the runtime?  As I said in the previous email,
            they aren't a good candidate for feeding back into the
            runtime due to the existing JVMTI agent process.  Is this
            mostly for testing purposes?</div>
          <div><br>
          </div>
          <div>--Dan</div>
          <div> </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px
            0.8ex;border-left:1px solid
            rgb(204,204,204);padding-left:1ex">
            <div class="msg-7567829150639208625">
              <div dir="ltr">
                <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)"><br>
                  <br>
                  Hence the desire for runtime help <br>
                  <br>
                  <br>
                </div>
                <hr style="display:inline-block;width:98%">
                <div id="m_-7567829150639208625divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> Dan Heidinga <<a href="mailto:heidinga@redhat.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">heidinga@redhat.com</a>><br>
                    <b>Sent:</b> Thursday, February 9, 2023 4:35 PM<br>
                    <b>To:</b> Gary Frost <<a href="mailto:gary.frost@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">gary.frost@oracle.com</a>><br>
                    <b>Cc:</b> <a href="mailto:classfile-api-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">classfile-api-dev@openjdk.org</a>
                    <<a href="mailto:classfile-api-dev@openjdk.org" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">classfile-api-dev@openjdk.org</a>><br>
                    <b>Subject:</b> [External] : Re: Reflective access
                    to bytes[] of loaded class</font>
                  <div> </div>
                </div>
                <div>
                  <div dir="ltr">
                    <div dir="ltr"><br>
                    </div>
                    <br>
                    <div>
                      <div dir="ltr">On Thu, Feb 9, 2023 at 11:03 AM
                        Gary Frost <<a href="mailto:gary.frost@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">gary.frost@oracle.com</a>>
                        wrote:<br>
                      </div>
                      <blockquote style="margin:0px 0px 0px
                        0.8ex;border-left:1px solid
                        rgb(204,204,204);padding-left:1ex">
                        <div>
                          <div dir="ltr">
                            <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">I
                              would like to make a case for adding a
                              reflection API for getting the bytes for
                              class loaded by the VM as part of this
                              Classfile API.
                              <br>
                            </div>
                            <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)"><br>
                              Something akin to <br>
                              <br>
                              byte[] Class.getClassfileBytes();</div>
                          </div>
                        </div>
                      </blockquote>
                      <div><br>
                      </div>
                      <div>I've often wanted the same kind of API when
                        doing one off tests and minor modifications so
                        I'm very sympathetic to the request.  Typically
                        when doing more "serious" class modification,
                        I've used the Instrumentation::retransform API
                        [0] or written a native JVMTI agent [1] and then
                        such an api to get the current classfile bytes
                        isn't required.  Does this match your typical
                        use cases as well?</div>
                      <div><br>
                      </div>
                      <div>The JVM does some interesting handling of
                        classfile bytes in these cases - it allows
                        non-retransform-capable agents to do a 1 time
                        modification of the original classfile bytes and
                        then saves those bytes away before passing them
                        on to the retransform-capable agents.  One
                        subsequent retransform events, those saved bytes
                        are reused and only the retransform-capable
                        agents get a chance to modify the bytes.</div>
                      <div><br>
                      </div>
                      <div>The reason this matters is that existing
                        retransform-capable agents aren't expecting to
                        see the modifications they've made present in
                        the classfile bytes they get passed.  Providing
                        an easy api to get the currently executing
                        bytecodes will mean that these agents will now
                        "see" their own modifications which may result
                        in incompatibilities.  </div>
                      <div><br>
                      </div>
                      <div>I'd be interested in feedback from existing
                        major agent providers to see how much of a
                        problem such a change would cause them before
                        pursuing it unless there's a more common pattern
                        of use I'm unaware of.</div>
                      <div><br>
                      </div>
                      <div>[0] <a href="https://cr.openjdk.java.net/~iris/se/17/latestSpec/api/java.instrument/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class.." target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://cr.openjdk.java.net/~iris/se/17/latestSpec/api/java.instrument/java/lang/instrument/Instrumentation.html#retransformClasses(java.lang.Class..</a>.) </div>
                      <div>[1] <a href="https://cr.openjdk.java.net/~iris/se/17/latestSpec/specs/jvmti.html#RetransformClasses" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://cr.openjdk.java.net/~iris/se/17/latestSpec/specs/jvmti.html#RetransformClasses</a></div>
                      <blockquote style="margin:0px 0px 0px
                        0.8ex;border-left:1px solid
                        rgb(204,204,204);padding-left:1ex">
                        <div>
                          <div dir="ltr">
                            <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)"><br>
                              <br>
                              <br>
                              At present developers usually resort to
                              something like <br>
                              <br>
clazz.getClassLoader().getResourceAsStream(<br>
                                  clazz.getName().replace(".", "/") +
                              ".class")<br>
                              <br>
                              Ignoring the fact that we may have just
                              forced an expensive network fetch, to
                              bytes that the JVM clearly already has
                              'squirrelled away' somewhere...
                              <br>
                              <br>
                              For me this is hugely problematic as there
                              is no guarentee that the bytes fetched
                              from such a stream will match the bytes
                              that the JVM is using for the class in
                              question....
                              <br>
                              <br>
                              Java offers all sorts of opportunities
                              (JVMTI agents, Java agents, even custom
                              ClassLoaders) for mutating the incoming
                              classfile's bytes. All of which the stream
                              fetched via getResourceAsStream()
                              completely sidesteps.<br>
                            </div>
                          </div>
                        </div>
                      </blockquote>
                      <div><br>
                      </div>
                      <div>See above (or the JVMTI spec) for which bytes
                        get passed through to agents.  The story is more
                        complex than it first appears.</div>
                      <div><br>
                      </div>
                      <div>--Dan</div>
                      <div> </div>
                      <blockquote style="margin:0px 0px 0px
                        0.8ex;border-left:1px solid
                        rgb(204,204,204);padding-left:1ex">
                        <div>
                          <div dir="ltr">
                            <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)"><br>
                              This may well be considered 'out of
                              bounds' for the Classfile API, but I think
                              we should consider it, as it seems to be
                              something that users of the Classfile API
                              will need going forward.
                              <br>
                            </div>
                            <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)"><br>
                            </div>
                            <div style="font-family:Calibri,Arial,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0);background-color:rgb(255,255,255)">Gary<br>
                            </div>
                          </div>
                        </div>
                      </blockquote>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>