Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes an integer overflow check when parsing the HTTP Content-Length header in the waltz HTTP server and adds a regression test to ensure overflow triggers the expected connection close path.
Changes:
- Replace the
content_len*10 + digitwraparound-based overflow detection with a bounds-based check againstULONG_MAX. - Add a unit test that opens a loopback TCP connection and sends an oversized
Content-Lengthvalue, asserting the server closes withFD_HTTP_SERVER_CONNECTION_CLOSE_LARGE_REQUEST.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
src/waltz/http/test_http_server.c |
Adds a new regression test and supporting helpers to validate overflow handling via a real socket connection. |
src/waltz/http/fd_http_server.c |
Updates Content-Length parsing to use a correct pre-multiply overflow check. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for( ulong i=0UL; i<200UL && !state.close_cnt; i++ ) { | ||
| fd_http_server_poll( http, 1 ); | ||
| } |
There was a problem hiding this comment.
The close-wait loop uses a fixed 200-iteration bound with fd_http_server_poll(http, 1), which can be flaky on slow/loaded CI machines. Consider using a wallclock-based timeout (or a larger bound) so the test fails only after a real elapsed deadline.
| ulong digit = (ulong)(content_length[ i ]-'0'); | ||
| if( FD_UNLIKELY( content_len>(ULONG_MAX-digit)/10UL ) ) { /* Overflow */ | ||
| close_conn( http, conn_idx, FD_HTTP_SERVER_CONNECTION_CLOSE_LARGE_REQUEST ); | ||
| return; | ||
| } | ||
|
|
||
| content_len = next; | ||
| content_len = content_len*10UL + digit; |
There was a problem hiding this comment.
ULONG_MAX is used in the new overflow check, but this translation unit doesn't include <limits.h>. This can fail to compile on toolchains where ULONG_MAX isn't pulled in indirectly. Add an explicit #include <limits.h> near the other standard includes.
There was a problem hiding this comment.
@copilot ULONG_MAX is provided by fd_util_base.h i think
1403930 to
4e4e41e
Compare
Performance Measurements ⏳
|
| ulong next = content_len*10UL + (ulong)(content_length[ i ]-'0'); | ||
| if( FD_UNLIKELY( next<content_len ) ) { /* Overflow */ | ||
| ulong digit = (ulong)(content_length[ i ]-'0'); | ||
| if( FD_UNLIKELY( content_len>(ULONG_MAX-digit)/10UL ) ) { /* Overflow */ |
There was a problem hiding this comment.
Can we just use __builtin_uaddl_overflow here?
| ulong digit = (ulong)(content_length[ i ]-'0'); | ||
| if( FD_UNLIKELY( content_len>(ULONG_MAX-digit)/10UL ) ) { /* Overflow */ | ||
| close_conn( http, conn_idx, FD_HTTP_SERVER_CONNECTION_CLOSE_LARGE_REQUEST ); | ||
| return; | ||
| } | ||
|
|
||
| content_len = next; | ||
| content_len = content_len*10UL + digit; | ||
| } | ||
|
|
||
| ulong total_len = (ulong)result+content_len; |
There was a problem hiding this comment.
@ripatel-fd something like this?
Doesn't look pretty, but would avoid a division although the compiler would have probably replaced the division by constant anyway with something smarter.
| ulong digit = (ulong)(content_length[ i ]-'0'); | |
| if( FD_UNLIKELY( content_len>(ULONG_MAX-digit)/10UL ) ) { /* Overflow */ | |
| close_conn( http, conn_idx, FD_HTTP_SERVER_CONNECTION_CLOSE_LARGE_REQUEST ); | |
| return; | |
| } | |
| content_len = next; | |
| content_len = content_len*10UL + digit; | |
| } | |
| ulong total_len = (ulong)result+content_len; | |
| ulong digit = (ulong)(content_length[ i ]-'0'); | |
| ulong next_content_len; | |
| if( FD_UNLIKELY( __builtin_mul_overflow( content_len, 10UL, &next_content_len ) || | |
| __builtin_add_overflow( next_content_len, digit, &next_content_len ) ) ) { /* Overflow */ | |
| close_conn( http, conn_idx, FD_HTTP_SERVER_CONNECTION_CLOSE_LARGE_REQUEST ); | |
| return; | |
| } | |
| content_len = next_content_len; | |
| } | |
| ulong total_len = (ulong)result+content_len; |
|
@ripatel-fd I've opened a new pull request, #8433, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
|
||
| content_len = next; | ||
| content_len = content_len*10UL + digit; | ||
| } |
There was a problem hiding this comment.
@intrigus-lgtm How about we just copy out the integer string to uchar x[], zero terminate it, and then call https://man7.org/linux/man-pages/man3/strtoumax.3.html for the conversion? IMO that's the cleanest option
There was a problem hiding this comment.
@copilot please implement this suggestion by modifying PR 8391 and submit it as a separate PR. Maintain original attribution
|
@ripatel-fd I've opened a new pull request, #8434, to work on those changes. Once the pull request is ready, I'll request review from you. |
No description provided.