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

macos: Add polling to OpenBSM publisher #6436

Merged
merged 5 commits into from
May 29, 2020

Conversation

theopolis
Copy link
Member

I don't think this is the root cause of #6431, but while reviewing the OpenBSM publisher I noticed it can hang osquery if there are no events in the audit queue.

This change applies the same polling interval and error handling as Linux.

osquery/events/darwin/openbsm.cpp Show resolved Hide resolved
osquery/events/darwin/openbsm.cpp Show resolved Hide resolved
osquery/events/darwin/openbsm.cpp Outdated Show resolved Hide resolved
@theopolis
Copy link
Member Author

@uptycs-nishant, I'll take a closer look at waiting in the select today. I may update this PR with a solution.

@theopolis
Copy link
Member Author

I looked at the events.cpp state machine a bit closer and found some no-op improvements where we can be consistent about (1) changing the state, (2) updating the state flag. I also saw that the inherited ::interrupted is a no-op since we are not using the dispatcher to control thread state. To protect publishers from making a mistake I added a private overload.

So there are some distinct changes in this PR:

  • Add polling to OpenBSM
  • Improve the EventPublisher abstractions
  • (TODO) Updating OpenBSM to wait during select instead of the default events cool-off

@theopolis
Copy link
Member Author

Even though TSAN did not warn about a potential race, I wanted to add mutexes because these data members can be accessed from different threads.

@directionless directionless added this to the 4.4.0 milestone May 26, 2020
@directionless
Copy link
Member

I built 6003890, using -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 and ran it on my 10.14.6 machine. Using the auditpipe configs (Thanks!) and osqueryi, I got reasonable data from process_events and socket_events. I'm not sure if there was any other manual testing you wanted.

}

WriteLock lock(event_ids_mutex_);
event_ids_ = event_ids;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event_ids_ = std::move(event_ids);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make this change but heads up I'm only really worried about optimizing the critical dequeue/parse path. A good follow up on the optimization route is looking at the process_events implementation on macOS and improving the string concatenation. (if you have more time to dedicate here)

ev_classes.insert("fw");
ev_classes.insert("fr");
ev_classes.insert("fa");
ev_classes.insert("fm");
}

struct au_class_ent* ace = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about?
while ((ace = getauclassent()) != nullptr) {
auto it = ev_classes.find(ace->ac_name);
if (it != ev_classes.end()) {
ADD_TO_MASK(&pr_flags, ace->ac_class, AU_PRS_BOTH);
}
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this only runs once I don't think we need to be super optimized.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, then why changing from std::vector to std::set?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess because we started using set for event_ids and it's the more appropriate container for this code here too, so I figured why not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::vector allows duplicates? set feels more appropriate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which property of set are we using here? We are iterating all the elements here for which vector or array is sufficient, I believe.

Copy link
Member

@directionless directionless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not solid enough on c++ to be super confident, but the code broadly looks fine to me. And it builds/tests okay.

ev_classes.insert("fw");
ev_classes.insert("fr");
ev_classes.insert("fa");
ev_classes.insert("fm");
}

struct au_class_ent* ace = nullptr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::vector allows duplicates? set feels more appropriate.

subscriber->tearDown();
subscriber->state(EventState::EVENT_NONE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why invert the order here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent with the other call sites that set state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants