Post on 31-May-2020
UndefinedBehaviorin2017
JohnRegehrUniversityofUtah,USA
Today:• Whatisundefinedbehavior(UB)?• Whydoesitexist?• WhataretheconsequencesofUBinCandC++?• ModernUBdetecFonandmiFgaFon
sqrt(-1)=?• i• NaN• Anarbitraryvalue• ThrowanexcepFon• Aborttheprogram• Undefinedbehavior
• Undefinedbehavior(UB)isadesignchoice• UBisthemostefficientalternaFvebecauseitimposesthefewestrequirements– “…behavior,uponuseofanonportableorerroneousprogramconstructoroferroneousdata,forwhichthisInternaFonalStandardimposesnorequirements”
CandC++havelotsofUB• Toavoidoverhead• Toavoidcompilercomplexity• ToprovidemaximalcompaFbilityacrossimplementaFonsandtargets
AccordingtoAppendixJofthestandard,C11has199undefinedbehaviors• Butthislistisn’tcomplete• Andthere’snocomparablelistforC++• AndnewUBsarebeingadded
From:hTp://en.cppreference.com/w/cpp/language/staFc_cast
Whathappenswhenyouexecuteundefinedbehavior?• Case1:Programbreaksimmediately(segfault,mathexcepFon)
• Case2:ProgramconFnues,butwillfaillater(corruptedRAM,etc.)
• Case3:Programworksasexpected– However,theUBisa“Fmebomb”–alatentproblemwaiFngtogooffwhenthecompiler,compilerversion,orcompilerflagsischanged
• Case4:Youdon’tknowhowtotriggertheUBbutsomeoneelsedoes
Importanttrendsoverthelast25years:• UBdetecFontoolshavebeengebngbeTer– StarFngperhapswithPurifyintheearly1990s– Moreabouttheselater
• CompilershavebeengebngclevereratexploiFngUBtoimprovecodegeneraFon– MakingtheFmebombsgooff– Moreaboutthissoon
• SecurityhasbecomeaprimaryconsideraFoninsodwaredevelopment
• ButofcourselegacyCandC++containplentyofUB
• Whatcanwedoaboutthat?– SaneopFon1:Gobackandfixtheoldcode
• Expensive...– SaneopFon2:StopsebngoffFmebombsbymakingopFmizersmoreaggressive
– Notassane:KeepmakingopFmizersmoreaggressivewhilealsonotinvesFnginmaintenanceofoldercodes
int foo (int x) { return (x + 1) > x; } int main() { printf("%d\n", (INT_MAX + 1) > INT_MAX); printf("%d\n", foo(INT_MAX)); return 0; } $ gcc -O2 foo.c ; ./a.out 0 1
int main() { int *p = (int *)malloc(sizeof(int)); int *q = (int *)realloc(p, sizeof(int)); *p = 1; *q = 2; if (p == q) printf("%d %d\n", *p, *q); } $ clang –O foo.c ; ./a.out 1 2
void foo(char *p) { #ifdef DEBUG printf("%s\n", p); #endif if (p) bar(p); }
_foo: testq %rdi, %rdi je L1 jmp _bar L1: ret
Without-DDEBUG
void foo(char *p) { #ifdef DEBUG printf("%s\n", p); #endif if (p) bar(p); }
_foo: pushq %rbx movq %rdi, %rbx call _puts movq %rbx, %rdi popq %rbx jmp _bar
With-DDEBUG
void foo(int *p, int *q, size_t n) { memcpy(p, q, n); if (!q) abort(); }
_foo: jmp memcpy
OpBmizaBonisvalidevenwhenn==0
TherearealotmoreUBs!• Strictaliasing– Iftwopointersrefertodifferenttypes,compilermayassumetheydon’trefertothesameobject
– Vastmajorityofprogramsviolatestrictaliasing• Infiniteloopsthatdon’tcontainside-effecFngoperaFonsareUB– Commoncase:compilercausesthelooptoexit– InC11thecompilercannotterminateaninfiniteloopswhosecontrollingexpressionisaconstantexpression• Sothenwecanatleastrelyonwhile (1) …
• EffectsofUBcanprecedethefirstundefinedoperaFon– PotenFallyundefinedoperaFonsarenotseenasside-effecFng
– CompilercanmoveacrashingoperaFoninfrontofadebugprintout!
– ThisisexplicitintheC++standard:
SowhatcandoweaboutUBinCandC++?• StaFcdetecFon• DynamicdetecFon• MiFgaFon
StaFcanalysis• Enableandheedcompilerwarnings– Use–Werror
• CodereviewersshouldbethinkingaboutUB• RununsoundstaFcanalysistools– Coverity– ClangstaFcanalyzer– Lotsmore
• RunsoundstaFcanalysistools– PolyspaceAnalyzer– Frama-C/TISAnalyzer
DynamicAnalysisusingClang(andGCC)• AddressSaniFzer(ASan)– Memorysafetyerrors
• UndefinedBehaviorSaniFzer(UBSan)– Shiderrors,signedintegeroverflow,alignmentissues,missingreturnstatements,etc.
• MemorySaniFzer(MSan)– UseofuniniFalizedstorage
• ThreadSaniFzer(TSan)– Dataraces,deadlocks
• Dynamicanalysisisgreat,sinceyougetaconcreteexecuFontrace
• Dynamicanalysisisterrible,sinceyouneedtestcasestodriveconcreteexecuFontraces
• Wheredowegetconcreteinputs?– Testsuites– Fuzzers– …
Missingdynamicanalysistools• Strictaliasing• Non-terminaFngloops• Unsequencedsideeffects– InafuncFonargumentlist– Inanexpression
UBMiFgaFon• Linuxcompileswith-fno-delete-null-pointer-checks
• MySQLcompileswith–fwrapv • Manyprogramscompilewith-fno-strict-aliasing
• PartsofAndroiduseUBSaninproducFon• Chromeisbuiltwithcontrolflowintegrity(CFI)enabledinx86-64– ProvidedbyrecentLLVMs– Overhead<1%
IssueswithUBmiFgaFon• SoluFonsaren’tstandardizedorportable• There’snomiFgaFonforconcurrencyerrors• MemorysafetyerrormiFgaFontendstobeexpensiveandmaybreakcode– AndASanisnotahardeningtool
• UBSancanbeconfiguredasahardeningtool– SodwaredevelopersneedtodecideiftheywanttoturnapotenFalexploitintoacrash
Summary
• UBissFllaseriousproblem– It’sprobablytoolatetofixtheCorC++standard– There’shopeforsaferdialects
• ToolsformanagingUBaresteadilyimproving• AllofstaFcdetecFon,dynamicdetecFon,andmiFgaFonshouldbeused– SodwaretesFngremainsextremelydifficult
Thanks!