Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only remount on startup if remount args are set #1222

Merged
merged 1 commit into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Source/santactl/Commands/SNTCommandStatus.m
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
Expand Down Expand Up @@ -190,10 +198,10 @@ - (instancetype)initWithESAPI:(std::shared_ptr<EndpointSecurityAPI>)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:@[]];
Expand All @@ -211,7 +219,7 @@ - (instancetype)initWithESAPI:(std::shared_ptr<EndpointSecurityAPI>)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
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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] &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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 {
Expand Down