diff options
Diffstat (limited to 'security/apparmor/lsm.c')
-rw-r--r-- | security/apparmor/lsm.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index b21830eced41..2e2a0dd4a73f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -48,8 +48,8 @@ int apparmor_initialized __initdata; | |||
48 | */ | 48 | */ |
49 | static void apparmor_cred_free(struct cred *cred) | 49 | static void apparmor_cred_free(struct cred *cred) |
50 | { | 50 | { |
51 | aa_free_task_context(cred->security); | 51 | aa_free_task_context(cred_cxt(cred)); |
52 | cred->security = NULL; | 52 | cred_cxt(cred) = NULL; |
53 | } | 53 | } |
54 | 54 | ||
55 | /* | 55 | /* |
@@ -62,7 +62,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp) | |||
62 | if (!cxt) | 62 | if (!cxt) |
63 | return -ENOMEM; | 63 | return -ENOMEM; |
64 | 64 | ||
65 | cred->security = cxt; | 65 | cred_cxt(cred) = cxt; |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
@@ -77,8 +77,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old, | |||
77 | if (!cxt) | 77 | if (!cxt) |
78 | return -ENOMEM; | 78 | return -ENOMEM; |
79 | 79 | ||
80 | aa_dup_task_context(cxt, old->security); | 80 | aa_dup_task_context(cxt, cred_cxt(old)); |
81 | new->security = cxt; | 81 | cred_cxt(new) = cxt; |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
@@ -87,8 +87,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old, | |||
87 | */ | 87 | */ |
88 | static void apparmor_cred_transfer(struct cred *new, const struct cred *old) | 88 | static void apparmor_cred_transfer(struct cred *new, const struct cred *old) |
89 | { | 89 | { |
90 | const struct aa_task_cxt *old_cxt = old->security; | 90 | const struct aa_task_cxt *old_cxt = cred_cxt(old); |
91 | struct aa_task_cxt *new_cxt = new->security; | 91 | struct aa_task_cxt *new_cxt = cred_cxt(new); |
92 | 92 | ||
93 | aa_dup_task_context(new_cxt, old_cxt); | 93 | aa_dup_task_context(new_cxt, old_cxt); |
94 | } | 94 | } |
@@ -469,7 +469,6 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd) | |||
469 | static int common_mmap(int op, struct file *file, unsigned long prot, | 469 | static int common_mmap(int op, struct file *file, unsigned long prot, |
470 | unsigned long flags) | 470 | unsigned long flags) |
471 | { | 471 | { |
472 | struct dentry *dentry; | ||
473 | int mask = 0; | 472 | int mask = 0; |
474 | 473 | ||
475 | if (!file || !file->f_security) | 474 | if (!file || !file->f_security) |
@@ -486,7 +485,6 @@ static int common_mmap(int op, struct file *file, unsigned long prot, | |||
486 | if (prot & PROT_EXEC) | 485 | if (prot & PROT_EXEC) |
487 | mask |= AA_EXEC_MMAP; | 486 | mask |= AA_EXEC_MMAP; |
488 | 487 | ||
489 | dentry = file->f_path.dentry; | ||
490 | return common_file_perm(op, file, mask); | 488 | return common_file_perm(op, file, mask); |
491 | } | 489 | } |
492 | 490 | ||
@@ -507,11 +505,9 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, | |||
507 | char **value) | 505 | char **value) |
508 | { | 506 | { |
509 | int error = -ENOENT; | 507 | int error = -ENOENT; |
510 | struct aa_profile *profile; | ||
511 | /* released below */ | 508 | /* released below */ |
512 | const struct cred *cred = get_task_cred(task); | 509 | const struct cred *cred = get_task_cred(task); |
513 | struct aa_task_cxt *cxt = cred->security; | 510 | struct aa_task_cxt *cxt = cred_cxt(cred); |
514 | profile = aa_cred_profile(cred); | ||
515 | 511 | ||
516 | if (strcmp(name, "current") == 0) | 512 | if (strcmp(name, "current") == 0) |
517 | error = aa_getprocattr(aa_newest_version(cxt->profile), | 513 | error = aa_getprocattr(aa_newest_version(cxt->profile), |
@@ -533,6 +529,8 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, | |||
533 | static int apparmor_setprocattr(struct task_struct *task, char *name, | 529 | static int apparmor_setprocattr(struct task_struct *task, char *name, |
534 | void *value, size_t size) | 530 | void *value, size_t size) |
535 | { | 531 | { |
532 | struct common_audit_data sa; | ||
533 | struct apparmor_audit_data aad = {0,}; | ||
536 | char *command, *args = value; | 534 | char *command, *args = value; |
537 | size_t arg_size; | 535 | size_t arg_size; |
538 | int error; | 536 | int error; |
@@ -576,30 +574,31 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, | |||
576 | } else if (strcmp(command, "permprofile") == 0) { | 574 | } else if (strcmp(command, "permprofile") == 0) { |
577 | error = aa_setprocattr_changeprofile(args, !AA_ONEXEC, | 575 | error = aa_setprocattr_changeprofile(args, !AA_ONEXEC, |
578 | AA_DO_TEST); | 576 | AA_DO_TEST); |
579 | } else if (strcmp(command, "permipc") == 0) { | 577 | } else |
580 | error = aa_setprocattr_permipc(args); | 578 | goto fail; |
581 | } else { | ||
582 | struct common_audit_data sa; | ||
583 | struct apparmor_audit_data aad = {0,}; | ||
584 | sa.type = LSM_AUDIT_DATA_NONE; | ||
585 | sa.aad = &aad; | ||
586 | aad.op = OP_SETPROCATTR; | ||
587 | aad.info = name; | ||
588 | aad.error = -EINVAL; | ||
589 | return aa_audit(AUDIT_APPARMOR_DENIED, | ||
590 | __aa_current_profile(), GFP_KERNEL, | ||
591 | &sa, NULL); | ||
592 | } | ||
593 | } else if (strcmp(name, "exec") == 0) { | 579 | } else if (strcmp(name, "exec") == 0) { |
594 | error = aa_setprocattr_changeprofile(args, AA_ONEXEC, | 580 | if (strcmp(command, "exec") == 0) |
595 | !AA_DO_TEST); | 581 | error = aa_setprocattr_changeprofile(args, AA_ONEXEC, |
596 | } else { | 582 | !AA_DO_TEST); |
583 | else | ||
584 | goto fail; | ||
585 | } else | ||
597 | /* only support the "current" and "exec" process attributes */ | 586 | /* only support the "current" and "exec" process attributes */ |
598 | return -EINVAL; | 587 | return -EINVAL; |
599 | } | 588 | |
600 | if (!error) | 589 | if (!error) |
601 | error = size; | 590 | error = size; |
602 | return error; | 591 | return error; |
592 | |||
593 | fail: | ||
594 | sa.type = LSM_AUDIT_DATA_NONE; | ||
595 | sa.aad = &aad; | ||
596 | aad.profile = aa_current_profile(); | ||
597 | aad.op = OP_SETPROCATTR; | ||
598 | aad.info = name; | ||
599 | aad.error = -EINVAL; | ||
600 | aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL); | ||
601 | return -EINVAL; | ||
603 | } | 602 | } |
604 | 603 | ||
605 | static int apparmor_task_setrlimit(struct task_struct *task, | 604 | static int apparmor_task_setrlimit(struct task_struct *task, |
@@ -886,7 +885,7 @@ static int __init set_init_cxt(void) | |||
886 | return -ENOMEM; | 885 | return -ENOMEM; |
887 | 886 | ||
888 | cxt->profile = aa_get_profile(root_ns->unconfined); | 887 | cxt->profile = aa_get_profile(root_ns->unconfined); |
889 | cred->security = cxt; | 888 | cred_cxt(cred) = cxt; |
890 | 889 | ||
891 | return 0; | 890 | return 0; |
892 | } | 891 | } |
@@ -915,8 +914,11 @@ static int __init apparmor_init(void) | |||
915 | 914 | ||
916 | error = register_security(&apparmor_ops); | 915 | error = register_security(&apparmor_ops); |
917 | if (error) { | 916 | if (error) { |
917 | struct cred *cred = (struct cred *)current->real_cred; | ||
918 | aa_free_task_context(cred_cxt(cred)); | ||
919 | cred_cxt(cred) = NULL; | ||
918 | AA_ERROR("Unable to register AppArmor\n"); | 920 | AA_ERROR("Unable to register AppArmor\n"); |
919 | goto set_init_cxt_out; | 921 | goto register_security_out; |
920 | } | 922 | } |
921 | 923 | ||
922 | /* Report that AppArmor successfully initialized */ | 924 | /* Report that AppArmor successfully initialized */ |
@@ -930,9 +932,6 @@ static int __init apparmor_init(void) | |||
930 | 932 | ||
931 | return error; | 933 | return error; |
932 | 934 | ||
933 | set_init_cxt_out: | ||
934 | aa_free_task_context(current->real_cred->security); | ||
935 | |||
936 | register_security_out: | 935 | register_security_out: |
937 | aa_free_root_ns(); | 936 | aa_free_root_ns(); |
938 | 937 | ||