Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHERI CSA: CHERI support for Clang Static Analyzer + cheri.* Checkers #744

Open
wants to merge 77 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
f94a9e9
[CHERI-CSA] Allow ASTContext::getIntWidth() for reference type
eupharina Dec 14, 2022
fb1708e
[CHERI-CSA] Use type IntWidth instead of TypeSize for NULL ptr SVal
eupharina Jun 13, 2024
89216c9
[CHERI-CSA] Improve LocAsInt arithmetic support
eupharina Dec 21, 2022
9066768
[CHERI-CSA] Add provenance bit to LocAsInteger
eupharina Dec 22, 2022
5af293b
[analyzer] scan-build: Retain -nostdinc++ option
eupharina Jan 9, 2023
44ffe23
[CHERI-CSA] Add alpha.cheri.ProvenanceSourceChecker
eupharina Dec 21, 2022
bbda964
[CHERI-CSA] ProvenanceSourceChecker: add subtraction
eupharina Feb 8, 2023
dc71e37
[CHERI-CSA] Add CapabilityCopyChecker
eupharina Feb 16, 2023
66daaa8
[CHERI_CSA] CapabilityCopyChecker: suppress for short loops
eupharina Mar 13, 2023
fb9707f
[CHERI_CSA] CapabilityCopyChecker: suppress for unaligned ptr
eupharina Mar 15, 2023
9d24a62
[CHERI_CSA] CapabilityCopyChecker: silence for hybrid mode
eupharina Jun 22, 2023
1152133
[CHERI-CSA] CapabilityCopyChecker: char* as universal pointer
eupharina Jun 27, 2023
ca199f2
[CHERI-CSA] CapabilityCopyChecker: suppress FP for short copies
eupharina Jul 14, 2023
58d95a9
[CHERI-CSA] CapabilityCopyChecker: improve bug trace
eupharina Jul 14, 2023
41cbcb7
[CHERI_CSA] ProvenanceSourceChecker: silence for hybrid mode
eupharina Jul 24, 2023
cef342e
[CHERI_CSA] CHERIUtils
eupharina Jul 26, 2023
b8f1f00
[CHERI_CSA] Add Capability Alignment Checker
eupharina Jul 26, 2023
ea4adbb
[CHERI_CSA] CapabilityAlignmentChecker: assume align on parameters an…
eupharina Aug 4, 2023
8e8d16d
[CHERI_CSA] CapabilityAlignmentChecker: support align check
eupharina Aug 8, 2023
f1c7332
[CHERI_CSA] CapabilityAlignmentChecker: array element alignment
eupharina Aug 9, 2023
880a375
[CHERI_CSA] CapabilityAlignmentChecker: attribute __aligned__
eupharina Aug 10, 2023
d5ed9a3
[CHERI_CSA] CapabilityAlignmentChecker: BugReporterVisitor
eupharina Aug 14, 2023
31a1238
[CHERI_CSA] CapabilityAlignmentChecker: fix FP for comparison with void*
eupharina Aug 15, 2023
bdb8b4c
[CHERI_CSA] CapabilityAlignmentChecker: refactoring of MemRegion alig…
eupharina Aug 17, 2023
da5f4e6
[CHERI_CSA] CapabilityAlignmentChecker: add allocation source locatio…
eupharina Aug 17, 2023
75c9b7c
[CHERI_CSA] CapabilityAlignmentChecker: improve warning message
eupharina Aug 18, 2023
b97d24d
[CHERI_CSA] CapabilityAlignmentChecker: removing dead symbols
eupharina Aug 22, 2023
f54740e
[CHERI_CSA] move 3 checkers from CHERIAlpha to CHERI section
eupharina Sep 6, 2023
3b9ce71
[CHERI_CSA] ProvenanceSourceChecker: propagate InvalidCap through Una…
eupharina Sep 7, 2023
7f94d78
[CHERI_CSA] Enable cheri.* checkers by default on purecap
eupharina Sep 8, 2023
218127c
[CHERI_CSA] ProvenanceSourceChecker: add FixIts
eupharina Sep 8, 2023
b84e4e5
[CHERI_CSA] Move cheri.CapabilityAlignmentChecker -> optin.portabilit…
eupharina Sep 11, 2023
a7f5025
[CHERI_CSA] CapabilityCopyChecker: add ReportForCharPtr option
eupharina Sep 14, 2023
aa7f973
[CHERI_CSA] Enable alpha.core.PointerSub by default for CHERI
eupharina Sep 15, 2023
762ec72
[CHERI_CSA] Support non-constant offsets to ElementRegion
eupharina Sep 27, 2023
7bffe6b
[CHERI_CSA] PointerAlignmentChecker: improve alignment tracking
eupharina Sep 27, 2023
d6144fc
[CHERI_CSA] PointerAlignmentChecker: use declaration as uniquing loca…
eupharina Oct 10, 2023
b08eede
[CHERI_CSA] CapabilityCopyChecker: fix infinite recursion
eupharina Nov 1, 2023
f8be53f
[CHERI_CSA] PointerSizeAssumptionsChecker: new checker
eupharina Oct 20, 2023
658efa9
[CHERI_CSA] ProvenanceSourceChecker: divide bugs into subtypes
eupharina Nov 13, 2023
5bb88e1
[CHERI_CSA] ProvenanceSource: suppress with -Wno-cheri-provenance
eupharina Nov 15, 2023
dc3ca05
[CHERI_CSA] Fix note links in reports HTML
eupharina Feb 12, 2024
3f77b58
[CHERI_CSA] Fix crash with FieldDecl as UniqLoc
eupharina Nov 28, 2023
c129ebe
[CHERI_CSA] PointerAlignmentChecker: report implicit assignment amd m…
eupharina Nov 27, 2023
2f7a26f
[CHERI_CSA] PointerAlignmentChecker: fix FP for adjacent objects
eupharina Dec 8, 2023
66a2f5d
[CHERI_CSA] PointerAlignmentChecker: fix FP for void* assignment
eupharina Feb 2, 2024
6192b51
[CHERI_CSA] PointerAlignmentChecker: improve warning notes
eupharina Feb 5, 2024
76832fd
[CHERI_CSA] PointerAlignmentChecker: suppress duplicate reports
eupharina Feb 6, 2024
894c785
[CHERI_CSA] PointerAlignmentChecker: improve messages & traces
eupharina Feb 9, 2024
92ed225
[CHERI_CSA] PointerAlignmentChecker: rework handling symbolic addresses
eupharina Feb 9, 2024
08e449f
[CHERI_CSA] PointerAlignmentChecker: false warnings suppression
eupharina Feb 23, 2024
f95c3e4
[CHERI_CSA] CapabilityCopyChecker: ReportForCharPtr=false by default
eupharina Mar 20, 2024
9a8a687
[CHERI_CSA] PointerAlignmentChecker: refine warning types
eupharina Mar 26, 2024
9f5b173
[CHERI_CSA] ProvenanceSourceChecker: refine warning types
eupharina Mar 26, 2024
0c833f1
[CHERI_CSA] PointerAlignmentChecker: support bcopy
eupharina Mar 26, 2024
f45ac19
[CHERI_CSA] ProvenanceSourceChecker: delete ptrdiff as capability war…
eupharina Mar 27, 2024
4cf1836
[CHERI_CSA] ProvenanceSourceChecker: Fix for CompoundAssignmentOp
eupharina Apr 2, 2024
76fe822
[CHERI_CSA] CapabilityCopyChecker: fix for BugType
eupharina Apr 4, 2024
fbc8f2e
[CHERI_CSA] ProvenanceSourceChecker: refine warning types
eupharina May 28, 2024
fe342af
[CHERI_CSA] New alpha.cheri.SubObjectRepresentability checker
eupharina Apr 22, 2024
a90f7a7
[CHERI_CSA] SubObjectRepresentability: detailed message
eupharina Apr 24, 2024
69ae32d
[CHERI_CSA] SubObjectRepresentability: disable notes for now
eupharina Apr 25, 2024
9699a8e
[CHERI_CSA] SubObjectRepresentability: enable notes with updated cher…
eupharina May 6, 2024
3a27311
[CHERI_CSA] SubObjectRepresentability: move alpha.cheri -> cheri
eupharina May 7, 2024
40e900e
[CHERI_CSA] New cheri.Allocation checker
eupharina Mar 29, 2024
c946daf
[CHERI_CSA] AllocationChecker: move static and heap allocation to new…
eupharina Apr 18, 2024
f9a4b19
[CHERI_CSA] AllocationChecker: suppress for ptr to first field
eupharina Apr 18, 2024
ef612bb
[CHERI_CSA] CHERIUtils: Print aka type in messages
eupharina May 28, 2024
bbf8fdc
[CHERI_CSA] AllocationChecker: suppress for flexible array
eupharina May 6, 2024
5450663
[CHERI_CSA] AllocationChecker: rework
eupharina May 20, 2024
bb55953
[CHERI_CSA] AllocationChecker: suppress for free
eupharina May 23, 2024
7d72902
[CHERI_CSA] CHERI API Modelling
eupharina May 24, 2024
f51699b
[CHERI_CSA] AllocationChecker: suppress for bounded suballocations
eupharina May 24, 2024
aee174e
[CHERI_CSA] AllocationChecker: add ReportForUnknownAllocations option
eupharina May 24, 2024
cac85bb
[CHERI_CSA] AllocationChecker: disable for non-purecap
eupharina May 31, 2024
f58077d
[CHERI_CSA] Refactoring state cleanup for dead symbols & regions
eupharina May 31, 2024
52238fd
[CHERI_CSA] SubObjectRepresentability: support other CHERI targets
eupharina Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ def FuchsiaAlpha : Package<"fuchsia">, ParentPackage<Alpha>;
def WebKit : Package<"webkit">;
def WebKitAlpha : Package<"webkit">, ParentPackage<Alpha>;

def CHERI : Package<"cheri">;
def CHERIAlpha : Package<"cheri">, ParentPackage<Alpha>;

//===----------------------------------------------------------------------===//
// Core Checkers.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1664,6 +1667,10 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">,
Documentation<NotDocumented>;

def PointerAlignmentChecker : Checker<"PointerAlignment">,
HelpText<"Check underaligned pointers.">,
Documentation<NotDocumented>;

} // end optin.portability

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1734,3 +1741,69 @@ def UncountedLocalVarsChecker : Checker<"UncountedLocalVarsChecker">,
Documentation<HasDocumentation>;

} // end alpha.webkit

//===----------------------------------------------------------------------===//
// CHERI checkers.
//===----------------------------------------------------------------------===//

let ParentPackage = CHERI in {

def CheriAPIModelling : Checker<"CheriAPIModelling">,
HelpText<"Model CheriAPI">,
Documentation<NotDocumented>;

def ProvenanceSourceChecker : Checker<"ProvenanceSource">,
HelpText<"Check expressions with ambiguous provenance source.">,
CheckerOptions<[
CmdLineOption<Boolean,
"ShowFixIts",
"Enable fix-it hints for this checker",
"false",
InAlpha>,
CmdLineOption<Boolean,
"ReportForAmbiguousProvenance",
"Report for binary operations with ambiguous provenance "
"for which the default capability derivation from LHS is fine. "
"Disabled if [-Wcheri-provenance] is disabled.",
"true",
Released>
]>,
Documentation<NotDocumented>;

def CapabilityCopyChecker : Checker<"CapabilityCopy">,
HelpText<"Check tag-stripping memory copy.">,
CheckerOptions<[
CmdLineOption<Boolean,
"ReportForCharPtr",
"Report tag-stripping copy for char* function parameters. "
"Suppression of warnings for C-strings is used to reduce "
"the number of false alarms, but it's not very reliable.",
"false",
Released>
]>,
Documentation<NotDocumented>;

def PointerSizeAssumptionsChecker : Checker<"PointerSizeAssumptions">,
HelpText<"Detect hardcoded expectations on pointer sizes">,
Documentation<NotDocumented>;

def SubObjectRepresentabilityChecker : Checker<"SubObjectRepresentability">,
HelpText<"Check for record fields with unrepresentable subobject bounds">,
Documentation<NotDocumented>;

} // end cheri

let ParentPackage = CHERIAlpha in {

def AllocationChecker : Checker<"Allocation">,
HelpText<"Suggest narrowing bounds for escaping suballocation capabilities">,
CheckerOptions<[
CmdLineOption<Boolean,
"ReportForUnknownAllocations",
"Report for pointers with untracked origin",
"true",
Released>
]>,
Documentation<NotDocumented>;

} // end alpha.cheri
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class BasicValueFactory {

const llvm::APSInt &getZeroWithTypeSize(QualType T) {
assert(T->isScalarType());
return getValue(0, Ctx.getTypeSize(T), true);
return getValue(0, Ctx.getIntWidth(T), true);
}

const llvm::APSInt &getTruthValue(bool b, QualType T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,11 @@ inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
return Base;
}

inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx,
SVal Base) const {
if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
return getStateManager().StoreMgr->getLValueElement(this, ElementType, *N,
Base);
return UnknownVal();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,10 @@ class SValBuilder {
return nonloc::ConcreteInt(BasicVals.getValue(integer, ptrType));
}

NonLoc makeLocAsInteger(Loc loc, unsigned bits) {
NonLoc makeLocAsInteger(Loc loc, unsigned bits, bool hasProvenance) {
assert((bits & ~255) == 0);
if (hasProvenance)
bits |= 256;
return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,13 @@ class LocAsInteger : public NonLoc {
unsigned getNumBits() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
return D->second;
return D->second & 255;
}

bool hasProvenance() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
return D->second & 256;
}

static bool classof(SVal V) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ class StoreManager {
return getLValueFieldOrIvar(D, Base);
}

virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base);
virtual SVal getLValueElement(ProgramStateRef State, QualType elementType,
NonLoc offset, SVal Base);

/// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10972,9 +10972,11 @@ unsigned ASTContext::getIntWidth(QualType T) const {
if (Target->SupportsCapabilities()) {
if (T->isPointerType() && T->getAs<PointerType>()->isCHERICapability())
return Target->getPointerRangeForCHERICapability();
if (T->isReferenceType() && T->getAs<ReferenceType>()->isCHERICapability()) {
return Target->getPointerRangeForCHERICapability();
}
if (T->isIntCapType())
return Target->getPointerRangeForCHERICapability();
assert(!T->isReferenceType() && "Should probably not be handled here");
}
// For builtin types, just use the standard type sizing method
return (unsigned)getTypeSize(T);
Expand Down
26 changes: 24 additions & 2 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "clang/Basic/CLWarnings.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
#include <clang/Basic/DiagnosticSema.h>
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MakeSupport.h"
#include "clang/Basic/ObjCRuntime.h"
Expand Down Expand Up @@ -3191,7 +3192,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,

static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
const llvm::Triple &Triple,
const InputInfo &Input) {
const InputInfo &Input,
DiagnosticsEngine &Diags) {
// Add default argument set.
if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
CmdArgs.push_back("-analyzer-checker=core");
Expand Down Expand Up @@ -3237,6 +3239,26 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
}

if (Triple.getEnvironment() == llvm::Triple::CheriPurecap ||
// FIXME: checks below should eventually become unreachable when
// Triple is updated to purecap in ToolChain constructor
(Triple.isMIPS() && tools::mips::hasMipsAbiArg(Args, "purecap")) ||
(Triple.isRISCV() && tools::riscv::isCheriPurecap(Args, Triple))) {
CmdArgs.push_back("-analyzer-checker=cheri");

// disable AmbiguousProvenance war if [-Wcheri-provenance] is disabled
if (Diags.getDiagnosticLevel(
diag::warn_ambiguous_provenance_capability_binop,
SourceLocation()) < DiagnosticsEngine::Warning) {
CmdArgs.push_back("-analyzer-config");
CmdArgs.push_back(
"cheri.ProvenanceSource:ReportForAmbiguousProvenance=false");
}

CmdArgs.push_back("-analyzer-checker=optin.portability.PointerAlignment");
CmdArgs.push_back("-analyzer-checker=alpha.core.PointerSub");
}

// Default nullability checks.
CmdArgs.push_back("-analyzer-checker=nullability.NullPassedToNonnull");
CmdArgs.push_back("-analyzer-checker=nullability.NullReturnedFromNonnull");
Expand Down Expand Up @@ -4986,7 +5008,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-DUNICODE");

if (isa<AnalyzeJobAction>(JA))
RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
RenderAnalyzerOptions(Args, CmdArgs, Triple, Input, D.getDiags());

if (isa<AnalyzeJobAction>(JA) ||
(isa<PreprocessJobAction>(JA) && Args.hasArg(options::OPT__analyze)))
Expand Down
Loading