diff options
| author | Alexey Samsonov <vonosmas@gmail.com> | 2014-09-12 19:51:26 +0000 |
|---|---|---|
| committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-09-12 19:51:26 +0000 |
| commit | 0e8364e91254c5cb410a47472557981cb56d961f (patch) | |
| tree | 3346a1f2609d4a5bc4d91dd39a4c1ff4fc76e3c7 | |
| parent | 63e3a29ff3e4050e615a56127b7789cdc15f520f (diff) | |
| download | bcm5719-llvm-0e8364e91254c5cb410a47472557981cb56d961f.tar.gz bcm5719-llvm-0e8364e91254c5cb410a47472557981cb56d961f.zip | |
[UBSan] Don't overflow when calculating memory range that should be dumped
llvm-svn: 217703
| -rw-r--r-- | compiler-rt/lib/ubsan/ubsan_diag.cc | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cc b/compiler-rt/lib/ubsan/ubsan_diag.cc index cb9349f3222..4a03aa38577 100644 --- a/compiler-rt/lib/ubsan/ubsan_diag.cc +++ b/compiler-rt/lib/ubsan/ubsan_diag.cc @@ -193,24 +193,34 @@ static Range *upperBound(MemoryLocation Loc, Range *Ranges, return Best; } +static inline uptr subtractNoOverflow(uptr LHS, uptr RHS) { + return (LHS < RHS) ? 0 : LHS - RHS; +} + +static inline uptr addNoOverflow(uptr LHS, uptr RHS) { + const uptr Limit = (uptr)-1; + return (LHS > Limit - RHS) ? Limit : LHS + RHS; +} + /// Render a snippet of the address space near a location. static void renderMemorySnippet(const Decorator &Decor, MemoryLocation Loc, Range *Ranges, unsigned NumRanges, const Diag::Arg *Args) { - const unsigned BytesToShow = 32; - const unsigned MinBytesNearLoc = 4; - // Show at least the 8 bytes surrounding Loc. - MemoryLocation Min = Loc - MinBytesNearLoc, Max = Loc + MinBytesNearLoc; + const unsigned MinBytesNearLoc = 4; + MemoryLocation Min = subtractNoOverflow(Loc, MinBytesNearLoc); + MemoryLocation Max = addNoOverflow(Loc, MinBytesNearLoc); + MemoryLocation OrigMin = Min; for (unsigned I = 0; I < NumRanges; ++I) { Min = __sanitizer::Min(Ranges[I].getStart().getMemoryLocation(), Min); Max = __sanitizer::Max(Ranges[I].getEnd().getMemoryLocation(), Max); } // If we have too many interesting bytes, prefer to show bytes after Loc. + const unsigned BytesToShow = 32; if (Max - Min > BytesToShow) - Min = __sanitizer::Min(Max - BytesToShow, Loc - MinBytesNearLoc); - Max = Min + BytesToShow; + Min = __sanitizer::Min(Max - BytesToShow, OrigMin); + Max = addNoOverflow(Min, BytesToShow); // Emit data. for (uptr P = Min; P != Max; ++P) { |

