diff --git a/Source/santactl/Commands/SNTCommandStatus.m b/Source/santactl/Commands/SNTCommandStatus.m index 9e3a2fe88..a5cba950b 100644 --- a/Source/santactl/Commands/SNTCommandStatus.m +++ b/Source/santactl/Commands/SNTCommandStatus.m @@ -267,7 +267,8 @@ - (void)runWithArguments:(NSArray *)arguments { printf(" %-25s | %s\n", "USB Remounting Mode", [[configurator.remountUSBMode componentsJoinedByString:@", "] UTF8String]); } - printf(" %-25s | %s\n", "On Start USB Options", StartupOptionToString(configurator.onStartUSBOptions).UTF8String); + printf(" %-25s | %s\n", "On Start USB Options", + StartupOptionToString(configurator.onStartUSBOptions).UTF8String); printf(" %-25s | %lld (Peak: %.2f%%)\n", "Watchdog CPU Events", cpuEvents, cpuPeak); printf(" %-25s | %lld (Peak: %.2fMB)\n", "Watchdog RAM Events", ramEvents, ramPeak); diff --git a/Source/santad/EventProviders/SNTEndpointSecurityDeviceManager.mm b/Source/santad/EventProviders/SNTEndpointSecurityDeviceManager.mm index 52a6c9168..41f521e96 100644 --- a/Source/santad/EventProviders/SNTEndpointSecurityDeviceManager.mm +++ b/Source/santad/EventProviders/SNTEndpointSecurityDeviceManager.mm @@ -41,10 +41,18 @@ using santa::santad::event_providers::endpoint_security::Message; using santa::santad::logs::endpoint_security::Logger; +// Defined operations for startup metrics: +// Device shouldn't be operated on (e.g. not a mass storage device) static NSString *const kMetricStartupDiskOperationSkip = @"Skipped"; +// Device already had appropriate flags set static NSString *const kMetricStartupDiskOperationAllowed = @"Allowed"; +// Device failed to be unmounted static NSString *const kMetricStartupDiskOperationUnmountFailed = @"UnmountFailed"; +// Device failed to be remounted static NSString *const kMetricStartupDiskOperationRemountFailed = @"RemountFailed"; +// Remounts were requested, but remount args weren't set +static NSString *const kMetricStartupDiskOperationRemountSkipped = @"RemountSkipped"; +// Operations on device matching the configured startup pref wwere successful static NSString *const kMetricStartupDiskOperationSuccess = @"Success"; @interface SNTEndpointSecurityDeviceManager () @@ -190,10 +198,10 @@ - (instancetype)initWithESAPI:(std::shared_ptr)esApi _diskArbSession = DASessionCreate(NULL); DASessionSetDispatchQueue(_diskArbSession, _diskQueue); - SNTMetricInt64Gauge *startupPrefsMetric = [[SNTMetricSet sharedInstance] - int64GaugeWithName:@"/santa/device_manager/startup_preference" - fieldNames:@[] - helpText:@"The current startup preference value"]; + SNTMetricInt64Gauge *startupPrefsMetric = + [[SNTMetricSet sharedInstance] int64GaugeWithName:@"/santa/device_manager/startup_preference" + fieldNames:@[] + helpText:@"The current startup preference value"]; [[SNTMetricSet sharedInstance] registerCallback:^{ [startupPrefsMetric set:startupPrefs forFieldValues:@[]]; @@ -211,7 +219,7 @@ - (instancetype)initWithESAPI:(std::shared_ptr)esApi return self; } -- (uint32_t)updatedMountFlags:(struct statfs*)sfs { +- (uint32_t)updatedMountFlags:(struct statfs *)sfs { uint32_t mask = sfs->f_flags | mountArgsToMask(self.remountArgs); // NB: APFS mounts get MNT_JOURNALED implicitly set. However, mount_apfs @@ -258,7 +266,15 @@ - (BOOL)shouldOperateOnDisk:(DADiskRef)disk { return true; } +- (BOOL)haveRemountArgs { + return [self.remountArgs count] > 0; +} + - (BOOL)remountUSBModeContainsFlags:(uint32_t)flags { + if (![self haveRemountArgs]) { + return false; + } + uint32_t requiredFlags = mountArgsToMask(self.remountArgs); LOGD(@" Got mount flags: 0x%08x | %@", flags, maskToMountArgs(flags)); @@ -310,7 +326,7 @@ - (void)performStartupTasks:(SNTDeviceManagerStartupPreferences)startupPrefs { continue; } - if (self.remountArgs != nil && [self remountUSBModeContainsFlags:sfs->f_flags]) { + if ([self remountUSBModeContainsFlags:sfs->f_flags]) { LOGI(@"Allowing existing mount as flags contain RemountUSBMode. '%s' -> '%s'", sfs->f_mntfromname, sfs->f_mntonname); [self incrementStartupMetricsOperation:kMetricStartupDiskOperationAllowed]; @@ -339,6 +355,12 @@ - (void)performStartupTasks:(SNTDeviceManagerStartupPreferences)startupPrefs { if (startupPrefs == SNTDeviceManagerStartupPreferencesRemount || startupPrefs == SNTDeviceManagerStartupPreferencesForceRemount) { + if (![self haveRemountArgs]) { + [self incrementStartupMetricsOperation:kMetricStartupDiskOperationRemountSkipped]; + LOGW(@"Remount requested during startup, but no remount args set. Leaving unmounted."); + continue; + } + uint32_t newMode = [self updatedMountFlags:sfs]; LOGI(@"Attempting to mount device again changing flags: 0x%08x --> 0x%08x", sfs->f_flags, newMode); @@ -439,9 +461,7 @@ - (es_auth_result_t)handleAuthMount:(const Message &)m { initWithOnName:[NSString stringWithUTF8String:eventStatFS->f_mntonname] fromName:[NSString stringWithUTF8String:eventStatFS->f_mntfromname]]; - BOOL shouldRemount = self.remountArgs != nil && [self.remountArgs count] > 0; - - if (shouldRemount) { + if ([self haveRemountArgs]) { event.remountArgs = self.remountArgs; if ([self remountUSBModeContainsFlags:eventStatFS->f_flags] && diff --git a/Source/santad/EventProviders/SNTEndpointSecurityDeviceManagerTest.mm b/Source/santad/EventProviders/SNTEndpointSecurityDeviceManagerTest.mm index fdad20a7b..b2ec19c07 100644 --- a/Source/santad/EventProviders/SNTEndpointSecurityDeviceManagerTest.mm +++ b/Source/santad/EventProviders/SNTEndpointSecurityDeviceManagerTest.mm @@ -55,7 +55,7 @@ - (instancetype)init; - (void)logDiskAppeared:(NSDictionary *)props; - (BOOL)shouldOperateOnDisk:(DADiskRef)disk; - (void)performStartupTasks:(SNTDeviceManagerStartupPreferences)startupPrefs; -- (uint32_t)updatedMountFlags:(struct statfs*)sfs; +- (uint32_t)updatedMountFlags:(struct statfs *)sfs; @end @interface SNTEndpointSecurityDeviceManagerTest : XCTestCase @@ -450,9 +450,9 @@ - (void)testPerformStartupTasks { PerformStartupTest(@[ disk1, disk2 ], nil, SNTDeviceManagerStartupPreferencesRemount); XCTAssertTrue(disk1.wasUnmounted); - XCTAssertTrue(disk1.wasMounted); + XCTAssertFalse(disk1.wasMounted); XCTAssertTrue(disk2.wasUnmounted); - XCTAssertTrue(disk2.wasMounted); + XCTAssertFalse(disk2.wasMounted); } } @@ -470,7 +470,8 @@ - (void)testUpdatedMountFlags { // For APFS, flags are still unioned, but MNT_JOUNRNALED is cleared strlcpy(sfs.f_fstypename, "apfs", sizeof(sfs.f_fstypename)); - XCTAssertEqual([deviceManager updatedMountFlags:&sfs], (sfs.f_flags | MNT_RDONLY | MNT_NOEXEC) & ~MNT_JOURNALED); + XCTAssertEqual([deviceManager updatedMountFlags:&sfs], + (sfs.f_flags | MNT_RDONLY | MNT_NOEXEC) & ~MNT_JOURNALED); } - (void)testEnable {