Bug #115551 comp_err hits AddressSanitizer: stack-buffer-overflow
Submitted: 10 Jul 2024 1:09 Modified: 27 Jul 2024 0:12
Reporter: david zhang Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Compiling Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any
Tags: ASAN build

[10 Jul 2024 1:09] david zhang
Description:
During server compilation, mysql server errors are generated using comp_err.

comp_err parses errmsg input line-by-line while
performing backslash unescape. str index calc error
leads to stack buffer overflow.

09:26:37 [ 21%] Built target comp_err
09:26:37 [ 21%] Generating ../include/mysqld_error.h, ../share/english/errmsg.sys
09:26:37 =================================================================
09:26:37 ==801084==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff80f9ac38 at pc 0x00000046367b bp 0x7fff80f9a570 sp 0x7fff80f99d18
09:26:37 READ of size 693 at 0x7fff80f9ac38 thread T0
09:26:37     #0 0x46367a in memmove (####/runtime_output_directory/comp_err+0x46367a)
09:26:37     #1 0x506f7a in parse_text_line ####/utilities/comp_err.cc:1194
09:26:37     #2 0x5073e7 in parse_message_string ####/utilities/comp_err.cc:975
09:26:37     #3 0x50a2ed in parse_input_file ####/utilities/comp_err.cc:576
09:26:37     #4 0x50b5a7 in main ####/utilities/comp_err.cc:205
09:26:37     #5 0x7f26ea6f6444 in __libc_start_main (/lib64/libc.so.6+0x22444)
09:26:37     #6 0x40960c  (####/runtime_output_directory/comp_err+0x40960c)
09:26:37 
09:26:37 Address 0x7fff80f9ac38 is located in stack of thread T0 at offset 1192 in frame
09:26:37     #0 0x509ec0 in parse_input_file ####/utilities/comp_err.cc:524
09:26:37 
09:26:37   This frame has 3 object(s):
09:26:37     [32, 48) 'current_message'
09:26:37     [96, 136) '_db_trace'
09:26:37     [192, 1192) 'buff' <== Memory access at offset 1192 overflows this variable
09:26:37 HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
09:26:37       (longjmp and C++ exceptions *are* supported)
09:26:37 SUMMARY: AddressSanitizer: stack-buffer-overflow (####/runtime_output_directory/comp_err+0x46367a) in memmove
09:26:37 Shadow bytes around the buggy address:
09:26:37   0x1000701eb530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37   0x1000701eb540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37   0x1000701eb550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37   0x1000701eb560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37   0x1000701eb570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37 =>0x1000701eb580: 00 00 00 00 00 00 00[f2]f2 f2 f3 f3 f3 f3 00 00
09:26:37   0x1000701eb590: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f2 f2 f2
09:26:37   0x1000701eb5a0: f2 f2 f2 f2 00 f2 f2 f2 f2 f2 f2 f2 00 00 00 00
09:26:37   0x1000701eb5b0: 00 f2 f2 f2 f3 f3 f3 f3 00 00 00 00 00 00 00 00
09:26:37   0x1000701eb5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37   0x1000701eb5d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
09:26:37 Shadow byte legend (one shadow byte represents 8 application bytes):
09:26:37   Addressable:           00
09:26:37   Partially addressable: 01 02 03 04 05 06 07 
09:26:37   Heap left redzone:       fa
09:26:37   Freed heap region:       fd
09:26:37   Stack left redzone:      f1
09:26:37   Stack mid redzone:       f2
09:26:37   Stack right redzone:     f3
09:26:37   Stack after return:      f5
09:26:37   Stack use after scope:   f8
09:26:37   Global redzone:          f9
09:26:37   Global init order:       f6
09:26:37   Poisoned by user:        f7
09:26:37   Container overflow:      fc
09:26:37   Array cookie:            ac
09:26:37   Intra object redzone:    bb
09:26:37   ASan internal:           fe
09:26:37   Left alloca redzone:     ca
09:26:37   Right alloca redzone:    cb
09:26:37 ==801084==ABORTING
09:26:37 make[2]: *** [include/mysqld_error.h] Error 1
09:26:37 make[1]: *** [utilities/CMakeFiles/GenError.dir/all] Error 2
09:26:37 make: *** [all] Error 2

How to repeat:
build mysqld with debug and asan on

Suggested fix:
root cause is from comp_err.cc calculating
memmove length. Fix the length arithmetic.

looks to me like a day-0 bug

see attached patch (if I figure out how to attach)
[10 Jul 2024 9:05] MySQL Verification Team
Hello david zhang,

Thank you for the report and feedback.
Could you please share exact make options used for the build, OS details etc.? Thank you.

regards,
Umesh
[10 Jul 2024 17:54] david zhang
relevant args to cmake

-DWITH_ASAN=1-DWITH_DEBUG=1

I believe this issue is not specific to any OS/CPU Arch. But for completeness we're using Linux, x86, devtoolset-7

It is worth noting that we triggered ASAN due to a long error message we added in our branch.  in comp_err.cc buff is stack allocated to 1000 chars.  with typical short error messages this condition is never detected.

see below:

static int parse_input_file(const char *file_name, struct errors **top_error,
                            struct languages **top_lang) {
  FILE *file;
  char *str, buff[1000];
[25 Jul 2024 13:30] MySQL Verification Team
Hello David zhang,

Thank you for the feedback.
I'm not able to reproduce on any platforms(with ASAN builds), unless I make changes to share/messages_to_*.txt files. Verifying for now so that dev's can take a call on this.  Could you please confirm exact version where you were seeing this? Thank you.

Looking at the recent source https://github.com/mysql/mysql-server/blame/596f0d238489a9cf9f43ce1ff905984f58d227b6/utili...

there was a temp fix to avoid issue on few platforms(char *str, buff[2000];).

regards,
Umesh
[27 Jul 2024 0:12] david zhang
increasing buff size is a work-around which fools ASAN

but the root cause are the length calculations in memmove()

I suggest undo the work-around to expose the issue cleanly.