Page MenuHomeFreeBSD

netlink: Wait for running handlers before a generic family is freed
Needs ReviewPublic

Authored by rcm on Fri, Oct 9, 2:44 AM.

Details

Reviewers
glebius
melifaro
Summary

genl_handle_message() looks a family and its command up with no lock,
and genl_unregister_family() frees the command table and clears the
family under the generic netlink lock without waiting for handlers
that are running. A request that arrives while the module owning the
family is unloaded can run a freed handler, or read a freed command:
unloading pflow(4) in a loop while requests are sent to it panics an
INVARIANTS kernel within seconds with "priv_check_cred: invalid
privilege" from the freed table's cmd_priv.

Take the generic netlink lock shared to look the family and command
up, copy the command, and count the handler as busy in the family
until it returns; genl_unregister_family() detaches the command table
under the lock and waits for the busy count to drain before it frees
the table and clears the family. The family's name stays until then,
so the slot cannot be reused meanwhile. The nlctrl family dump reads
the family table under the shared lock too.

Fixes: 7e5bf68495cc ("netlink: add netlink support")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped