Truncated length-encoded authentication response aborts an ASan observer
Self Checks
- I have read the Contributing Guide.
- This is only for bug report, if you would like to ask a question, please head to Discussions.
- I have searched for existing issues search for existing issues, including closed ones.
- I confirm that I am using English to submit this report, otherwise it will be closed.
- 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- Please do not modify this template :) and fill in all the required fields.
OceanBase version
OceanBase CE 5.0.2.0, revision 1-d128661ca4f5b3d167c1928e556d70d2f901baef, built from source HEAD d128661ca4f5b3d167c1928e556d70d2f901baef with Release+ASan.
Self Hosted
Self Hosted (Source)
Environment
OS: Ubuntu 22.04.5 LTS Kernel: Linux 6.5.13-5-pve x86_64 Compiler: Clang 17.0.6 Build: RelWithDebInfo + AddressSanitizer Observer SHA-256: ca68b559c56922e2f652e3b4606a865337c0fe8b51142c689a312aec3554a02d Topology: one zone, loopback listeners only ASAN_OPTIONS=detect_leaks=0:abort_on_error=1:symbolize=1
Steps to reproduce
Use a disposable ASan observer. Do not run this against a production instance.
Start the tested observer on loopback and wait until
root@sysauthentication reaches the normal authentication path. The reviewed server arguments are inartifacts/manifest.json.Compile the attached dedicated PoC:
g++ -std=gnu++17 -O2 -Wall -Wextra -Werror \ poc/observer_lenenc_probe.cpp -o observer_lenenc_probeVerify the well-formed zero-length authentication control receives a response:
./observer_lenenc_probe 38881 controlSend a handshake response with
CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATAand a final lone0xfebyte, with none of the eight required length bytes:./observer_lenenc_probe 38881 truncatedInspect the observer exit status and its ASan log.
Observed PoC output:
MODE=truncated GREETING=74 RESPONSE=no RESPONSE_LEN=0 ERROR=0 ERRNO=0
observer return code: -6 (SIGABRT)Minimal ASan stack:
ERROR: AddressSanitizer: memcpy-param-overlap
#0 __asan_memcpy
#1 write_str_reuse_buf<ObIAllocator> ob_sql_session_info.cpp:3752
#2 ObSQLSessionInfo::set_login_info ob_sql_session_info.cpp:3778
#3 ObMPConnect::load_privilege_info obmp_connect.cpp:756
#4 ObMPConnect::verify_identify obmp_connect.cpp:2466
#5 ObMPConnect::process obmp_connect.cpp:357
Packet allocation path:
#7 ObMysqlProtocolProcessor::decode_hsr_body ob_mysql_protocol_processor.cpp:124
#8 ObMysqlProtocolProcessor::do_decode ob_mysql_protocol_processor.cpp:80Root-cause path: OMPKHandshakeResponse::decode() calls ObMySQLUtil::get_length(pos, len) without
passing the packet end. For marker 0xfe, get_length() consumes eight length bytes without a
remaining-length check. The decoded ASan fill value later reaches set_login_info() as an invalid
authentication length.
✔️ Expected Behavior
The handshake decoder should reject a truncated length-encoded integer, close only that client
connection, and keep the observer healthy. Every 0xfc, 0xfd, and 0xfe marker should require
its complete fixed-width payload before any read or pointer advance.
❌ Actual Behavior
The full Release+ASan observer reads beyond the logical handshake-response tail, derives a bogus
authentication length, and aborts with SIGABRT in set_login_info(). The trigger occurs before a
client is authenticated.
Source: oceanbase/oceanbase