Based on the ASAN report, it looks like we are invoking strnxmov incorrectly, or there is a bug in strnxmov that causes it to exceed the specified size FN_REFLEN (512 bytes). As far as I can tell, the maximum possible name length here is something like 645 bytes (including a path component separator character FN_LIBCHAR and the reg_ext suffix .frm). If there is some ./ prepended, the name could be even longer. We also need to reserve one byte for the terminating NUL character.
If strxnmov() itself did not cause a buffer overflow, the call would still have to be fixed to detect that an overflow would have occurred, to avoid invoking access on a truncated string of 512 characters that is not NUL terminated. Something like this, using a standard library function:
That is, if the file name length exceeds 511 bytes, we assume that the file does not exist. Linux for example limits the path component length to 255 bytes, so 512 bytes are just enough for databasename/filename.frm and a terminating NUL character.
Marko Mäkelä
added a comment - The following code was added in MDEV-11412 :
static bool frm_file_exists( const char *path)
{
char buff[FN_REFLEN];
strxnmov(buff, FN_REFLEN, path, reg_ext, NullS);
return !access(buff, F_OK);
}
Based on the ASAN report, it looks like we are invoking strnxmov incorrectly, or there is a bug in strnxmov that causes it to exceed the specified size FN_REFLEN (512 bytes). As far as I can tell, the maximum possible name length here is something like 645 bytes (including a path component separator character FN_LIBCHAR and the reg_ext suffix .frm ). If there is some ./ prepended, the name could be even longer. We also need to reserve one byte for the terminating NUL character.
If strxnmov() itself did not cause a buffer overflow, the call would still have to be fixed to detect that an overflow would have occurred, to avoid invoking access on a truncated string of 512 characters that is not NUL terminated. Something like this, using a standard library function:
char buff[FN_REFLEN];
return snprintf(buff, sizeof buff, "%s%s" , path, reg_ext) < sizeof buff &&
!access(buff, F_OK);
That is, if the file name length exceeds 511 bytes, we assume that the file does not exist. Linux for example limits the path component length to 255 bytes, so 512 bytes are just enough for databasename/filename.frm and a terminating NUL character.
Vladislav Vaintroub
added a comment - On Windows, debug compilation, it also crashes, thanks to runtime checks (/RTC1), which is on by default in debug compile
Error:Run-Time Check Failure #2 - Stack around the variable 'buff' was corrupted. At :0
240521 14:50:53 [ERROR] mysqld got exception 0x80000003 ;
Sorry, we probably made a mistake, and this is a bug.
Your assistance in bug reporting will enable us to fix this for the next release.
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
Server version: 10.5.26-MariaDB-debug-log source revision: 310fd6ff695541247db766baf3ade1e3b4db16e9
key_buffer_size=1048576
read_buffer_size=131072
max_used_connections=3
max_threads=65537
thread_count=1
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 25170481 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0x2c9a6e58f28
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
server.dll!handle_rtc_failure()[my_init.c:303]
server.dll!failwithmessage()[error.cpp:213]
server.dll!_RTC_StackFailure()[error.cpp:263]
server.dll!_RTC_CheckStackVars()[stack.cpp:69]
server.dll!frm_file_exists()[ha_innodb.cc:13318]
server.dll!ha_innobase::delete_table()[ha_innodb.cc:13415]
server.dll!ha_innobase::delete_table()[ha_innodb.cc:13515]
server.dll!hton_drop_table()[handler.cc:568]
server.dll!ha_delete_table()[handler.cc:2863]
server.dll!delete_table_force()[handler.cc:5178]
server.dll!plugin_foreach_with_mask()[sql_plugin.cc:2554]
server.dll!ha_delete_table_force()[handler.cc:5224]
server.dll!mysql_rm_table_no_locks()[sql_table.cc:2601]
server.dll!mysql_rm_table()[sql_table.cc:2164]
server.dll!mysql_execute_command()[sql_parse.cc:5073]
server.dll!mysql_parse()[sql_parse.cc:8204]
server.dll!dispatch_command()[sql_parse.cc:1895]
server.dll!do_command()[sql_parse.cc:1376]
server.dll!threadpool_process_request()[threadpool_common.cc:365]
server.dll!tp_callback()[threadpool_common.cc:199]
server.dll!tp_callback()[threadpool_win.cc:343]
server.dll!work_callback()[threadpool_win.cc:394]
ntdll.dll!RtlHashUnicodeString()
ntdll.dll!RtlClearThreadWorkOnBehalfTicket()
KERNEL32.DLL!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (0x2c9a6e624f0): DROP TABLE `##################################################_long`.`#################################################_long`
Connection ID (thread ID): 4
Status: NOT_KILLED
Optimizer switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
The manual page at https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mariadbd/ contains
information that should help you find out what is causing the crash.
Writing a core file at E:\10.5\xxx\mysql-test\var\mysqld.1\data
Minidump written to E:\10.5\xxx\mysql-test\var\mysqld.1\data\mariadbd.dmp
----------SERVER LOG END-------------
- found 'mariadbd.dmp' (0/5)
Trying 'cdb' to get a backtrace
Output from cdb follows. Faulting thread is printed twice,with and without function parameters
Search for STACK_TEXT to see the stack trace of
the faulting thread. Callstacks of other threads are printed after it.
Microsoft (R) Windows Debugger Version 10.0.19041.685 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [E:\10.5\xxx\mysql-test\var\log\main.drop\mysqld.1\data\mariadbd.dmp]
User Mini Dump File: Only registers, stack and portions of memory are available
Response Time (ms) Location
OK C:\Windows\System32
OK E:\10.5\xxx\sql\Debug
OK .
Response Time (ms) Location
OK C:\Windows\System32
OK E:\10.5\xxx\sql\Debug
OK .
Deferred srv*C:\symbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: C:\Windows\System32;E:\10.5\xxx\sql\Debug;.;srv*C:\symbols*https://msdl.microsoft.com/download/symbols
Executable search path is: C:\Windows\System32;E:\10.5\xxx\sql\Debug;.
Windows 10 Version 22631 MP (16 procs) Free x64
Product: WinNt, suite: SingleUserTS
22621.1.amd64fre.ni_release.220506-1250
Machine Name:
Debug session time: Tue May 21 14:50:54.000 2024 (UTC + 2:00)
System Uptime: 6 days 13:50:42.180
Process Uptime: 0 days 0:00:01.000
....................................
This dump file has a breakpoint exception stored in it.
The stored exception information can be accessed via .ecxr.
For analysis of this file, run !analyze -v
ntdll!NtGetContextThread:
ret
0:016> cdb: Reading initial command '!sym prompts off; !analyze -v; .ecxr; !for_each_frame dv /t;!uniqstack -p;q'
quiet mode - symbol prompts off
KEY_VALUES_STRING: 1
Key : Analysis.CPU.Sec
Value: 0
Key : Analysis.DebugAnalysisProvider.CPP
Value: Create: 8007007e on DESKTOP
Key : Analysis.DebugData
Value: CreateObject
Key : Analysis.DebugModel
Value: CreateObject
Key : Analysis.Elapsed.Sec
Value: 0
Key : Analysis.Memory.CommitPeak.Mb
Value: 240
Key : Analysis.System
Value: CreateObject
Key : Timeline.OS.Boot.DeltaSec
Value: 568242
The bug for the reported test case should have been fixed in MDEV-25691 (MariaDB Server 10.6.1), which removed the function frm_file_exists() and the related tweak in ha_innobase::delete_table(). I see that the fix is correcting invocations of strxnmov() in several other places that also affects 10.6 and later major versions.
Marko Mäkelä
added a comment - The bug for the reported test case should have been fixed in MDEV-25691 (MariaDB Server 10.6.1), which removed the function frm_file_exists() and the related tweak in ha_innobase::delete_table() . I see that the fix is correcting invocations of strxnmov() in several other places that also affects 10.6 and later major versions.
I did not try to figure out whether other strxnmov overwrites are exploitable, or even it is possible to reproduce ASAN failure, just looked for the common pattern, passing sizeof(buffer), where sizeof(buffer)-1 is more commonly used.
Vladislav Vaintroub
added a comment - I did not try to figure out whether other strxnmov overwrites are exploitable, or even it is possible to reproduce ASAN failure, just looked for the common pattern, passing sizeof(buffer), where sizeof(buffer)-1 is more commonly used.
Well, this specific crash was no longer in 10.6, as Marko notes above. However, while fixing this specific 10.5 crash, I also checked and fixed similar wrong invocations of strnxmov , which could mean yet undiscovered similar crashes would be fixed as well.
Vladislav Vaintroub
added a comment - Well, this specific crash was no longer in 10.6, as Marko notes above. However, while fixing this specific 10.5 crash, I also checked and fixed similar wrong invocations of strnxmov , which could mean yet undiscovered similar crashes would be fixed as well.
People
Vladislav Vaintroub
Ramesh Sivaraman
Votes:
0Vote for this issue
Watchers:
8Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":798,"ttfb":235.59999990463257,"pageVisibility":"visible","entityId":129220,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":1,"journeyId":"167b215f-91fe-4794-9cbe-df1459e01056","navigationType":0,"readyForUser":915.9000000953674,"redirectCount":0,"resourceLoadedEnd":559.1999998092651,"resourceLoadedStart":244.2999997138977,"resourceTiming":[{"duration":18.5,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":244.2999997138977,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":244.2999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":262.7999997138977,"responseStart":0,"secureConnectionStart":0},{"duration":18.5,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true&whisper-enabled=true","startTime":244.69999980926514,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":244.69999980926514,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":263.19999980926514,"responseStart":0,"secureConnectionStart":0},{"duration":165.09999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/s/0917945aaa57108d00c5076fea35e069-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":244.90000009536743,"connectEnd":244.90000009536743,"connectStart":244.90000009536743,"domainLookupEnd":244.90000009536743,"domainLookupStart":244.90000009536743,"fetchStart":244.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":267.5,"responseEnd":410,"responseStart":288.40000009536743,"secureConnectionStart":244.90000009536743},{"duration":281.90000009536743,"initiatorType":"script","name":"https://jira.mariadb.org/s/2d8175ec2fa4c816e8023260bd8c1786-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true&whisper-enabled=true","startTime":245.5,"connectEnd":266.2999997138977,"connectStart":266.2999997138977,"domainLookupEnd":266.2999997138977,"domainLookupStart":266.2999997138977,"fetchStart":245.5,"redirectEnd":0,"redirectStart":0,"requestStart":267,"responseEnd":527.4000000953674,"responseStart":280.90000009536743,"secureConnectionStart":266.2999997138977},{"duration":39.30000019073486,"initiatorType":"script","name":"https://jira.mariadb.org/s/a9324d6758d385eb45c462685ad88f1d-CDN/lu2cib/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":245.7999997138977,"connectEnd":245.7999997138977,"connectStart":245.7999997138977,"domainLookupEnd":245.7999997138977,"domainLookupStart":245.7999997138977,"fetchStart":245.7999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":268.09999990463257,"responseEnd":285.09999990463257,"responseStart":283.7999997138977,"secureConnectionStart":245.7999997138977},{"duration":48,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":245.90000009536743,"connectEnd":245.90000009536743,"connectStart":245.90000009536743,"domainLookupEnd":245.90000009536743,"domainLookupStart":245.90000009536743,"fetchStart":245.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":270.09999990463257,"responseEnd":293.90000009536743,"responseStart":292.2999997138977,"secureConnectionStart":245.90000009536743},{"duration":50.09999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":246.09999990463257,"connectEnd":246.09999990463257,"connectStart":246.09999990463257,"domainLookupEnd":246.09999990463257,"domainLookupStart":246.09999990463257,"fetchStart":246.09999990463257,"redirectEnd":0,"redirectStart":0,"requestStart":270.2999997138977,"responseEnd":296.19999980926514,"responseStart":294.09999990463257,"secureConnectionStart":246.09999990463257},{"duration":22.100000381469727,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2cib/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":246.2999997138977,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":246.2999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":268.40000009536743,"responseStart":0,"secureConnectionStart":0},{"duration":50.299999713897705,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":246.5,"connectEnd":246.5,"connectStart":246.5,"domainLookupEnd":246.5,"domainLookupStart":246.5,"fetchStart":246.5,"redirectEnd":0,"redirectStart":0,"requestStart":274.2999997138977,"responseEnd":296.7999997138977,"responseStart":294.69999980926514,"secureConnectionStart":246.5},{"duration":23.90000009536743,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":246.59999990463257,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":246.59999990463257,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":270.5,"responseStart":0,"secureConnectionStart":0},{"duration":59,"initiatorType":"script","name":"https://jira.mariadb.org/s/5d5e8fe91fbc506585e83ea3b62ccc4b-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":246.7999997138977,"connectEnd":246.7999997138977,"connectStart":246.7999997138977,"domainLookupEnd":246.7999997138977,"domainLookupStart":246.7999997138977,"fetchStart":246.7999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":285,"responseEnd":305.7999997138977,"responseStart":302.2999997138977,"secureConnectionStart":246.7999997138977},{"duration":308.09999990463257,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":250.90000009536743,"connectEnd":250.90000009536743,"connectStart":250.90000009536743,"domainLookupEnd":250.90000009536743,"domainLookupStart":250.90000009536743,"fetchStart":250.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":312.19999980926514,"responseEnd":559,"responseStart":552.1999998092651,"secureConnectionStart":250.90000009536743},{"duration":301.90000009536743,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":257.2999997138977,"connectEnd":257.2999997138977,"connectStart":257.2999997138977,"domainLookupEnd":257.2999997138977,"domainLookupStart":257.2999997138977,"fetchStart":257.2999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":315.59999990463257,"responseEnd":559.1999998092651,"responseStart":552.7999997138977,"secureConnectionStart":257.2999997138977},{"duration":109.2000002861023,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":555.1999998092651,"connectEnd":555.1999998092651,"connectStart":555.1999998092651,"domainLookupEnd":555.1999998092651,"domainLookupStart":555.1999998092651,"fetchStart":555.1999998092651,"redirectEnd":0,"redirectStart":0,"requestStart":625.6999998092651,"responseEnd":664.4000000953674,"responseStart":663.5,"secureConnectionStart":555.1999998092651},{"duration":266.09999990463257,"initiatorType":"script","name":"https://www.google-analytics.com/analytics.js","startTime":791.5,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":791.5,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":1057.5999999046326,"responseStart":0,"secureConnectionStart":0},{"duration":269.2000002861023,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":798.2999997138977,"connectEnd":798.2999997138977,"connectStart":798.2999997138977,"domainLookupEnd":798.2999997138977,"domainLookupStart":798.2999997138977,"fetchStart":798.2999997138977,"redirectEnd":0,"redirectStart":0,"requestStart":1031.1999998092651,"responseEnd":1067.5,"responseStart":1066.2999997138977,"secureConnectionStart":798.2999997138977}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":52,"responseStart":236,"responseEnd":257,"domLoading":239,"domInteractive":991,"domContentLoadedEventStart":991,"domContentLoadedEventEnd":1053,"domComplete":1541,"loadEventStart":1541,"loadEventEnd":1541,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":955.0999999046326},{"name":"bigPipe.sidebar-id.end","time":955.9000000953674},{"name":"bigPipe.activity-panel-pipe-id.start","time":955.9000000953674},{"name":"bigPipe.activity-panel-pipe-id.end","time":961},{"name":"activityTabFullyLoaded","time":1070.7999997138977}],"measures":[],"correlationId":"ce02ce79301d4d","effectiveType":"4g","downlink":10,"rtt":0,"serverDuration":110,"dbReadsTimeInMs":14,"dbConnsTimeInMs":22,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
The following code was added in
MDEV-11412:{
strxnmov(buff, FN_REFLEN, path, reg_ext, NullS);
}
Based on the ASAN report, it looks like we are invoking strnxmov incorrectly, or there is a bug in strnxmov that causes it to exceed the specified size FN_REFLEN (512 bytes). As far as I can tell, the maximum possible name length here is something like 645 bytes (including a path component separator character FN_LIBCHAR and the reg_ext suffix .frm). If there is some ./ prepended, the name could be even longer. We also need to reserve one byte for the terminating NUL character.
If strxnmov() itself did not cause a buffer overflow, the call would still have to be fixed to detect that an overflow would have occurred, to avoid invoking access on a truncated string of 512 characters that is not NUL terminated. Something like this, using a standard library function:
!access(buff, F_OK);
That is, if the file name length exceeds 511 bytes, we assume that the file does not exist. Linux for example limits the path component length to 255 bytes, so 512 bytes are just enough for databasename/filename.frm and a terminating NUL character.