diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2018-07-13 14:06:02 -0400 |
---|---|---|
committer | James Morris <james.morris@microsoft.com> | 2018-07-16 15:31:57 -0400 |
commit | c77b8cdf745d91eca138e7bfa430dc6640b604a0 (patch) | |
tree | f1cc1edc3cecbff32a4450d252b551f5260ee9e1 | |
parent | ef96837b0de4af47732e2a8ebf5c18e8a885ded6 (diff) |
module: replace the existing LSM hook in init_module
Both the init_module and finit_module syscalls call either directly
or indirectly the security_kernel_read_file LSM hook. This patch
replaces the direct call in init_module with a call to the new
security_kernel_load_data hook and makes the corresponding changes
in SELinux, LoadPin, and IMA.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: Jeff Vander Stoep <jeffv@google.com>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Cc: Kees Cook <keescook@chromium.org>
Acked-by: Jessica Yu <jeyu@kernel.org>
Acked-by: Paul Moore <paul@paul-moore.com>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: James Morris <james.morris@microsoft.com>
-rw-r--r-- | kernel/module.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 23 | ||||
-rw-r--r-- | security/loadpin/loadpin.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 15 |
4 files changed, 32 insertions, 14 deletions
diff --git a/kernel/module.c b/kernel/module.c index f475f30eed8c..a7615d661910 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2876,7 +2876,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len, | |||
2876 | if (info->len < sizeof(*(info->hdr))) | 2876 | if (info->len < sizeof(*(info->hdr))) |
2877 | return -ENOEXEC; | 2877 | return -ENOEXEC; |
2878 | 2878 | ||
2879 | err = security_kernel_read_file(NULL, READING_MODULE); | 2879 | err = security_kernel_load_data(LOADING_MODULE); |
2880 | if (err) | 2880 | if (err) |
2881 | return err; | 2881 | return err; |
2882 | 2882 | ||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index e467664965e7..ef349a761609 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -429,16 +429,6 @@ void ima_post_path_mknod(struct dentry *dentry) | |||
429 | */ | 429 | */ |
430 | int ima_read_file(struct file *file, enum kernel_read_file_id read_id) | 430 | int ima_read_file(struct file *file, enum kernel_read_file_id read_id) |
431 | { | 431 | { |
432 | bool sig_enforce = is_module_sig_enforced(); | ||
433 | |||
434 | if (!file && read_id == READING_MODULE) { | ||
435 | if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES) && | ||
436 | (ima_appraise & IMA_APPRAISE_ENFORCE)) { | ||
437 | pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n"); | ||
438 | return -EACCES; /* INTEGRITY_UNKNOWN */ | ||
439 | } | ||
440 | return 0; /* We rely on module signature checking */ | ||
441 | } | ||
442 | return 0; | 432 | return 0; |
443 | } | 433 | } |
444 | 434 | ||
@@ -479,9 +469,6 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, | |||
479 | return 0; | 469 | return 0; |
480 | } | 470 | } |
481 | 471 | ||
482 | if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */ | ||
483 | return 0; | ||
484 | |||
485 | /* permit signed certs */ | 472 | /* permit signed certs */ |
486 | if (!file && read_id == READING_X509_CERTIFICATE) | 473 | if (!file && read_id == READING_X509_CERTIFICATE) |
487 | return 0; | 474 | return 0; |
@@ -510,6 +497,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, | |||
510 | */ | 497 | */ |
511 | int ima_load_data(enum kernel_load_data_id id) | 498 | int ima_load_data(enum kernel_load_data_id id) |
512 | { | 499 | { |
500 | bool sig_enforce; | ||
501 | |||
513 | if ((ima_appraise & IMA_APPRAISE_ENFORCE) != IMA_APPRAISE_ENFORCE) | 502 | if ((ima_appraise & IMA_APPRAISE_ENFORCE) != IMA_APPRAISE_ENFORCE) |
514 | return 0; | 503 | return 0; |
515 | 504 | ||
@@ -525,6 +514,14 @@ int ima_load_data(enum kernel_load_data_id id) | |||
525 | pr_err("Prevent firmware sysfs fallback loading.\n"); | 514 | pr_err("Prevent firmware sysfs fallback loading.\n"); |
526 | return -EACCES; /* INTEGRITY_UNKNOWN */ | 515 | return -EACCES; /* INTEGRITY_UNKNOWN */ |
527 | } | 516 | } |
517 | break; | ||
518 | case LOADING_MODULE: | ||
519 | sig_enforce = is_module_sig_enforced(); | ||
520 | |||
521 | if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES)) { | ||
522 | pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n"); | ||
523 | return -EACCES; /* INTEGRITY_UNKNOWN */ | ||
524 | } | ||
528 | default: | 525 | default: |
529 | break; | 526 | break; |
530 | } | 527 | } |
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index 5fa191252c8f..0716af28808a 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c | |||
@@ -173,9 +173,15 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) | |||
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
175 | 175 | ||
176 | static int loadpin_load_data(enum kernel_load_data_id id) | ||
177 | { | ||
178 | return loadpin_read_file(NULL, (enum kernel_read_file_id) id); | ||
179 | } | ||
180 | |||
176 | static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { | 181 | static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { |
177 | LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), | 182 | LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), |
178 | LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), | 183 | LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), |
184 | LSM_HOOK_INIT(kernel_load_data, loadpin_load_data), | ||
179 | }; | 185 | }; |
180 | 186 | ||
181 | void __init loadpin_add_hooks(void) | 187 | void __init loadpin_add_hooks(void) |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2b5ee5fbd652..a8bf324130f5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4073,6 +4073,20 @@ static int selinux_kernel_read_file(struct file *file, | |||
4073 | return rc; | 4073 | return rc; |
4074 | } | 4074 | } |
4075 | 4075 | ||
4076 | static int selinux_kernel_load_data(enum kernel_load_data_id id) | ||
4077 | { | ||
4078 | int rc = 0; | ||
4079 | |||
4080 | switch (id) { | ||
4081 | case LOADING_MODULE: | ||
4082 | rc = selinux_kernel_module_from_file(NULL); | ||
4083 | default: | ||
4084 | break; | ||
4085 | } | ||
4086 | |||
4087 | return rc; | ||
4088 | } | ||
4089 | |||
4076 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 4090 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
4077 | { | 4091 | { |
4078 | return avc_has_perm(&selinux_state, | 4092 | return avc_has_perm(&selinux_state, |
@@ -6972,6 +6986,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6972 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), | 6986 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), |
6973 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), | 6987 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), |
6974 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), | 6988 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), |
6989 | LSM_HOOK_INIT(kernel_load_data, selinux_kernel_load_data), | ||
6975 | LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file), | 6990 | LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file), |
6976 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), | 6991 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), |
6977 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), | 6992 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), |