LoadPin: Move pin reporting cleanly out of locking
authorKees Cook <keescook@chromium.org>
Fri, 9 Dec 2022 19:57:44 +0000 (11:57 -0800)
committerKees Cook <keescook@chromium.org>
Thu, 19 Jan 2023 23:18:20 +0000 (15:18 -0800)
Refactor the pin reporting to be more cleanly outside the locking. It
was already, but moving it around helps clear the path for the root to
switch when not enforcing.

Cc: Paul Moore <paul@paul-moore.com>
Cc: James Morris <jmorris@namei.org>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: linux-security-module@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Serge Hallyn <serge@hallyn.com>
Link: https://lore.kernel.org/r/20221209195746.1366607-3-keescook@chromium.org
security/loadpin/loadpin.c

index 5b15f8f7268d3c639cf57d9e65fa041d9523a6a1..ef12d77548aeebe4ba8325449896dcecd653dbee 100644 (file)
@@ -131,6 +131,7 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id)
 {
        struct super_block *load_root;
        const char *origin = kernel_read_file_id_str(id);
+       bool first_root_pin = false;
        bool load_root_writable;
 
        /* If the file id is excluded, ignore the pinning. */
@@ -162,18 +163,14 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id)
         */
        if (!pinned_root) {
                pinned_root = load_root;
-               /*
-                * Unlock now since it's only pinned_root we care about.
-                * In the worst case, we will (correctly) report pinning
-                * failures before we have announced that pinning is
-                * enforcing. This would be purely cosmetic.
-                */
-               spin_unlock(&pinned_root_spinlock);
+               first_root_pin = true;
+       }
+       spin_unlock(&pinned_root_spinlock);
+
+       if (first_root_pin) {
                report_writable(pinned_root, load_root_writable);
                set_sysctl(load_root_writable);
                report_load(origin, file, "pinned");
-       } else {
-               spin_unlock(&pinned_root_spinlock);
        }
 
        if (IS_ERR_OR_NULL(pinned_root) ||