Skip to content

Commit 341235a

Browse files
eupharinaresistor
authored andcommitted
[CHERI_CSA] AllocationChecker: add ReportForUnknownAllocations option
1 parent a7fa5f3 commit 341235a

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,9 @@ let ParentPackage = CHERIAlpha in {
18441844
: Checker<"Allocation">,
18451845
HelpText<
18461846
"Suggest narrowing bounds for escaping suballocation capabilities">,
1847+
CheckerOptions<[CmdLineOption<
1848+
Boolean, "ReportForUnknownAllocations",
1849+
"Report for pointers with untracked origin", "true", Released>]>,
18471850
Documentation<NotDocumented>;
18481851

18491852
} // end alpha.cheri

clang/lib/StaticAnalyzer/Checkers/CHERI/AllocationChecker.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class AllocationChecker
4040
: public Checker<check::PostStmt<CastExpr>, check::PreCall, check::PostCall,
4141
check::Bind, check::EndFunction> {
4242
BugType BT_Default{this, "Allocation partitioning", "CHERI portability"};
43-
BugType BT_KnownReg{this, "Heap or static allocation partitioning",
44-
"CHERI portability"};
43+
BugType BT_UnknownReg{this, "Unknown allocation partitioning",
44+
"CHERI portability"};
4545

4646
const CallDescriptionSet IgnoreFnSet = {
4747
{CDM::SimpleFunc, {"free"}, 1},
@@ -81,6 +81,8 @@ class AllocationChecker
8181
void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
8282
void checkEndFunction(const ReturnStmt *RS, CheckerContext &Ctx) const;
8383

84+
bool ReportForUnknownAllocations;
85+
8486
private:
8587
ExplodedNode *emitAllocationPartitionWarning(CheckerContext &C,
8688
const MemRegion *MR,
@@ -111,7 +113,13 @@ std::pair<const MemRegion *, bool> getAllocationStart(const ASTContext &ASTCtx,
111113
return std::make_pair(R, ZeroShift);
112114
}
113115

114-
bool isAllocation(const MemRegion *R) {
116+
bool isAllocation(const MemRegion *R, const AllocationChecker *Chk) {
117+
if (!Chk->ReportForUnknownAllocations) {
118+
const MemSpaceRegion *MemSpace = R->getMemorySpace();
119+
if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
120+
return false;
121+
}
122+
115123
if (R->getAs<SymbolicRegion>())
116124
return true;
117125
if (const TypedValueRegion *TR = R->getAs<TypedValueRegion>()) {
@@ -176,12 +184,19 @@ ExplodedNode *AllocationChecker::emitAllocationPartitionWarning(
176184
CheckerContext &C, const MemRegion *MR, SourceRange SR,
177185
StringRef Msg = "") const {
178186
if (ExplodedNode *ErrNode = C.generateNonFatalErrorNode()) {
179-
auto R = std::make_unique<PathSensitiveBugReport>(BT_Default, Msg, ErrNode);
180-
R->addRange(SR);
181-
R->markInteresting(MR);
182187

183188
const MemRegion *PrevAlloc =
184189
getAllocationStart(C.getASTContext(), MR, C.getState()).first;
190+
const MemSpaceRegion *MS =
191+
PrevAlloc ? PrevAlloc->getMemorySpace() : MR->getMemorySpace();
192+
const BugType &BT =
193+
isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MS)
194+
? BT_Default
195+
: BT_UnknownReg;
196+
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, ErrNode);
197+
R->addRange(SR);
198+
R->markInteresting(MR);
199+
185200
R->addVisitor(std::make_unique<AllocPartitionBugVisitor>(
186201
PrevAlloc == MR ? nullptr : PrevAlloc, MR));
187202

@@ -216,14 +231,10 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
216231
getAllocationStart(ASTCtx, MR, State);
217232

218233
const MemRegion *SR = StartPair.first;
219-
if (!isAllocation(SR))
234+
if (!isAllocation(SR, this))
220235
return;
221236
bool ZeroShift = StartPair.second;
222237

223-
const MemSpaceRegion *MemSpace = SR->getMemorySpace();
224-
if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
225-
return;
226-
227238
SVal DstVal = C.getSVal(CE);
228239
const MemRegion *DMR = DstVal.getAsRegion();
229240
if (MR->getAs<ElementRegion>() && (!DMR || !DMR->getAs<ElementRegion>())) {
@@ -252,10 +263,14 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
252263
->getUnqualifiedDesugaredType();
253264
const Type *Ty2 = DstTy->getPointeeType()->getUnqualifiedDesugaredType();
254265
if (!relatedTypes(ASTCtx, Ty1, Ty2)) {
255-
State = State->add<SuballocationSet>(SR);
256-
if (DMR)
266+
if (!State->contains<SuballocationSet>(SR)) {
267+
State = State->add<SuballocationSet>(SR);
268+
Updated = true;
269+
}
270+
if (DMR && !State->contains<SuballocationSet>(DMR)) {
257271
State = State->add<SuballocationSet>(DMR);
258-
Updated = true;
272+
Updated = true;
273+
}
259274
} // else OK
260275
} // else ??? (ignore for now)
261276
} else {
@@ -419,7 +434,10 @@ PathDiagnosticPieceRef AllocationChecker::AllocPartitionBugVisitor::VisitNode(
419434
//===----------------------------------------------------------------------===//
420435

421436
void ento::registerAllocationChecker(CheckerManager &Mgr) {
422-
Mgr.registerChecker<AllocationChecker>();
437+
auto *Checker = Mgr.registerChecker<AllocationChecker>();
438+
Checker->ReportForUnknownAllocations =
439+
Mgr.getAnalyzerOptions().getCheckerBooleanOption(
440+
Checker, "ReportForUnknownAllocations");
423441
}
424442

425443
bool ento::shouldRegisterAllocationChecker(const CheckerManager &Mgr) {

clang/test/Analysis/analyzer-config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// CHECK: [config]
55
// CHECK-NEXT: add-pop-up-notes = true
66
// CHECK-NEXT: aggressive-binary-operation-simplification = false
7+
// CHECK-NEXT: alpha.cheri.Allocation:ReportForUnknownAllocations = true
78
// CHECK-NEXT: alpha.clone.CloneChecker:IgnoredFilesPattern = ""
89
// CHECK-NEXT: alpha.clone.CloneChecker:MinimumCloneComplexity = 50
910
// CHECK-NEXT: alpha.clone.CloneChecker:ReportNormalClones = true

0 commit comments

Comments
 (0)