loadpin.c (ecb41832bd2a7a3f8ac93527cec5e51e3827daed) | loadpin.c (eec4844fae7c033a0c1fc1eb3b8517aeb8b6cc49) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Module and Firmware Pinning Security Module 4 * 5 * Copyright 2011-2016 Google Inc. 6 * 7 * Author: Kees Cook <keescook@chromium.org> 8 */ --- 23 unchanged lines hidden (view full) --- 32 task_pid_nr(current), 33 cmdline ? "\"" : "", cmdline, cmdline ? "\"" : ""); 34 35 kfree(cmdline); 36 kfree(pathname); 37} 38 39static int enforce = IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE); | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Module and Firmware Pinning Security Module 4 * 5 * Copyright 2011-2016 Google Inc. 6 * 7 * Author: Kees Cook <keescook@chromium.org> 8 */ --- 23 unchanged lines hidden (view full) --- 32 task_pid_nr(current), 33 cmdline ? "\"" : "", cmdline, cmdline ? "\"" : ""); 34 35 kfree(cmdline); 36 kfree(pathname); 37} 38 39static int enforce = IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE); |
40static char *exclude_read_files[READING_MAX_ID]; 41static int ignore_read_file_id[READING_MAX_ID] __ro_after_init; |
|
40static struct super_block *pinned_root; 41static DEFINE_SPINLOCK(pinned_root_spinlock); 42 43#ifdef CONFIG_SYSCTL | 42static struct super_block *pinned_root; 43static DEFINE_SPINLOCK(pinned_root_spinlock); 44 45#ifdef CONFIG_SYSCTL |
44static int zero; 45static int one = 1; | |
46 47static struct ctl_path loadpin_sysctl_path[] = { 48 { .procname = "kernel", }, 49 { .procname = "loadpin", }, 50 { } 51}; 52 53static struct ctl_table loadpin_sysctl_table[] = { 54 { 55 .procname = "enforce", 56 .data = &enforce, 57 .maxlen = sizeof(int), 58 .mode = 0644, 59 .proc_handler = proc_dointvec_minmax, | 46 47static struct ctl_path loadpin_sysctl_path[] = { 48 { .procname = "kernel", }, 49 { .procname = "loadpin", }, 50 { } 51}; 52 53static struct ctl_table loadpin_sysctl_table[] = { 54 { 55 .procname = "enforce", 56 .data = &enforce, 57 .maxlen = sizeof(int), 58 .mode = 0644, 59 .proc_handler = proc_dointvec_minmax, |
60 .extra1 = &zero, 61 .extra2 = &one, | 60 .extra1 = SYSCTL_ZERO, 61 .extra2 = SYSCTL_ONE, |
62 }, 63 { } 64}; 65 66/* 67 * This must be called after early kernel init, since then the rootdev 68 * is available. 69 */ --- 46 unchanged lines hidden (view full) --- 116 } 117} 118 119static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) 120{ 121 struct super_block *load_root; 122 const char *origin = kernel_read_file_id_str(id); 123 | 62 }, 63 { } 64}; 65 66/* 67 * This must be called after early kernel init, since then the rootdev 68 * is available. 69 */ --- 46 unchanged lines hidden (view full) --- 116 } 117} 118 119static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) 120{ 121 struct super_block *load_root; 122 const char *origin = kernel_read_file_id_str(id); 123 |
124 /* If the file id is excluded, ignore the pinning. */ 125 if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) && 126 ignore_read_file_id[id]) { 127 report_load(origin, file, "pinning-excluded"); 128 return 0; 129 } 130 |
|
124 /* This handles the older init_module API that has a NULL file. */ 125 if (!file) { 126 if (!enforce) { 127 report_load(origin, NULL, "old-api-pinning-ignored"); 128 return 0; 129 } 130 131 report_load(origin, NULL, "old-api-denied"); --- 42 unchanged lines hidden (view full) --- 174} 175 176static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { 177 LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), 178 LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), 179 LSM_HOOK_INIT(kernel_load_data, loadpin_load_data), 180}; 181 | 131 /* This handles the older init_module API that has a NULL file. */ 132 if (!file) { 133 if (!enforce) { 134 report_load(origin, NULL, "old-api-pinning-ignored"); 135 return 0; 136 } 137 138 report_load(origin, NULL, "old-api-denied"); --- 42 unchanged lines hidden (view full) --- 181} 182 183static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { 184 LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), 185 LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), 186 LSM_HOOK_INIT(kernel_load_data, loadpin_load_data), 187}; 188 |
189static void __init parse_exclude(void) 190{ 191 int i, j; 192 char *cur; 193 194 /* 195 * Make sure all the arrays stay within expected sizes. This 196 * is slightly weird because kernel_read_file_str[] includes 197 * READING_MAX_ID, which isn't actually meaningful here. 198 */ 199 BUILD_BUG_ON(ARRAY_SIZE(exclude_read_files) != 200 ARRAY_SIZE(ignore_read_file_id)); 201 BUILD_BUG_ON(ARRAY_SIZE(kernel_read_file_str) < 202 ARRAY_SIZE(ignore_read_file_id)); 203 204 for (i = 0; i < ARRAY_SIZE(exclude_read_files); i++) { 205 cur = exclude_read_files[i]; 206 if (!cur) 207 break; 208 if (*cur == '\0') 209 continue; 210 211 for (j = 0; j < ARRAY_SIZE(ignore_read_file_id); j++) { 212 if (strcmp(cur, kernel_read_file_str[j]) == 0) { 213 pr_info("excluding: %s\n", 214 kernel_read_file_str[j]); 215 ignore_read_file_id[j] = 1; 216 /* 217 * Can not break, because one read_file_str 218 * may map to more than on read_file_id. 219 */ 220 } 221 } 222 } 223} 224 |
|
182static int __init loadpin_init(void) 183{ 184 pr_info("ready to pin (currently %senforcing)\n", 185 enforce ? "" : "not "); | 225static int __init loadpin_init(void) 226{ 227 pr_info("ready to pin (currently %senforcing)\n", 228 enforce ? "" : "not "); |
229 parse_exclude(); |
|
186 security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); 187 return 0; 188} 189 190DEFINE_LSM(loadpin) = { 191 .name = "loadpin", 192 .init = loadpin_init, 193}; 194 195/* Should not be mutable after boot, so not listed in sysfs (perm == 0). */ 196module_param(enforce, int, 0); 197MODULE_PARM_DESC(enforce, "Enforce module/firmware pinning"); | 230 security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); 231 return 0; 232} 233 234DEFINE_LSM(loadpin) = { 235 .name = "loadpin", 236 .init = loadpin_init, 237}; 238 239/* Should not be mutable after boot, so not listed in sysfs (perm == 0). */ 240module_param(enforce, int, 0); 241MODULE_PARM_DESC(enforce, "Enforce module/firmware pinning"); |
242module_param_array_named(exclude, exclude_read_files, charp, NULL, 0); 243MODULE_PARM_DESC(exclude, "Exclude pinning specific read file types"); |
|