if (!writable)
pr_info("load pinning engaged.\n");
}
/* * This must be called after early kernel init, since then the rootdev * is available.
*/ staticbool sb_is_writable(struct super_block *mnt_sb)
{ bool writable = true;
if (mnt_sb->s_bdev)
writable = !bdev_read_only(mnt_sb->s_bdev);
return writable;
}
staticvoid loadpin_sb_free_security(struct super_block *mnt_sb)
{ /* * When unmounting the filesystem we were using for load * pinning, we acknowledge the superblock release, but make sure * no other modules or firmware can be loaded when we are in * enforcing mode. Otherwise, allow the root to be reestablished.
*/ if (!IS_ERR_OR_NULL(pinned_root) && mnt_sb == pinned_root) { if (enforce) {
pinned_root = ERR_PTR(-EIO);
pr_info("umount pinned fs: refusing further loads\n");
} else {
pinned_root = NULL;
}
}
}
/* If the file id is excluded, ignore the pinning. */ if ((unsignedint)id < ARRAY_SIZE(ignore_read_file_id) &&
ignore_read_file_id[id]) {
report_load(origin, file, "pinning-excluded"); return 0;
}
/* This handles the older init_module API that has a NULL file. */ if (!file) { if (!enforce) {
report_load(origin, NULL, "old-api-pinning-ignored"); return 0;
}
/* First loaded module/firmware defines the root for all others. */
spin_lock(&pinned_root_spinlock); /* * pinned_root is only NULL at startup or when the pinned root has * been unmounted while we are not in enforcing mode. Otherwise, it * is either a valid reference, or an ERR_PTR.
*/ if (!pinned_root) {
pinned_root = load_root;
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");
}
if (IS_ERR_OR_NULL(pinned_root) ||
((load_root != pinned_root) && !dm_verity_loadpin_is_bdev_trusted(load_root->s_bdev))) { if (unlikely(!enforce)) {
report_load(origin, file, "pinning-ignored"); return 0;
}
staticint loadpin_read_file(struct file *file, enum kernel_read_file_id id, bool contents)
{ /* * LoadPin only cares about the _origin_ of a file, not its * contents, so we can ignore the "are full contents available" * argument here.
*/ return loadpin_check(file, id);
}
staticint loadpin_load_data(enum kernel_load_data_id id, bool contents)
{ /* * LoadPin only cares about the _origin_ of a file, not its * contents, so a NULL file is passed, and we can ignore the * state of "contents".
*/ return loadpin_check(NULL, (enum kernel_read_file_id) id);
}
staticvoid __init parse_exclude(void)
{ int i, j; char *cur;
/* * Make sure all the arrays stay within expected sizes. This * is slightly weird because kernel_read_file_str[] includes * READING_MAX_ID, which isn't actually meaningful here.
*/
BUILD_BUG_ON(ARRAY_SIZE(exclude_read_files) !=
ARRAY_SIZE(ignore_read_file_id));
BUILD_BUG_ON(ARRAY_SIZE(kernel_read_file_str) <
ARRAY_SIZE(ignore_read_file_id));
for (i = 0; i < ARRAY_SIZE(exclude_read_files); i++) {
cur = exclude_read_files[i]; if (!cur) break; if (*cur == '\0') continue;
for (j = 0; j < ARRAY_SIZE(ignore_read_file_id); j++) { if (strcmp(cur, kernel_read_file_str[j]) == 0) {
pr_info("excluding: %s\n",
kernel_read_file_str[j]);
ignore_read_file_id[j] = 1; /* * Can not break, because one read_file_str * may map to more than on read_file_id.
*/
}
}
}
}
/** * init_loadpin_securityfs - create the securityfs directory for LoadPin * * We can not put this method normally under the loadpin_init() code path since * the security subsystem gets initialized before the vfs caches. * * Returns 0 if the securityfs directory creation was successful.
*/ staticint __init init_loadpin_securityfs(void)
{ struct dentry *loadpin_dir, *dentry;
loadpin_dir = securityfs_create_dir("loadpin", NULL); if (IS_ERR(loadpin_dir)) {
pr_err("LoadPin: could not create securityfs dir: %ld\n",
PTR_ERR(loadpin_dir)); return PTR_ERR(loadpin_dir);
}
dentry = securityfs_create_file("dm-verity", 0600, loadpin_dir,
(void *)LOADPIN_DM_VERITY, &loadpin_dm_verity_ops); if (IS_ERR(dentry)) {
pr_err("LoadPin: could not create securityfs entry 'dm-verity': %ld\n",
PTR_ERR(dentry)); return PTR_ERR(dentry);
}
return 0;
}
fs_initcall(init_loadpin_securityfs);
#endif/* CONFIG_SECURITY_LOADPIN_VERITY */
/* Should not be mutable after boot, so not listed in sysfs (perm == 0). */
module_param(enforce, int, 0);
MODULE_PARM_DESC(enforce, "Enforce module/firmware pinning");
module_param_array_named(exclude, exclude_read_files, charp, NULL, 0);
MODULE_PARM_DESC(exclude, "Exclude pinning specific read file types");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.