Open usx95 opened 4 months ago
Right now, string annotations are enabled only with libc++ compiled with ASan, and it looks like [it's not the case on godbolt](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:2,endLineNumber:11,positionColumn:2,positionLineNumber:11,selectionStartColumn:2,selectionStartLineNumber:11,startColumn:2,startLineNumber:11),source:'%23include+%3Cstring%3E%0A%23include+%3Ciostream%3E%0A%0A%0Aint+main()+%7B%0A++++std::string+dst,+src+%3D+%221234567890123456789012345678901234567890long%22%3B%0A++++dst.reserve(src.size()+%2B+30)%3B%0A++++dst+%3D+src%3B%0A++++std::cout+%3C%3C+%22c:+%22+%3C%3C+dst%5Bdst.size()+%2B+4%5D+%3C%3C+std::endl%3B%0A++++return+0%3B%0A%7D'),l:'5',n:'1',o:'C%2B%2B+source+%231',t:'0')),k:38.53075642514707,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!((name:fmt,ver:'811')),options:'-Wextra+-Wall+-std%3Dc%2B%2B20+-fsanitize%3Daddress+-stdlib%3Dlibc%2B%2B+-O3',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0')),k:32.360514748877364,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'1',compilationPanelShown:'0',compiler:clang_trunk,compilerName:'',compilerOutShown:'0',execArgs:'',execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-fsanitize%3Daddress+-stdlib%3Dlibc%2B%2B+-std%3Dc%2B%2B20',overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:'1',wrap:'1'),l:'5',n:'0',o:'Executor+x86-64+clang+(trunk)+(C%2B%2B,+Editor+%231)',t:'0')),k:29.10872882597559,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4). UAF from the example should be detected with string annotations, but I will confirm it.
However, container annotations are not necessary to detect UAF as shown here in case of a long string (when external buffer for content is allocated, >=16
for libstdc++ and >=23
for [libc++](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:65,endLineNumber:13,positionColumn:65,positionLineNumber:13,selectionStartColumn:65,selectionStartLineNumber:13,startColumn:65,startLineNumber:13),source:'%23include+%3Cstring%3E%0A%23include+%3Ciostream%3E%0A%23include+%3Cstring_view%3E%0A%0Astruct+MyThing+%7B%0A++++std::string_view+s%3B%0A%7D%3B%0A%0AMyThing+makeThing(std::string+s)+%7B%0A++++return+MyThing%7Bs%7D%3B%0A%7D%0A%0Astd::string+getS()+%7B+return+std::string(%22abcdabcdabcdabcd1231234%22)%3B+%7D%0A%0Aint+main()+%7B%0A++++auto+thing+%3D+makeThing(getS())%3B%0A++++std::cout+%3C%3C+thing.s+%3C%3C+std::endl%3B%0A++++return+0%3B%0A%7D'),l:'5',n:'1',o:'C%2B%2B+source+%231',t:'0')),k:34.12532858401412,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!((name:fmt,ver:'811')),options:'-Wextra+-Wall+-std%3Dc%2B%2B20+-fsanitize%3Daddress+-stdlib%3Dlibc%2B%2B',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0')),k:31.490414230772725,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:tool,i:(args:'-checks%3Dclang-analyzer-*',argsPanelShown:'1',editorid:1,fontScale:14,fontUsePx:'0',j:1,monacoEditorHasBeenAutoOpened:'1',monacoEditorOpen:'1',monacoStdin:'1',stdin:'',stdinPanelShown:'1',toolId:clangtidytrunk,wrap:'1'),l:'5',n:'0',o:'clang-tidy+(trunk)+x86-64+clang+(trunk)+(Editor+%231,+Compiler+%231)',t:'0')),k:1.1794162633248197,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+clang+15.0.0',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+(trunk)+(Compiler+%231)',t:'0')),k:33.20484092188836,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)), because external memory is freed in the destructor, the error is reported.
In case of a short string, content is inside the object, so nothing is freed in the destructor. I believe (to be confirmed) it's not detected here, because the string is created in mains' stack frame and the frame is not yet freed.
If getS()
is called in another function, [UAF is detected](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:2,endLineNumber:19,positionColumn:2,positionLineNumber:19,selectionStartColumn:2,selectionStartLineNumber:19,startColumn:2,startLineNumber:19),source:'%23include+%3Cstring%3E%0A%23include+%3Ciostream%3E%0A%23include+%3Cstring_view%3E%0A%0Astruct+MyThing+%7B%0A++++std::string_view+s%3B%0A%7D%3B%0A%0AMyThing+makeThing(std::string+s)+%7B+return+MyThing%7Bs%7D%3B+%7D%0A%0Astd::string+getS()+%7B+return+%22short%22%3B+%7D%0A%0AMyThing+foo()+%7B+return+makeThing(getS())%3B+%7D%0A%0Aint+main()+%7B%0A++++auto+thing+%3D+foo()%3B%0A++++std::cout+%3C%3C+%22S:+%22+%3C%3C+thing.s+%3C%3C+std::endl%3B%0A++++return+0%3B%0A%7D'),l:'5',n:'1',o:'C%2B%2B+source+%231',t:'0')),k:38.53075642514707,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!((name:fmt,ver:'811')),options:'-Wextra+-Wall+-std%3Dc%2B%2B20+-fsanitize%3Daddress+-stdlib%3Dlibc%2B%2B',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0')),k:27.7910842482704,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:executor,i:(argsPanelShown:'1',compilationPanelShown:'0',compiler:clang_trunk,compilerName:'',compilerOutShown:'0',execArgs:'',execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-fsanitize%3Daddress+-stdlib%3Dlibc%2B%2B',overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:'1',wrap:'1'),l:'5',n:'0',o:'Executor+x86-64+clang+(trunk)+(C%2B%2B,+Editor+%231)',t:'0')),k:33.67815932658255,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4).
I'm not sure if we can do something here. Have to confirm that ASan with container annotations (string annotations) detects it.
https://godbolt.org/z/dj8K3xb17
Is this a known false negative ? Works fine with strings with a length
>=16
. https://godbolt.org/z/8cGT7b38n