liaoxin01 opened a new pull request, #68462:
URL: https://github.com/apache/doris/pull/68462
### What problem does this PR solve?
Problem Summary:
A single raw request to the BE HTTP port takes the whole BE process down:
PUT /api/_http_stream HTTP/1.1
Host: <be>
group_commit: async_mode
Content-Length: not_a_number
The client gets no response and times out, FE then fails queries with
`No backend available as scan node`, and `SHOW BACKENDS` reports the BE as
not alive until it is restarted.
Root cause: `HttpStreamAction::_handle_group_commit()` parsed
`Content-Length`
with a bare `std::stoll()`. libevent invokes the header hook from its own C
frames, so the `std::invalid_argument` thrown there unwinds through C code
and
terminates the process. `StreamLoadAction::_can_group_commit()` already
guards
the same parse - the http stream path was missed. Two more attacker
controlled
headers on the same request path have the same defect: `wal_id` in
`HttpStreamAction::on_chunk_data()`, and the deprecated `auth_code` in
`parse_basic_auth()`, which every load action calls.
The fix:
- Add `safe_stoll()` next to the existing `safe_stoi()` in `string_util`, and
parse `Content-Length`, `wal_id` and `auth_code` with it. A malformed value
now fails the request with `INVALID_ARGUMENT`; a malformed `auth_code` is
simply an invalid credential, so authentication fails instead.
- Guard the three libevent hooks in `ev_http_server.cpp`. Handlers are
expected
to report failures through `Status`; this is the last resort that keeps a
missed one from taking the process down - the exception is logged and that
single request is failed, never the BE. It also covers the numeric parses
that
are still unguarded behind other endpoints, for example `segment_index_id`
in
`download_binlog_action.cpp` and `reset_value` in `jeprofile_actions.cpp`.
After the fix the request above is answered with an `INVALID_ARGUMENT` status
and the BE stays alive.
### Release note
Fix a BE crash that could be triggered remotely by a malformed
`Content-Length`,
`wal_id` or `auth_code` header sent to the BE HTTP stream load endpoint.
### Check List (For Author)
- Test: Unit Test
- `be/test/util/string_util_test.cpp`: `StringUtilTest.safe_stoll`
- `be/test/service/http/stream_load_test.cpp`:
`HttpStreamMalformedContentLengthIsRejected`,
`HttpStreamMalformedWalIdIsRejected`
- `be/test/service/http/http_utils_test.cpp`:
`HttpUtilsTest.parse_auth_code`
- These cases are new and have been compile verified locally; the BE UT
run
itself is left to CI.
- Behavior changed: Yes. A malformed numeric header is rejected with
`INVALID_ARGUMENT` (authentication failure for `auth_code`) instead of
crashing the BE.
- Does this need documentation: No
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]