I am still continuing my search on the issue.
It seems that the issue is rising from pylsqpack.
When the value field in the packet header for HTTP3 GET request contains
long strings there are problems while encoding (Only in s390x).
Due to this one of the GET parameters gets jumbled and this results in a bad request.
I am not able to see the same issue on ls-qpack though.
I will update any new findings.
On Sun, Mar 16, 2025 at 12:12:08PM +0000, Pranav P wrote:
I am still continuing my search on the issue.
It seems that the issue is rising from pylsqpack.
When the value field in the packet header for HTTP3 GET request contains >>long strings there are problems while encoding (Only in s390x).
Due to this one of the GET parameters gets jumbled and this results in a bad request.
I am not able to see the same issue on ls-qpack though.
I will update any new findings.
Yes, I was just going through this today (I hadn't noticed your emails
until after I'd spent some time on it) and I found much the same
thing. I reduced it to the following more manageable test case:
# amd64
(b'', [(b':path', b'/dns-query?dns=AAABAAABAAAAAAAAAAABAAABAAAAAAAAA2RucwZnb29nbGUAAAEAAQ')])import pylsqpack
encoder = pylsqpack.Encoder()
decoder = pylsqpack.Decoder(4096, 16)
_, frame = encoder.encode(0, [(b':path', b'/dns-query?dns=AAABAAABAAAAAAAAAAABAAABAAAAAAAAA2RucwZnb29nbGUAAAEAAQ')])
decoder.feed_header(0, frame)
# s390x
(b'', [(b':path', b'd/snq-euyrd?snA=AAABAAABAAAAAAAAAAABAAABAAAAAAAAR2cuZwbn92bnUGAAAEAAQ')])import pylsqpack
encoder = pylsqpack.Encoder()
decoder = pylsqpack.Decoder(4096, 16)
_, frame = encoder.encode(0, [(b':path', b'/dns-query?dns=AAABAAABAAAAAAAAAAABAAABAAAAAAAAA2RucwZnb29nbGUAAAEAAQ')])
decoder.feed_header(0, frame)
In a file called huff-tables.h in ls-qpack, some calculations where happening based on the following code:
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define I(i,j) ((j<<8)|i)
#else
#define I(i,j) ((i<<8)|j)
#endif
Surprisingly when compiled with the c99 standards the #else part was getting executed while for gnu99 #if part was getting triggered.
Writing some #ifdef statements it was found that __BYTE_ORDER and __LITTLE_ENDIAN were not defined when compiled with c99 and hence the macro evaluated to
#if NULL == NULL
which caused the little endian logic of the code to get executed.
In little endian systems, this would not be an issue as either ways only little endian part of the logic will get executed.
__BYTE_ORDER and __LITTLE_ENDIAN are defined in the header file endian.h in glibc.
This header file is automatically included when compiling with gnu99 and not when compiling with c99(This was tested by preprocessing with both c99 and gnu99 with the -E flag passed to gcc).
In the setup.py file of pylsqpack it is mentioned to adhere to c99 standards. >So, adding <endian.h> header file to lsqpack.c file seems to fix the issue.
Please see if the attached patch is fine. I also am not aware of how to submit a patch. So, if the attached patch is all good, can you please guide me on how to submit the patch.
Thanks a lot. I raised an issue with a suggested fix on pylsqpack's github repo
and has
asked them how they want to integrate the changes. I will also raise a PR to ls-qpack's
repo. Meanwhile, I am attaching the patch with a commit message generated via quilt.
I am new to the community so please feel free to share if something is to be modified.
Thanks
Pranav
[https://res.public.onecdn.static.microsoft/assets/mail/file-icon/png/generic_16x16.png]0001-Fix-enddianness-bug-in-pylsqpack-Encoder.encode.patch<https://ibm-my.sharepoint.com/:u:/p/pranav_p7/EcY4vFeM7QpCnoEzfnuMXr0BYOU-u3vndDV3ESeVodixIA>
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 546 |
Nodes: | 16 (3 / 13) |
Uptime: | 29:40:00 |
Calls: | 10,391 |
Calls today: | 2 |
Files: | 14,064 |
Messages: | 6,417,089 |