@@ -37,14 +37,19 @@ using EscapePair = std::pair<const MemRegion *, EscapeInfo>;
3737
3838namespace {
3939class AllocationChecker
40- : public Checker<check::PostStmt<CastExpr>, check::PreCall, check::Bind ,
41- check::EndFunction> {
40+ : public Checker<check::PostStmt<CastExpr>, check::PreCall, check::PostCall ,
41+ check::Bind, check:: EndFunction> {
4242 BugType BT_Default{this , " Allocation partitioning" , " CHERI portability" };
4343 BugType BT_KnownReg{this , " Heap or static allocation partitioning" ,
4444 " CHERI portability" };
4545
4646 const CallDescriptionSet IgnoreFnSet = {
47- {{CDM::SimpleFunc, {" free" }, 1 }},
47+ {CDM::SimpleFunc, {" free" }, 1 },
48+ };
49+
50+ const CallDescriptionSet CheriBoundsFnSet = {
51+ {CDM::SimpleFunc, {" cheri_bounds_set" }, 2 },
52+ {CDM::SimpleFunc, {" cheri_bounds_set_exact" }, 2 },
4853 };
4954
5055 class AllocPartitionBugVisitor : public BugReporterVisitor {
@@ -72,6 +77,7 @@ class AllocationChecker
7277public:
7378 void checkPostStmt (const CastExpr *CE, CheckerContext &C) const ;
7479 void checkPreCall (const CallEvent &Call, CheckerContext &C) const ;
80+ void checkPostCall (const CallEvent &Call, CheckerContext &C) const ;
7581 void checkBind (SVal L, SVal V, const Stmt *S, CheckerContext &C) const ;
7682 void checkEndFunction (const ReturnStmt *RS, CheckerContext &Ctx) const ;
7783
@@ -87,6 +93,7 @@ class AllocationChecker
8793REGISTER_MAP_WITH_PROGRAMSTATE (AllocMap, const MemRegion *, QualType)
8894REGISTER_MAP_WITH_PROGRAMSTATE(ShiftMap, const MemRegion *, const MemRegion *)
8995REGISTER_SET_WITH_PROGRAMSTATE(SuballocationSet, const MemRegion *)
96+ REGISTER_SET_WITH_PROGRAMSTATE(BoundedSet, const MemRegion *)
9097
9198namespace {
9299std::pair<const MemRegion *, bool > getAllocationStart (const ASTContext &ASTCtx,
@@ -198,21 +205,25 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
198205 const MemRegion *MR = SrcVal.getAsRegion ();
199206 if (!MR)
200207 return ;
201- const MemSpaceRegion *MemSpace = MR->getMemorySpace ();
202- if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
208+
209+ ProgramStateRef State = C.getState ();
210+ if (State->contains <BoundedSet>(MR))
203211 return ;
204212
205213 const ASTContext &ASTCtx = C.getASTContext ();
206- ProgramStateRef State = C.getState ();
207214 bool Updated = false ;
208-
209215 std::pair<const MemRegion *, bool > StartPair =
210216 getAllocationStart (ASTCtx, MR, State);
217+
211218 const MemRegion *SR = StartPair.first ;
212219 if (!isAllocation (SR))
213220 return ;
214221 bool ZeroShift = StartPair.second ;
215222
223+ const MemSpaceRegion *MemSpace = SR->getMemorySpace ();
224+ if (!isa<HeapSpaceRegion, GlobalsSpaceRegion, StackSpaceRegion>(MemSpace))
225+ return ;
226+
216227 SVal DstVal = C.getSVal (CE);
217228 const MemRegion *DMR = DstVal.getAsRegion ();
218229 if (MR->getAs <ElementRegion>() && (!DMR || !DMR->getAs <ElementRegion>())) {
@@ -258,7 +269,7 @@ void AllocationChecker::checkPostStmt(const CastExpr *CE,
258269
259270void AllocationChecker::checkPreCall (const CallEvent &Call,
260271 CheckerContext &C) const {
261- if (IgnoreFnSet.contains (Call))
272+ if (IgnoreFnSet.contains (Call) || CheriBoundsFnSet. contains (Call) )
262273 return ;
263274
264275 ProgramStateRef State = C.getState ();
@@ -303,6 +314,25 @@ void AllocationChecker::checkPreCall(const CallEvent &Call,
303314 C.addTransition (State, N ? N : C.getPredecessor ());
304315}
305316
317+ void AllocationChecker::checkPostCall (const CallEvent &Call,
318+ CheckerContext &C) const {
319+ if (!CheriBoundsFnSet.contains (Call))
320+ return ;
321+ const MemRegion *MR = C.getSVal (Call.getArgExpr (0 )).getAsRegion ();
322+ const MemRegion *ResMR = C.getSVal (Call.getOriginExpr ()).getAsRegion ();
323+ if (!MR || !ResMR)
324+ return ;
325+
326+ ProgramStateRef State = C.getState ();
327+ if (!State->contains <SuballocationSet>(MR) ||
328+ !State->contains <SuballocationSet>(ResMR))
329+ return ;
330+
331+ State = State->remove <SuballocationSet>(ResMR);
332+ State = State->add <BoundedSet>(ResMR);
333+ C.addTransition (State);
334+ }
335+
306336void AllocationChecker::checkBind (SVal L, SVal V, const Stmt *S,
307337 CheckerContext &C) const {
308338 const MemRegion *Dst = L.getAsRegion ();
0 commit comments