aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2016-06-22 21:01:08 -0400
committerJohn Johansen <john.johansen@canonical.com>2016-07-12 11:43:10 -0400
commit58acf9d911c8831156634a44d0b022d683e1e50c (patch)
treedf76653f50579f989c36eab7139919523f50d561
parent5f20fdfed16bc599a325a145bf0123a8e1c9beea (diff)
apparmor: fix module parameters can be changed after policy is locked
the policy_lock parameter is a one way switch that prevents policy from being further modified. Unfortunately some of the module parameters can effectively modify policy by turning off enforcement. split policy_admin_capable into a view check and a full admin check, and update the admin check to test the policy_lock parameter. Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r--security/apparmor/include/policy.h2
-rw-r--r--security/apparmor/lsm.c22
-rw-r--r--security/apparmor/policy.c18
3 files changed, 29 insertions, 13 deletions
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index c28b0f20ab53..52275f040a5f 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -403,6 +403,8 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
403 return profile->audit; 403 return profile->audit;
404} 404}
405 405
406bool policy_view_capable(void);
407bool policy_admin_capable(void);
406bool aa_may_manage_policy(int op); 408bool aa_may_manage_policy(int op);
407 409
408#endif /* __AA_POLICY_H */ 410#endif /* __AA_POLICY_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 656b97c2e1ea..300f8336fb8e 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -730,51 +730,49 @@ __setup("apparmor=", apparmor_enabled_setup);
730/* set global flag turning off the ability to load policy */ 730/* set global flag turning off the ability to load policy */
731static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp) 731static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp)
732{ 732{
733 if (!capable(CAP_MAC_ADMIN)) 733 if (!policy_admin_capable())
734 return -EPERM; 734 return -EPERM;
735 if (aa_g_lock_policy)
736 return -EACCES;
737 return param_set_bool(val, kp); 735 return param_set_bool(val, kp);
738} 736}
739 737
740static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp) 738static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp)
741{ 739{
742 if (!capable(CAP_MAC_ADMIN)) 740 if (!policy_view_capable())
743 return -EPERM; 741 return -EPERM;
744 return param_get_bool(buffer, kp); 742 return param_get_bool(buffer, kp);
745} 743}
746 744
747static int param_set_aabool(const char *val, const struct kernel_param *kp) 745static int param_set_aabool(const char *val, const struct kernel_param *kp)
748{ 746{
749 if (!capable(CAP_MAC_ADMIN)) 747 if (!policy_admin_capable())
750 return -EPERM; 748 return -EPERM;
751 return param_set_bool(val, kp); 749 return param_set_bool(val, kp);
752} 750}
753 751
754static int param_get_aabool(char *buffer, const struct kernel_param *kp) 752static int param_get_aabool(char *buffer, const struct kernel_param *kp)
755{ 753{
756 if (!capable(CAP_MAC_ADMIN)) 754 if (!policy_view_capable())
757 return -EPERM; 755 return -EPERM;
758 return param_get_bool(buffer, kp); 756 return param_get_bool(buffer, kp);
759} 757}
760 758
761static int param_set_aauint(const char *val, const struct kernel_param *kp) 759static int param_set_aauint(const char *val, const struct kernel_param *kp)
762{ 760{
763 if (!capable(CAP_MAC_ADMIN)) 761 if (!policy_admin_capable())
764 return -EPERM; 762 return -EPERM;
765 return param_set_uint(val, kp); 763 return param_set_uint(val, kp);
766} 764}
767 765
768static int param_get_aauint(char *buffer, const struct kernel_param *kp) 766static int param_get_aauint(char *buffer, const struct kernel_param *kp)
769{ 767{
770 if (!capable(CAP_MAC_ADMIN)) 768 if (!policy_view_capable())
771 return -EPERM; 769 return -EPERM;
772 return param_get_uint(buffer, kp); 770 return param_get_uint(buffer, kp);
773} 771}
774 772
775static int param_get_audit(char *buffer, struct kernel_param *kp) 773static int param_get_audit(char *buffer, struct kernel_param *kp)
776{ 774{
777 if (!capable(CAP_MAC_ADMIN)) 775 if (!policy_view_capable())
778 return -EPERM; 776 return -EPERM;
779 777
780 if (!apparmor_enabled) 778 if (!apparmor_enabled)
@@ -786,7 +784,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
786static int param_set_audit(const char *val, struct kernel_param *kp) 784static int param_set_audit(const char *val, struct kernel_param *kp)
787{ 785{
788 int i; 786 int i;
789 if (!capable(CAP_MAC_ADMIN)) 787 if (!policy_admin_capable())
790 return -EPERM; 788 return -EPERM;
791 789
792 if (!apparmor_enabled) 790 if (!apparmor_enabled)
@@ -807,7 +805,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
807 805
808static int param_get_mode(char *buffer, struct kernel_param *kp) 806static int param_get_mode(char *buffer, struct kernel_param *kp)
809{ 807{
810 if (!capable(CAP_MAC_ADMIN)) 808 if (!policy_admin_capable())
811 return -EPERM; 809 return -EPERM;
812 810
813 if (!apparmor_enabled) 811 if (!apparmor_enabled)
@@ -819,7 +817,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
819static int param_set_mode(const char *val, struct kernel_param *kp) 817static int param_set_mode(const char *val, struct kernel_param *kp)
820{ 818{
821 int i; 819 int i;
822 if (!capable(CAP_MAC_ADMIN)) 820 if (!policy_admin_capable())
823 return -EPERM; 821 return -EPERM;
824 822
825 if (!apparmor_enabled) 823 if (!apparmor_enabled)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 780712553651..179e68d7dc5f 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -918,6 +918,22 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
918 &sa, NULL); 918 &sa, NULL);
919} 919}
920 920
921bool policy_view_capable(void)
922{
923 struct user_namespace *user_ns = current_user_ns();
924 bool response = false;
925
926 if (ns_capable(user_ns, CAP_MAC_ADMIN))
927 response = true;
928
929 return response;
930}
931
932bool policy_admin_capable(void)
933{
934 return policy_view_capable() && !aa_g_lock_policy;
935}
936
921/** 937/**
922 * aa_may_manage_policy - can the current task manage policy 938 * aa_may_manage_policy - can the current task manage policy
923 * @op: the policy manipulation operation being done 939 * @op: the policy manipulation operation being done
@@ -932,7 +948,7 @@ bool aa_may_manage_policy(int op)
932 return 0; 948 return 0;
933 } 949 }
934 950
935 if (!capable(CAP_MAC_ADMIN)) { 951 if (!policy_admin_capable()) {
936 audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES); 952 audit_policy(op, GFP_KERNEL, NULL, "not policy admin", -EACCES);
937 return 0; 953 return 0;
938 } 954 }