@@ -44,14 +44,20 @@ using EscapePair = std::pair<const MemRegion*, EscapeInfo>;
4444namespace {
4545class AllocationChecker : public Checker <check::PostStmt<CastExpr>,
4646 check::PreCall,
47+ check::PostCall,
4748 check::Bind,
4849 check::EndFunction> {
4950 BugType BT_Default{this , " Allocation partitioning" , " CHERI portability" };
5051 BugType BT_KnownReg{this , " Heap or static allocation partitioning" ,
5152 " CHERI portability" };
5253
5354 const CallDescriptionSet IgnoreFnSet = {
54- {{CDM::SimpleFunc, {" free" }, 1 }},
55+ {CDM::SimpleFunc, {" free" }, 1 },
56+ };
57+
58+ const CallDescriptionSet CheriBoundsFnSet = {
59+ {CDM::SimpleFunc, {" cheri_bounds_set" }, 2 },
60+ {CDM::SimpleFunc, {" cheri_bounds_set_exact" }, 2 },
5561 };
5662
5763
@@ -81,6 +87,7 @@ class AllocationChecker : public Checker<check::PostStmt<CastExpr>,
8187public:
8288 void checkPostStmt (const CastExpr *CE, CheckerContext &C) const ;
8389 void checkPreCall (const CallEvent &Call, CheckerContext &C) const ;
90+ void checkPostCall (const CallEvent &Call, CheckerContext &C) const ;
8491 void checkBind (SVal L, SVal V, const Stmt *S, CheckerContext &C) const ;
8592 void checkEndFunction (const ReturnStmt *RS, CheckerContext &Ctx) const ;
8693
@@ -96,6 +103,8 @@ class AllocationChecker : public Checker<check::PostStmt<CastExpr>,
96103REGISTER_MAP_WITH_PROGRAMSTATE (AllocMap, const MemRegion *, QualType)
97104REGISTER_MAP_WITH_PROGRAMSTATE(ShiftMap, const MemRegion *, const MemRegion *)
98105REGISTER_SET_WITH_PROGRAMSTATE(SuballocationSet, const MemRegion *)
106+ REGISTER_SET_WITH_PROGRAMSTATE(BoundedSet, const MemRegion *)
107+
99108
100109namespace {
101110std::pair<const MemRegion *, bool > getAllocationStart (const ASTContext &ASTCtx,
@@ -207,21 +216,25 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
207216 const MemRegion *MR = SrcVal.getAsRegion ();
208217 if (!MR)
209218 return ;
210- const MemSpaceRegion *MemSpace = MR->getMemorySpace ();
211- if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
219+
220+ ProgramStateRef State = C.getState ();
221+ if (State->contains <BoundedSet>(MR))
212222 return ;
213223
214224 const ASTContext &ASTCtx = C.getASTContext ();
215- ProgramStateRef State = C.getState ();
216225 bool Updated = false ;
217-
218226 std::pair<const MemRegion *, bool > StartPair =
219227 getAllocationStart (ASTCtx, MR, State);
228+
220229 const MemRegion *SR = StartPair.first ;
221230 if (!isAllocation (SR))
222231 return ;
223232 bool ZeroShift = StartPair.second ;
224233
234+ const MemSpaceRegion *MemSpace = SR->getMemorySpace ();
235+ if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
236+ return ;
237+
225238 SVal DstVal = C.getSVal (CE);
226239 const MemRegion *DMR = DstVal.getAsRegion ();
227240 if (MR->getAs <ElementRegion>() && (!DMR || !DMR->getAs <ElementRegion>())) {
@@ -267,9 +280,9 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
267280
268281void AllocationChecker::checkPreCall (const CallEvent &Call,
269282 CheckerContext &C) const {
270- if (IgnoreFnSet.contains (Call))
283+ if (IgnoreFnSet.contains (Call) || CheriBoundsFnSet. contains (Call) )
271284 return ;
272-
285+
273286 ProgramStateRef State = C.getState ();
274287 ExplodedNode *N = nullptr ;
275288 bool Updated = false ;
@@ -305,6 +318,25 @@ void AllocationChecker::checkPreCall(const CallEvent &Call,
305318 C.addTransition (State, N ? N : C.getPredecessor ());
306319}
307320
321+ void AllocationChecker::checkPostCall (const CallEvent &Call,
322+ CheckerContext &C) const {
323+ if (!CheriBoundsFnSet.contains (Call))
324+ return ;
325+ const MemRegion *MR = C.getSVal (Call.getArgExpr (0 )).getAsRegion ();
326+ const MemRegion *ResMR = C.getSVal (Call.getOriginExpr ()).getAsRegion ();
327+ if (!MR || !ResMR)
328+ return ;
329+
330+ ProgramStateRef State = C.getState ();
331+ if (!State->contains <SuballocationSet>(MR) ||
332+ !State->contains <SuballocationSet>(ResMR))
333+ return ;
334+
335+ State = State->remove <SuballocationSet>(ResMR);
336+ State = State->add <BoundedSet>(ResMR);
337+ C.addTransition (State);
338+ }
339+
308340void AllocationChecker::checkBind (SVal L, SVal V, const Stmt *S,
309341 CheckerContext &C) const {
310342 const MemRegion *Dst = L.getAsRegion ();
0 commit comments