Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-3635

[Java] BinaryDecoder trapped into infinite loop while decode crafted data

Add voteVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.11.0
    • 1.12.0
    • java
    • None

    Description

      stackrace:

       

      "DataComputingThread5" #58 prio=5 os_prio=0 tid=0x0000ffff8ab4b000 nid=0x13907 runnable [0x0000ffff3ce11000]
         java.lang.Thread.State: RUNNABLE
          at org.apache.avro.io.BinaryDecoder.doSkipItems(BinaryDecoder.java:454)
          at org.apache.avro.io.BinaryDecoder.skipArray(BinaryDecoder.java:473)
          at org.apache.avro.generic.GenericDatumReader.skip(GenericDatumReader.java:576)
          at org.apache.avro.io.FastReaderBuilder.lambda$initializeRecordReader$0(FastReaderBuilder.java:159)
          at org.apache.avro.io.FastReaderBuilder$$Lambda$652/470404086.execute(Unknown Source)
          at org.apache.avro.io.FastReaderBuilder$RecordReader.read(FastReaderBuilder.java:576)
          at org.apache.avro.io.FastReaderBuilder.lambda$createUnionReader$30(FastReaderBuilder.java:413)
          at org.apache.avro.io.FastReaderBuilder$$Lambda$679/1790128078.read(Unknown Source)
          at org.apache.avro.io.FastReaderBuilder.lambda$createFieldSetter$1(FastReaderBuilder.java:182)
      ... 

       

      specific code:

      private long doSkipItems() throws IOException {
          long result;
          for(result = this.readLong(); result < 0L; result = this.readLong()) {
              long bytecount = this.readLong();
              this.doSkipBytes(bytecount);
          }
      
          return result;
      }
      
      protected void doSkipBytes(long length) throws IOException {
          int remaining = this.limit - this.pos;
          if (length <= (long)remaining) {
              this.pos = (int)((long)this.pos + length);
          } else {
              this.limit = this.pos = 0;
              length -= (long)remaining;
              this.source.skipSourceBytes(length);
          }
      
      } 

      if the bytecount is negative, during doSkipBytes, the pos is moved forward. As a result, the previous data is parsed repeatedly.

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            bismillah bismillah

            Dates

              Created:
              Updated:

              Slack

                Issue deployment