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