• Al Viro's avatar
    selinux: saner handling of policy reloads · 4a0b33f7
    Al Viro authored
    On policy reload selinuxfs replaces two subdirectories (/booleans
    and /class) with new variants.  Unfortunately, that's done with
    serious abuses of directory locking.
    
    1) lock_rename() should be done to parents, not to objects being
    exchanged
    
    2) there's a bunch of reasons why it should not be done for directories
    that do not have a common ancestor; most of those do not apply to
    selinuxfs, but even in the best case the proof is subtle and brittle.
    
    3) failure halfway through the creation of /class will leak
    names and values arrays.
    
    4) use of d_genocide() is also rather brittle; it's probably not much of
    a bug per se, but e.g. an overmount of /sys/fs/selinuxfs/classes/shm/index
    with any regular file will end up with leaked mount on policy reload.
    Sure, don't do it, but...
    
    Let's stop messing with disconnected directories; just create
    a temporary (/.swapover) with no permissions for anyone (on the
    level of ->permission() returing -EPERM, no matter who's calling
    it) and build the new /booleans and /class in there; then
    lock_rename on root and that temporary directory and d_exchange()
    old and new both for class and booleans.  Then unlock and use
    simple_recursive_removal() to take the temporary out; it's much
    more robust.
    
    And instead of bothering with separate pathways for freeing
    new (on failure halfway through) and old (on success) names/values,
    do all freeing in one place.  With temporaries swapped with the
    old ones when we are past all possible failures.
    
    The only user-visible difference is that /.swapover shows up
    (but isn't possible to open, look up into, etc.) for the
    duration of policy reload.
    Reviewed-by: default avatarStephen Smalley <stephen.smalley.work@gmail.com>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    [PM: applied some fixes from Al post merge]
    Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
    4a0b33f7
selinuxfs.c 49.5 KB