Skip to content

Commit eba7735

Browse files
committed
LoadPin: Allow filesystem switch when not enforcing
For LoadPin to be used at all in a classic distro environment, it needs to allow for switching filesystems (from the initramfs to the "real" root filesystem). To allow for this, if the "enforce" mode is not set at boot, reset the pinned filesystem tracking when the pinned filesystem gets unmounted instead of invalidating further loads. Once enforcement is set, it cannot be unset, and the pinning will stick. This means that distros can build with CONFIG_SECURITY_LOADPIN=y, but with CONFIG_SECURITY_LOADPIN_ENFORCE disabled, but after boot is running, the system can enable enforcement: $ sysctl -w kernel.loadpin.enforced=1 Cc: Paul Moore <[email protected]> Cc: James Morris <[email protected]> Cc: "Serge E. Hallyn" <[email protected]> Cc: [email protected] Signed-off-by: Kees Cook <[email protected]> Reviewed-by: Serge Hallyn <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2cfaa84 commit eba7735

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

security/loadpin/loadpin.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,16 @@ static void loadpin_sb_free_security(struct super_block *mnt_sb)
119119
/*
120120
* When unmounting the filesystem we were using for load
121121
* pinning, we acknowledge the superblock release, but make sure
122-
* no other modules or firmware can be loaded.
122+
* no other modules or firmware can be loaded when we are in
123+
* enforcing mode. Otherwise, allow the root to be reestablished.
123124
*/
124125
if (!IS_ERR_OR_NULL(pinned_root) && mnt_sb == pinned_root) {
125-
pinned_root = ERR_PTR(-EIO);
126-
pr_info("umount pinned fs: refusing further loads\n");
126+
if (enforce) {
127+
pinned_root = ERR_PTR(-EIO);
128+
pr_info("umount pinned fs: refusing further loads\n");
129+
} else {
130+
pinned_root = NULL;
131+
}
127132
}
128133
}
129134

@@ -158,8 +163,9 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id)
158163
/* First loaded module/firmware defines the root for all others. */
159164
spin_lock(&pinned_root_spinlock);
160165
/*
161-
* pinned_root is only NULL at startup. Otherwise, it is either
162-
* a valid reference, or an ERR_PTR.
166+
* pinned_root is only NULL at startup or when the pinned root has
167+
* been unmounted while we are not in enforcing mode. Otherwise, it
168+
* is either a valid reference, or an ERR_PTR.
163169
*/
164170
if (!pinned_root) {
165171
pinned_root = load_root;

0 commit comments

Comments
 (0)