Provided as an attachment is a (barely) C++ program which demonstrates a "stack use after scope" address sanitizer failure when using bulk cursors.
The pseudo-program:
WtCursor cursor = session.openCursor(tableUri, "bulk");
{
std::string value = "value";
cursor->set_key(cursor.get(), "key1");
cursor->set_value(cursor.get(), value.c_str());
cursor.save();
}
{
cursor->set_key(cursor.get(), "key2"); // gets into `__wt_cursor_copy_release_item(value)` which attempts to copy out the previous value set. But that variable is now out of scope.
cursor->set_value(cursor.get(), "value");
cursor.save();
}
The output:
==13666==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc5e06fe60 at pc 0x000000441504 bp 0x7ffc5e06fa60 sp 0x7ffc5e06f200
READ of size 6 at 0x7ffc5e06fe60 thread T0
#0 0x441503 in memcpy /data/mci/bc90f05be614b5760ea98b96a5a10212/toolchain-builder/tmp/build-llvm.sh-2ni/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:792:5
#1 0x7f081885f774 in __wt_buf_grow_worker /home/dgottlieb/xgen/wiredtiger/src/support/scratch.c:55
#2 0x7f08187910ab in __wt_buf_grow /home/dgottlieb/xgen/wiredtiger/./src/include/buf.i:17
#3 0x7f081879118e in __wt_buf_set /home/dgottlieb/xgen/wiredtiger/./src/include/buf.i:80
#4 0x7f0818794d06 in __wt_cursor_copy_release_item /home/dgottlieb/xgen/wiredtiger/src/cursor/cur_std.c:249
#5 0x7f0818791447 in __cursor_copy_release /home/dgottlieb/xgen/wiredtiger/./src/include/cursor.i:29
#6 0x7f081879741f in __wt_cursor_set_valuev /home/dgottlieb/xgen/wiredtiger/src/cursor/cur_std.c:578
#7 0x7f0818796fa4 in __wt_cursor_set_value /home/dgottlieb/xgen/wiredtiger/src/cursor/cur_std.c:556
#8 0x501885 in main /home/dgottlieb/xgen/scratch/stack_use_after_scope.cpp:28:5
#9 0x7f081777182f in __libc_start_main /build/glibc-LK5gWL/glibc-2.23/csu/../csu/libc-start.c:291
#10 0x427228 in _start (/home/dgottlieb/xgen/scratch/a.out+0x427228)
Address 0x7ffc5e06fe60 is located in stack of thread T0 at offset 224 in frame
#0 0x5011df in main /home/dgottlieb/xgen/scratch/stack_use_after_scope.cpp:5
This frame has 7 object(s):
[32, 40) 'conn' (line 6)
[64, 72) 'cursor' (line 7)
[96, 104) 'session' (line 8)
[128, 160) 'tableUri' (line 11)
[192, 193) 'ref.tmp' (line 11)
[208, 240) 'value' (line 22) <== Memory access at offset 224 is inside this variable
[272, 273) 'ref.tmp15' (line 22)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope /data/mci/bc90f05be614b5760ea98b96a5a10212/toolchain-builder/tmp/build-llvm.sh-2ni/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:792:5 in memcpy
Shadow bytes around the buggy address:
0x10000bc05f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc05f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc05f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc05fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc05fb0: f1 f1 f1 f1 00 f2 f2 f2 00 f2 f2 f2 00 f2 f2 f2
=>0x10000bc05fc0: 00 00 00 00 f2 f2 f2 f2 f8 f2 f8 f8[f8]f8 f2 f2
0x10000bc05fd0: f2 f2 f8 f3 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc05fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc05ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc06000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10000bc06010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==13666==ABORTING
- is depended on by
-
SERVER-43883 Enable WiredTiger cursor copy debug mode in asan builds
-
- Closed
-
- is related to
-
WT-5574 Rolling back a prepared transaction with `cursor_copy` results in a use-after-free
-
- Closed
-
- related to
-
WT-13091 Make cursor_copy debug mode more precise
-
- Closed
-