Skip to content

Commit d48dc9c

Browse files
eupharinaresistor
authored andcommitted
[CHERI_CSA] AllocationChecker: add ReportForUnknownAllocations option
1 parent 264aa7a commit d48dc9c

File tree

3 files changed

+49
-23
lines changed

3 files changed

+49
-23
lines changed

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,15 +1818,15 @@ def ProvenanceSourceChecker : Checker<"ProvenanceSource">,
18181818

18191819
def CapabilityCopyChecker : Checker<"CapabilityCopy">,
18201820
HelpText<"Check tag-stripping memory copy.">,
1821-
CheckerOptions<[
1822-
CmdLineOption<Boolean,
1823-
"ReportForCharPtr",
1824-
"Report tag-stripping copy for char* function parameters. "
1825-
"Suppression of warnings for C-strings is used to reduce "
1826-
"the number of false alarms, but it's not very reliable.",
1827-
"false",
1828-
Released>
1829-
]>,
1821+
CheckerOptions<[
1822+
CmdLineOption<Boolean,
1823+
"ReportForCharPtr",
1824+
"Report tag-stripping copy for char* function parameters. "
1825+
"Suppression of warnings for C-strings is used to reduce "
1826+
"the number of false alarms, but it's not very reliable.",
1827+
"false",
1828+
Released>
1829+
]>,
18301830
Documentation<NotDocumented>;
18311831

18321832
def PointerSizeAssumptionsChecker : Checker<"PointerSizeAssumptions">,
@@ -1843,6 +1843,13 @@ let ParentPackage = CHERIAlpha in {
18431843

18441844
def AllocationChecker : Checker<"Allocation">,
18451845
HelpText<"Suggest narrowing bounds for escaping suballocation capabilities">,
1846+
CheckerOptions<[
1847+
CmdLineOption<Boolean,
1848+
"ReportForUnknownAllocations",
1849+
"Report for pointers with untracked origin",
1850+
"true",
1851+
Released>
1852+
]>,
18461853
Documentation<NotDocumented>;
18471854

18481855
} // end alpha.cheri

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

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class AllocationChecker : public Checker<check::PostStmt<CastExpr>,
4848
check::Bind,
4949
check::EndFunction> {
5050
BugType BT_Default{this, "Allocation partitioning", "CHERI portability"};
51-
BugType BT_KnownReg{this, "Heap or static allocation partitioning",
51+
BugType BT_UnknownReg{this, "Unknown allocation partitioning",
5252
"CHERI portability"};
5353

5454
const CallDescriptionSet IgnoreFnSet = {
@@ -91,6 +91,8 @@ class AllocationChecker : public Checker<check::PostStmt<CastExpr>,
9191
void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
9292
void checkEndFunction(const ReturnStmt *RS, CheckerContext &Ctx) const;
9393

94+
bool ReportForUnknownAllocations;
95+
9496
private:
9597
ExplodedNode *emitAllocationPartitionWarning(CheckerContext &C,
9698
const MemRegion *MR,
@@ -122,7 +124,13 @@ std::pair<const MemRegion *, bool> getAllocationStart(const ASTContext &ASTCtx,
122124
return std::make_pair(R, ZeroShift);
123125
}
124126

125-
bool isAllocation(const MemRegion *R) {
127+
bool isAllocation(const MemRegion *R, const AllocationChecker* Chk) {
128+
if (!Chk->ReportForUnknownAllocations) {
129+
const MemSpaceRegion *MemSpace = R->getMemorySpace();
130+
if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
131+
return false;
132+
}
133+
126134
if (R->getAs<SymbolicRegion>())
127135
return true;
128136
if (const TypedValueRegion *TR = R->getAs<TypedValueRegion>()) {
@@ -187,12 +195,19 @@ ExplodedNode *AllocationChecker::emitAllocationPartitionWarning(
187195
CheckerContext &C, const MemRegion *MR, SourceRange SR,
188196
StringRef Msg = "") const {
189197
if (ExplodedNode *ErrNode = C.generateNonFatalErrorNode()) {
190-
auto R = std::make_unique<PathSensitiveBugReport>(BT_Default, Msg, ErrNode);
191-
R->addRange(SR);
192-
R->markInteresting(MR);
193198

194199
const MemRegion *PrevAlloc =
195200
getAllocationStart(C.getASTContext(), MR, C.getState()).first;
201+
const MemSpaceRegion *MS =
202+
PrevAlloc ? PrevAlloc->getMemorySpace() : MR->getMemorySpace();
203+
const BugType &BT =
204+
isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MS)
205+
? BT_Default
206+
: BT_UnknownReg;
207+
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, ErrNode);
208+
R->addRange(SR);
209+
R->markInteresting(MR);
210+
196211
R->addVisitor(std::make_unique<AllocPartitionBugVisitor>(
197212
PrevAlloc == MR ? nullptr : PrevAlloc, MR));
198213

@@ -227,14 +242,10 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
227242
getAllocationStart(ASTCtx, MR, State);
228243

229244
const MemRegion *SR = StartPair.first;
230-
if (!isAllocation(SR))
245+
if (!isAllocation(SR, this))
231246
return;
232247
bool ZeroShift = StartPair.second;
233248

234-
const MemSpaceRegion *MemSpace = SR->getMemorySpace();
235-
if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
236-
return;
237-
238249
SVal DstVal = C.getSVal(CE);
239250
const MemRegion *DMR = DstVal.getAsRegion();
240251
if (MR->getAs<ElementRegion>() && (!DMR || !DMR->getAs<ElementRegion>())) {
@@ -263,10 +274,14 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
263274
->getUnqualifiedDesugaredType();
264275
const Type *Ty2 = DstTy->getPointeeType()->getUnqualifiedDesugaredType();
265276
if (!relatedTypes(ASTCtx, Ty1, Ty2)) {
266-
State = State->add<SuballocationSet>(SR);
267-
if (DMR)
277+
if (!State->contains<SuballocationSet>(SR)) {
278+
State = State->add<SuballocationSet>(SR);
279+
Updated = true;
280+
}
281+
if (DMR && !State->contains<SuballocationSet>(DMR)) {
268282
State = State->add<SuballocationSet>(DMR);
269-
Updated = true;
283+
Updated = true;
284+
}
270285
} // else OK
271286
} // else ??? (ignore for now)
272287
} else {
@@ -423,7 +438,10 @@ PathDiagnosticPieceRef AllocationChecker::AllocPartitionBugVisitor::VisitNode(
423438
//===----------------------------------------------------------------------===//
424439

425440
void ento::registerAllocationChecker(CheckerManager &Mgr) {
426-
Mgr.registerChecker<AllocationChecker>();
441+
auto *Checker = Mgr.registerChecker<AllocationChecker>();
442+
Checker->ReportForUnknownAllocations =
443+
Mgr.getAnalyzerOptions().getCheckerBooleanOption(
444+
Checker, "ReportForUnknownAllocations");
427445
}
428446

429447
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)