@@ -196,23 +196,48 @@ raw_ostream &operator<<(raw_ostream &OS, const MCInstReference &);
196
196
197
197
namespace PAuthGadgetScanner {
198
198
199
+ // The report classes are designed to be used in an immutable manner.
200
+ // When an issue report is constructed in multiple steps, an attempt is made
201
+ // to distinguish intermediate and final results at the type level.
202
+ //
203
+ // Here is an overview of issue life-cycle:
204
+ // * an analysis (SrcSafetyAnalysis at now, DstSafetyAnalysis will be added
205
+ // later to support the detection of authentication oracles) computes register
206
+ // state for each instruction in the function.
207
+ // * each instruction is checked to be a gadget of some kind, taking the
208
+ // computed state into account. If a gadget is found, its kind and location
209
+ // are stored into a subclass of Diagnostic wrapped into BriefReport<ReqT>.
210
+ // * if any issue is to be reported for the function, the same analysis is
211
+ // re-run to collect extra information to provide to the user. Which extra
212
+ // information can be requested depends on the particular analysis (for
213
+ // example, SrcSafetyAnalysis is able to compute the set of instructions
214
+ // clobbering the particular register, thus ReqT is MCPhysReg). At this stage,
215
+ // `FinalReport`s are created.
216
+ //
217
+ // Here, the subclasses of Diagnostic store the pieces of information which
218
+ // are kept unchanged since they are collected on the first run of the analysis.
219
+ // BriefReport<T>::RequestedDetails, on the other hand, is replaced with
220
+ // FinalReport::Details computed by the second run of the analysis.
221
+
199
222
// / Description of a gadget kind that can be detected. Intended to be
200
- // / statically allocated to be attached to reports by reference.
223
+ // / statically allocated and attached to reports by reference.
201
224
class GadgetKind {
202
225
const char *Description;
203
226
204
227
public:
228
+ // / Wraps a description string which must be a string literal.
205
229
GadgetKind (const char *Description) : Description(Description) {}
206
230
207
231
StringRef getDescription () const { return Description; }
208
232
};
209
233
210
- // / Base report located at some instruction, without any additional information.
211
- struct Report {
234
+ // / Basic diagnostic information, which is kept unchanged since it is collected
235
+ // / on the first run of the analysis.
236
+ struct Diagnostic {
212
237
MCInstReference Location;
213
238
214
- Report (MCInstReference Location) : Location(Location) {}
215
- virtual ~Report () {}
239
+ Diagnostic (MCInstReference Location) : Location(Location) {}
240
+ virtual ~Diagnostic () {}
216
241
217
242
virtual void generateReport (raw_ostream &OS,
218
243
const BinaryContext &BC) const = 0;
@@ -221,27 +246,27 @@ struct Report {
221
246
StringRef IssueKind) const ;
222
247
};
223
248
224
- struct GadgetReport : public Report {
249
+ struct GadgetDiagnostic : public Diagnostic {
225
250
// The particular kind of gadget that is detected.
226
251
const GadgetKind &Kind;
227
252
228
- GadgetReport (const GadgetKind &Kind, MCInstReference Location)
229
- : Report (Location), Kind(Kind) {}
253
+ GadgetDiagnostic (const GadgetKind &Kind, MCInstReference Location)
254
+ : Diagnostic (Location), Kind(Kind) {}
230
255
231
256
void generateReport (raw_ostream &OS, const BinaryContext &BC) const override ;
232
257
};
233
258
234
259
// / Report with a free-form message attached.
235
- struct GenericReport : public Report {
260
+ struct GenericDiagnostic : public Diagnostic {
236
261
std::string Text;
237
- GenericReport (MCInstReference Location, StringRef Text)
238
- : Report (Location), Text(Text) {}
262
+ GenericDiagnostic (MCInstReference Location, StringRef Text)
263
+ : Diagnostic (Location), Text(Text) {}
239
264
virtual void generateReport (raw_ostream &OS,
240
265
const BinaryContext &BC) const override ;
241
266
};
242
267
243
268
// / An information about an issue collected on the slower, detailed,
244
- // / run of an analysis.
269
+ // / run of the analysis.
245
270
class ExtraInfo {
246
271
public:
247
272
virtual void print (raw_ostream &OS, const MCInstReference Location) const = 0;
@@ -260,35 +285,34 @@ class ClobberingInfo : public ExtraInfo {
260
285
261
286
// / A brief version of a report that can be further augmented with the details.
262
287
// /
263
- // / It is common for a particular type of gadget detector to be tied to some
264
- // / specific kind of analysis. If an issue is returned by that detector, it may
265
- // / be further augmented with the detailed info in an analysis-specific way,
266
- // / or just be left as-is (f.e. if a free-form warning was reported).
288
+ // / A half-baked report produced on the first run of the analysis. An extra,
289
+ // / analysis-specific information may be requested to be collected on the
290
+ // / second run.
267
291
template <typename T> struct BriefReport {
268
- BriefReport (std::shared_ptr<Report > Issue,
292
+ BriefReport (std::shared_ptr<Diagnostic > Issue,
269
293
const std::optional<T> RequestedDetails)
270
294
: Issue(Issue), RequestedDetails(RequestedDetails) {}
271
295
272
- std::shared_ptr<Report > Issue;
296
+ std::shared_ptr<Diagnostic > Issue;
273
297
std::optional<T> RequestedDetails;
274
298
};
275
299
276
- // / A detailed version of a report.
277
- struct DetailedReport {
278
- DetailedReport (std::shared_ptr<Report > Issue,
279
- std::shared_ptr<ExtraInfo> Details)
300
+ // / A final version of the report.
301
+ struct FinalReport {
302
+ FinalReport (std::shared_ptr<Diagnostic > Issue,
303
+ std::shared_ptr<ExtraInfo> Details)
280
304
: Issue(Issue), Details(Details) {}
281
305
282
- std::shared_ptr<Report > Issue;
306
+ std::shared_ptr<Diagnostic > Issue;
283
307
std::shared_ptr<ExtraInfo> Details;
284
308
};
285
309
286
310
struct FunctionAnalysisResult {
287
- std::vector<DetailedReport > Diagnostics;
311
+ std::vector<FinalReport > Diagnostics;
288
312
};
289
313
290
314
// / A helper class storing per-function context to be instantiated by Analysis.
291
- class FunctionAnalysis {
315
+ class FunctionAnalysisContext {
292
316
BinaryContext &BC;
293
317
BinaryFunction &BF;
294
318
MCPlusBuilder::AllocatorIdTy AllocatorId;
@@ -304,8 +328,9 @@ class FunctionAnalysis {
304
328
void handleSimpleReports (SmallVector<BriefReport<MCPhysReg>> &Reports);
305
329
306
330
public:
307
- FunctionAnalysis (BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocatorId,
308
- bool PacRetGadgetsOnly)
331
+ FunctionAnalysisContext (BinaryFunction &BF,
332
+ MCPlusBuilder::AllocatorIdTy AllocatorId,
333
+ bool PacRetGadgetsOnly)
309
334
: BC(BF.getBinaryContext()), BF(BF), AllocatorId(AllocatorId),
310
335
PacRetGadgetsOnly (PacRetGadgetsOnly) {}
311
336
0 commit comments