Skip to content

Commit 728a99b

Browse files
authored
Add nullability to stored events. Fix unwrap of missing data. (#509)
This fixes a crash that could occur in the FAA block dialog. This issue was introduced during development of the .7 release and was never part of a release.
1 parent 0365296 commit 728a99b

8 files changed

+64
-62
lines changed

.bazelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ build --define=apple.propagate_embedded_extra_outputs=yes
44
build --copt=-Werror
55
build --copt=-Wall
66
build --copt=-Wformat-security
7+
build --copt=-Wnullability-completeness
78
build --copt=-Wno-error=deprecated-declarations
8-
build --copt=-Wno-error=nullability-completeness
99
build --copt=-Wreorder-init-list
1010
build --copt=-Wsemicolon-before-method-body
1111
build --copt=-Wc99-designator

Source/common/SNTStoredEvent.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
@interface SNTStoredEvent : NSObject <NSSecureCoding>
2020

2121
/// The date and time the execution request was received by santad.
22-
@property NSDate *occurrenceDate;
22+
@property(nonnull) NSDate *occurrenceDate;
2323

2424
/// An index for this event, randomly generated during initialization.
25-
@property NSNumber *idx;
25+
@property(nonnull) NSNumber *idx;
2626

2727
// Subclasses are required to define: `hashForEvent`.
2828
// The base class implementation will throw an exception.
29-
- (NSString *)hashForEvent;
29+
- (nullable NSString *)hashForEvent;
3030

3131
@end

Source/common/SNTStoredExecutionEvent.h

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,59 +23,59 @@
2323
/// Represents an execution event stored in the events database.
2424
@interface SNTStoredExecutionEvent : SNTStoredEvent <NSSecureCoding>
2525

26-
- (instancetype)initWithFileInfo:(SNTFileInfo *)fileInfo;
26+
- (nullable instancetype)initWithFileInfo:(nullable SNTFileInfo *)fileInfo;
2727

2828
/// The SHA-256 of the executed file.
29-
@property NSString *fileSHA256;
29+
@property(nullable) NSString *fileSHA256;
3030

3131
/// The full path of the executed file.
32-
@property NSString *filePath;
32+
@property(nullable) NSString *filePath;
3333

3434
/// Set to YES if the event is a part of a bundle. When an event is passed to SantaGUI this propery
3535
/// will be used as an indicator to to kick off bundle hashing as necessary. Default value is NO.
3636
@property BOOL needsBundleHash;
3737

3838
/// If the executed file was part of a bundle, this is the calculated hash of all the nested
3939
/// executables within the bundle.
40-
@property NSString *fileBundleHash;
40+
@property(nullable) NSString *fileBundleHash;
4141

4242
/// If the executed file was part of a bundle, this is the time in ms it took to hash the bundle.
43-
@property NSNumber *fileBundleHashMilliseconds;
43+
@property(nullable) NSNumber *fileBundleHashMilliseconds;
4444

4545
/// If the executed file was part of a bundle, this is the total count of related mach-o binaries.
46-
@property NSNumber *fileBundleBinaryCount;
46+
@property(nullable) NSNumber *fileBundleBinaryCount;
4747

4848
/// If the executed file was part of the bundle, this is the CFBundleDisplayName, if it exists
4949
/// or the CFBundleName if not.
50-
@property NSString *fileBundleName;
50+
@property(nullable) NSString *fileBundleName;
5151

5252
/// If the executed file was part of the bundle, this is the path to the bundle.
53-
@property NSString *fileBundlePath;
53+
@property(nullable) NSString *fileBundlePath;
5454

5555
/// The relative path to the bundle's main executable.
56-
@property NSString *fileBundleExecutableRelPath;
56+
@property(nullable) NSString *fileBundleExecutableRelPath;
5757

5858
/// If the executed file was part of the bundle, this is the CFBundleID.
59-
@property NSString *fileBundleID;
59+
@property(nullable) NSString *fileBundleID;
6060

6161
/// If the executed file was part of the bundle, this is the CFBundleVersion.
62-
@property NSString *fileBundleVersion;
62+
@property(nullable) NSString *fileBundleVersion;
6363

6464
/// If the executed file was part of the bundle, this is the CFBundleShortVersionString.
65-
@property NSString *fileBundleVersionString;
65+
@property(nullable) NSString *fileBundleVersionString;
6666

6767
/// If the executed file was signed, this is an NSArray of MOLCertificate's
6868
/// representing the signing chain.
69-
@property NSArray<MOLCertificate *> *signingChain;
69+
@property(nullable) NSArray<MOLCertificate *> *signingChain;
7070

7171
/// If the executed file was signed, this is the Team ID if present in the signature information.
72-
@property NSString *teamID;
72+
@property(nullable) NSString *teamID;
7373

7474
/// If the executed file was signed, this is the Signing ID if present in the signature information.
75-
@property NSString *signingID;
75+
@property(nullable) NSString *signingID;
7676

7777
/// If the executed file was signed, this is the CDHash of the binary.
78-
@property NSString *cdhash;
78+
@property(nullable) NSString *cdhash;
7979

8080
/// Codesigning flags for the process (from `<Kernel/kern/cs_blobs.h>`)
8181
@property uint32_t codesigningFlags;
@@ -84,55 +84,55 @@
8484
@property SNTSigningStatus signingStatus;
8585

8686
/// The user who executed the binary.
87-
@property NSString *executingUser;
87+
@property(nullable) NSString *executingUser;
8888

8989
/// The decision santad returned.
9090
@property SNTEventState decision;
9191

9292
/// NSArray of logged in users when the decision was made.
93-
@property NSArray *loggedInUsers;
93+
@property(nullable) NSArray *loggedInUsers;
9494

9595
/// NSArray of sessions when the decision was made (e.g. nobody@console, nobody@ttys000).
96-
@property NSArray *currentSessions;
96+
@property(nullable) NSArray *currentSessions;
9797

9898
/// The process ID of the binary being executed.
99-
@property NSNumber *pid;
99+
@property(nullable) NSNumber *pid;
100100

101101
/// The parent process ID of the binary being executed.
102-
@property NSNumber *ppid;
102+
@property(nullable) NSNumber *ppid;
103103

104104
/// The name of the parent process.
105-
@property NSString *parentName;
105+
@property(nullable) NSString *parentName;
106106

107107
/// Quarantine data about the executed file, if any.
108-
@property NSString *quarantineDataURL;
109-
@property NSString *quarantineRefererURL;
110-
@property NSDate *quarantineTimestamp;
111-
@property NSString *quarantineAgentBundleID;
108+
@property(nullable) NSString *quarantineDataURL;
109+
@property(nullable) NSString *quarantineRefererURL;
110+
@property(nullable) NSDate *quarantineTimestamp;
111+
@property(nullable) NSString *quarantineAgentBundleID;
112112

113113
/// A generated string representing the publisher based on the signingChain
114-
@property(readonly) NSString *publisherInfo;
114+
@property(readonly, nullable) NSString *publisherInfo;
115115

116116
/// Return an array of the underlying SecCertificateRef's of the signingChain
117117
///
118118
/// WARNING: If the refs need to be used for a long time be careful to properly
119119
/// CFRetain/CFRelease the returned items.
120-
@property(readonly) NSArray *signingChainCertRefs;
120+
@property(readonly, nullable) NSArray *signingChainCertRefs;
121121

122122
/// If the executed file was entitled, this is the set of key/value pairs of entitlements
123-
@property NSDictionary *entitlements;
123+
@property(nullable) NSDictionary *entitlements;
124124

125125
/// Whether or not the set of entitlements were filtered (e.g. due to configuration)
126126
@property BOOL entitlementsFiltered;
127127

128128
/// The timestamp of when the binary was signed. This timestamp is the secure
129129
/// timestamp that was certified by Apple's timestamp authority service and can
130130
/// be trusted.
131-
@property NSDate *secureSigningTime;
131+
@property(nullable) NSDate *secureSigningTime;
132132

133133
/// The timestamp of when the binary was signed. This timestamp is the insecure
134134
/// timestamp provided by the developer during signing. It has not been validated
135135
/// and could be spoofed.
136-
@property NSDate *signingTime;
136+
@property(nullable) NSDate *signingTime;
137137

138138
@end

Source/common/SNTStoredExecutionEvent.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
@implementation SNTStoredExecutionEvent
2525

26-
- (instancetype)initWithFileInfo:(SNTFileInfo *)fileInfo {
26+
- (nullable instancetype)initWithFileInfo:(nullable SNTFileInfo *)fileInfo {
2727
self = [super init];
2828
if (self) {
2929
_filePath = fileInfo.path;

Source/common/SNTStoredFileAccessEvent.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,46 +23,46 @@
2323
@interface SNTStoredFileAccessEvent : SNTStoredEvent <NSSecureCoding>
2424

2525
/// The rule version that was violated.
26-
@property NSString *ruleVersion;
26+
@property(nullable) NSString *ruleVersion;
2727

2828
/// The rule name that was violated.
29-
@property NSString *ruleName;
29+
@property(nullable) NSString *ruleName;
3030

3131
/// The watched path that was accessed.
32-
@property NSString *accessedPath;
32+
@property(nullable) NSString *accessedPath;
3333

34-
@property SNTStoredFileAccessProcess *process;
34+
@property(nullable) SNTStoredFileAccessProcess *process;
3535

3636
@end
3737

3838
@interface SNTStoredFileAccessProcess : NSObject <NSSecureCoding>
3939

4040
/// The full path of the process's executable file.
41-
@property NSString *filePath;
41+
@property(nullable) NSString *filePath;
4242

4343
/// If the process was signed, this is the CDHash of the binary.
44-
@property NSString *cdhash;
44+
@property(nullable) NSString *cdhash;
4545

4646
/// The SHA-256 of the executed file.
47-
@property NSString *fileSHA256;
47+
@property(nullable) NSString *fileSHA256;
4848

4949
/// If the process was signed, this is the Signing ID if present in the signature information.
50-
@property NSString *signingID;
50+
@property(nullable) NSString *signingID;
5151

5252
/// If the executed file was signed, this is an NSArray of MOLCertificate's
5353
/// representing the signing chain.
54-
@property NSArray<MOLCertificate *> *signingChain;
54+
@property(nullable) NSArray<MOLCertificate *> *signingChain;
5555

5656
/// If the process was signed, this is the Team ID if present in the signature information.
57-
@property NSString *teamID;
57+
@property(nullable) NSString *teamID;
5858

5959
/// The process ID of the binary being executed.
60-
@property NSNumber *pid;
60+
@property(nullable) NSNumber *pid;
6161

6262
/// The user who executed the binary.
63-
@property NSString *executingUser;
63+
@property(nullable) NSString *executingUser;
6464

6565
/// Information about this process's parent
66-
@property SNTStoredFileAccessProcess *parent;
66+
@property(nullable) SNTStoredFileAccessProcess *parent;
6767

6868
@end

Source/common/SNTStoredFileAccessEvent.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#import "Source/common/SNTStoredFileAccessEvent.h"
1616

1717
#import "Source/common/CoderMacros.h"
18+
#import "Source/common/MOLCertificate.h"
1819

1920
@implementation SNTStoredFileAccessEvent
2021

@@ -34,6 +35,7 @@ - (void)encodeWithCoder:(NSCoder *)coder {
3435
ENCODE(coder, accessedPath);
3536
ENCODE(coder, ruleVersion);
3637
ENCODE(coder, ruleName);
38+
ENCODE(coder, process);
3739
}
3840

3941
- (instancetype)initWithCoder:(NSCoder *)decoder {
@@ -83,7 +85,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder {
8385
DECODE(decoder, cdhash, NSString);
8486
DECODE(decoder, fileSHA256, NSString);
8587
DECODE(decoder, signingID, NSString);
86-
DECODE(decoder, signingChain, NSString);
88+
DECODE_ARRAY(decoder, signingChain, MOLCertificate);
8789
DECODE(decoder, teamID, NSString);
8890
DECODE(decoder, pid, NSNumber);
8991
DECODE(decoder, executingUser, NSString);

Source/gui/SNTBinaryMessageWindowView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func copyDetailsToClipboard(e: SNTStoredExecutionEvent?, customURL: String?) {
7474
s += "\nCDHash : \(cdhash)"
7575
}
7676
s += "\nSHA-256 : \(e?.fileSHA256 ?? "unknown")"
77-
s += "\nParent : \(e?.parentName ?? "") (\(String(format: "%d", e?.ppid.intValue ?? 0)))"
77+
s += "\nParent : \(e?.parentName ?? "") (\(String(format: "%d", e?.ppid?.intValue ?? 0)))"
7878

7979
let url = SNTBlockMessage.eventDetailURL(for: e, customURL: customURL as String?)
8080
s += "\nURL : \(url?.absoluteString ?? "unknown")"
@@ -148,7 +148,7 @@ struct MoreDetailsView: View {
148148

149149
addLabel {
150150
Text("Parent").bold().font(Font.system(size: 12.0))
151-
Text(verbatim: "\(e?.parentName ?? "") (\(e?.ppid.stringValue ?? "unknown"))")
151+
Text(verbatim: "\(e?.parentName ?? "") (\(e?.ppid?.stringValue ?? "unknown"))")
152152
.textSelection(.enabled)
153153
}
154154

Source/gui/SNTFileAccessMessageWindowView.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,27 @@ struct MoreDetailsView: View {
6666
Spacer()
6767
addLabel {
6868
Text("Accessed Path").bold().font(Font.system(size: 12.0))
69-
Text(e.accessedPath).font(Font.system(size: 12.0).monospaced()).textSelection(.enabled)
69+
Text(e.accessedPath ?? "").font(Font.system(size: 12.0).monospaced()).textSelection(.enabled)
7070
}
7171

7272
Divider()
7373

7474
addLabel {
7575
Text("Binary Path").bold().font(Font.system(size: 12.0))
76-
Text(e.process.filePath).font(Font.system(size: 12.0).monospaced()).textSelection(.enabled)
76+
Text(e.process?.filePath ?? "").font(Font.system(size: 12.0).monospaced()).textSelection(.enabled)
7777
}
7878

7979
Divider()
8080

81-
if let signingID = e.process.signingID {
81+
if let signingID = e.process?.signingID {
8282
addLabel {
8383
Text("Signing ID").bold().font(Font.system(size: 12.0))
8484
Text(signingID).font(Font.system(size: 12.0).monospaced()).textSelection(.enabled)
8585
}
8686
Divider()
8787
}
8888

89-
if let cdHash = e.process.cdhash {
89+
if let cdHash = e.process?.cdhash {
9090
addLabel {
9191
Text("CDHash").bold().font(Font.system(size: 12.0))
9292
Text(cdHash).font(Font.system(size: 12.0).monospaced()).textSelection(.enabled)
@@ -97,7 +97,7 @@ struct MoreDetailsView: View {
9797
addLabel {
9898
Text("SHA-256").bold().font(Font.system(size: 12.0))
9999
// Fix the max width of this to 240px so that the SHA-256 splits across 2 lines evenly.
100-
Text(e.process.fileSHA256).font(Font.system(size: 12.0).monospaced()).frame(width: 240)
100+
Text(e.process?.fileSHA256 ?? "").font(Font.system(size: 12.0).monospaced()).frame(width: 240)
101101
.textSelection(.enabled)
102102
}
103103

@@ -151,11 +151,11 @@ struct Event: View {
151151
Divider()
152152

153153
VStack(alignment: .leading, spacing: 10.0) {
154-
TextWithLimit(e.accessedPath).textSelection(.enabled)
155-
TextWithLimit((e.process?.parent?.filePath as NSString?)?.lastPathComponent ?? "").textSelection(.enabled)
156-
TextWithLimit(e.process?.executingUser ?? "unknown").textSelection(.enabled)
157-
TextWithLimit(e.ruleName).textSelection(.enabled)
158-
TextWithLimit(e.ruleVersion).textSelection(.enabled)
154+
TextWithLimit(e.accessedPath ?? "<unknown>").textSelection(.enabled)
155+
TextWithLimit((e.process?.filePath as NSString?)?.lastPathComponent ?? "").textSelection(.enabled)
156+
TextWithLimit(e.process?.executingUser ?? "<unknown>").textSelection(.enabled)
157+
TextWithLimit(e.ruleName ?? "<unknown>").textSelection(.enabled)
158+
TextWithLimit(e.ruleVersion ?? "<unknown>").textSelection(.enabled)
159159

160160
}
161161
}.sheet(isPresented: $isShowingDetails) {

0 commit comments

Comments
 (0)