On Fri, Oct 18, 2024 at 10:44 AM Stephen Smalley <stephen.smalley.work@xxxxxxxxx> wrote: > > On Thu, Oct 17, 2024 at 3:42 PM Matthew Sheets > <masheets@xxxxxxxxxxxxxxxxxxx> wrote: > > > > Hi All, > > > > I am currently working on an update for dbus-broker to trigger reload of > > its configuration whenever an SELinux policy load event is seen. > > > > For some background dbus-broker is comprised of two major elements the > > launcher and the broker. To trigger a config reload you can either send > > a SIGHUP to the launcher or send a message to the launcher over dbus. > > In most cases the launcher will be the brokers parent. > > > > Here is a link to my current PR: > > https://github.com/bus1/dbus-broker/pull/379 > > > > In this current state things work. The broker will see the POLICY_LOAD > > event and properly send a SIGHUP to its parent, but as David pointed out > > my initial attempt at the fix is no good since there is no guarantee > > that the brokers parent will be the launcher. > > > > My attempts at moving the callback registration into the launcher have > > been less successful. From what my debugging has told me is that the > > selinux_set_callback is going through successfully and the function > > pointer is correctly pointing to the callback function I define. But > > when I trigger a load_policy my callback function is never called. > > > > I am not familiar with how the callbacks in libselinux work under the > > hood so I am unsure about what could be blocking them in this situation. > > Caveat: I haven't looked deeply so take this with a grain of salt (or two). > There are generally two ways of discovering when policy has been reloaded: > 1. Create and receive notifications on a SELinux netlink socket, or > 2. Map the SELinux status page and poll it for updates to the policy seqno. > > Internally libselinux has switched to using the status page whenever > the kernel supports it since doing so is more efficient (no syscall > required to read it once you've mapped the page). As an aside, the > status page is also more easily "virtualizable" for SELinux namespaces > since it is per-SELinux state/namespace already (the netlink socket > can also be virtualized via a separate network namespace if/when my > namespace patches land but that requires you to unshare the network > namespace too). > > As far as libselinux APIs are concerned for the status page, you can > check for a policy reload or enforcing mode change by calling > selinux_status_updated() at any time after having done an initial > selinux_status_open(). selinux_status_updated() will call any > registered callbacks if enforcing mode or policy was changed, and, it > returns an indicator as to whether anything changed since the last > time it was called. > > Or if you choose to use the netlink socket and want to use the > libselinux APIs, you'd call avc_netlink_acquire_fd() to create and > take ownership of the SELinux netlink socket and then poll/select on > it for notifications, and upon receiving them, calling > avc_netlink_check_nb() to process them, including calling your > callbacks. > > But you have to do one of those two things in order for your callback > to be invoked. I assume dbus and dbus-broker are already doing one of > them which is why it works for them but not for the launcher. Also, both avc_has_perm*() and selinux_check_access() internally call selinux_status_updated() to ensure that they are using the latest enforcing mode and policy. So anything using those libselinux functions would get the status update for free.