Skip to content

Fix COMPRESSION_ERROR on valid HPACK input#8817

Merged
maskit merged 4 commits intoapache:masterfrom
mrdg:hpack-decode-fix
May 17, 2022
Merged

Fix COMPRESSION_ERROR on valid HPACK input#8817
maskit merged 4 commits intoapache:masterfrom
mrdg:hpack-decode-fix

Conversation

@mrdg
Copy link
Copy Markdown
Contributor

@mrdg mrdg commented May 4, 2022

This fixes a bug that causes a valid http2 header value to be rejected with a COMPRESSION_ERROR:

With the test input I added, a leaf node is found exactly on a byte boundary. Because the leaf node check happens before the shift check, byte_boundary_crossed is set to 0, but then immediately incremented again. And because finding the next leaf node crosses three byte boundaries, we end up with 4 total and return an error. Reordering the checks fixes the issue.

Note: I wasn't able to run the whole test suite so I'm not sure if this breaks anything else.

@randall randall added this to the 10.0.0 milestone May 4, 2022
@randall randall added the HTTP/2 label May 4, 2022
@randall
Copy link
Copy Markdown
Contributor

randall commented May 4, 2022

@ezelkow1 Can you kick off builds here?

@mrdg
Copy link
Copy Markdown
Contributor Author

mrdg commented May 6, 2022

I found that my first commit still had problems: the byte_boundary_crossed > 3 check still fails for some valid inputs. When a code is more than 3 bytes long, and starts right before a byte boundary, you still cross 4 byte boundaries. I think the better approach is to count the number of bits parsed and check that you don't exceed the length of longest code in the table. I did that in f70728a. This should catch some other invalid inputs that the previous approach didn't catch (see added tests).

@maskit
Copy link
Copy Markdown
Member

maskit commented May 9, 2022

Thank you for the fix. I ran test_HPACK with a couple of external test data and I was realized that current HPACK decoder seems to be broken and it's still broken even with your fix.

What I did are:

$ cd trafficserver/proxy/http2
$ git clone https://github.com/http2jp/hpack-test-case.git
$ ./test_HPACK -i hpack-test-case/go-hpack/

test_HPACK(16235,0x10da86600) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
32 test stories
REGRESSION_TEST initialization begun
REGRESSION TEST HPACK_Encoding started
    REGRESSION_RESULT HPACK_Encoding:                           PASSED
REGRESSION TEST HPACK_Decoding started
BX=c99r6jp89a7nou0026b=3u0026s=q4; localization=en-us%3Bus%3Bus <-> BX=c99r6jp89a7no&b=3&s=q4; localization=en-us%3Bus%3Bus
RPRINT HPACK_Decoding: Story 8 sequence 1 failed.
    REGRESSION_RESULT HPACK_Decoding:                           FAILED
REGRESSION TEST Regression started
RPRINT Regression: regression test
RPERF Regression.speed 100.000000
    REGRESSION_RESULT Regression:                               PASSED

It might be an error in the test data, but I think I checked ATS can decode all the encoded data from different implementations when we were actively working on HTTP/2 and HPACK. Let me check the error above first.

I haven't looked into your change closely, but I'd suggest to move the test case you added into test_HuffmanCode since it's purely for Huffman decoding.

@maskit
Copy link
Copy Markdown
Member

maskit commented May 9, 2022

Seems like the errors I found are due to incompatibility between the test data and test program. We can ignore the errors for now.

And good news is that your change passed all the test we can try. I'll look into your change closely later.

@bryancall bryancall added the Bug label May 9, 2022
@bryancall bryancall requested a review from maskit May 9, 2022 23:06
Copy link
Copy Markdown
Member

@maskit maskit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it failed on a test in HTTP/2 test suite (h2spec). I thought this test is ran on CI but it didn't catch the error somehow.

I ran h2spec locally and got this error below.

HPACK: Header Compression for HTTP/2
  5. Primitive Type Representations
    5.2. String Literal Representation
      using source address 127.0.0.1:62782
      × 3: Sends a Huffman-encoded string literal representation containing the EOS symbol
        -> The endpoint MUST treat this as a decoding error.
           Expected: GOAWAY Frame (Error Code: COMPRESSION_ERROR)
                     Connection closed
             Actual: DATA Frame (length:219, flags:0x01, stream_id:1)

I get your fix is needed for the byte boundary issue but the error above need to be fixed.

Also, to give a bit of context about byte_boundary_crossed, it was added for another test case in h2spec.
#2172

@mrdg mrdg force-pushed the hpack-decode-fix branch from f70728a to 054194d Compare May 13, 2022 06:58
@mrdg
Copy link
Copy Markdown
Contributor Author

mrdg commented May 13, 2022

@maskit sorry for the delay: I had to update my machine to get the autest suite to run. I pushed a fix for the failing EOS test. That fix itself made one of the Huffman tests fail, because it was trying to decode an EOS symbol, which is invalid, so I changed it to check for an error.

I also moved the tests I added to test_Huffmancode.cc

Copy link
Copy Markdown
Member

@maskit maskit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the updates. I confirmed all the tests pass.

@maskit maskit merged commit d362729 into apache:master May 17, 2022
zwoop pushed a commit that referenced this pull request May 25, 2022
* Check for leaf node after resetting byte counter

* Improve invalid decoding length

* Move error tests to test_Huffmancode

* Reject EOS symbol

(cherry picked from commit d362729)
@zwoop
Copy link
Copy Markdown
Contributor

zwoop commented May 25, 2022

Cherry-picked to v9.2.x

@zwoop zwoop modified the milestones: 10.0.0, 9.2.0 May 25, 2022
moonchen pushed a commit to moonchen/trafficserver that referenced this pull request Jul 26, 2022
* Check for leaf node after resetting byte counter

* Improve invalid decoding length

* Move error tests to test_Huffmancode

* Reject EOS symbol

(cherry picked from commit d362729)

Co-authored-by: Menno de Gier <mrdegier@gmail.com>
masaori335 pushed a commit to masaori335/trafficserver that referenced this pull request Feb 21, 2023
* asf/9.2.x:
  Updated ChangeLog
  Restore down nameservers after they come back online (apache#8847)
  Fix Rocky Linux 8 arm64 GCC Compiler Warnings (apache#8850)
  Fix `COMPRESSION_ERROR` on valid HPACK input (apache#8817)
  remap_stats: convert to using TSHttpTxnPristineUrlGet and TSHttpTxnClientReqGet for hostname, remove pre remap continuation (apache#8362)
  Re-introduce import to get man_pages list available for sphinx. Closes apache#8858 (apache#8859)
  Add missing configuration files man pages (apache#8861)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants