aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_access.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2011-01-17 11:05:27 -0500
committerCasey Schaufler <casey@schaufler-ca.com>2011-01-17 11:05:27 -0500
commit7898e1f8e9eb1bee88c92d636e0ab93f2cbe31c6 (patch)
treed4aaa367bb42d0ff9d1e4ba227f248b5b9cd7687 /security/smack/smack_access.c
parentaeda4ac3efc29e4d55989abd0a73530453aa69ba (diff)
Subject: [PATCH] Smack: mmap controls for library containment
In the embedded world there are often situations where libraries are updated from a variety of sources, for a variety of reasons, and with any number of security characteristics. These differences might include privilege required for a given library provided interface to function properly, as occurs from time to time in graphics libraries. There are also cases where it is important to limit use of libraries based on the provider of the library and the security aware application may make choices based on that criteria. These issues are addressed by providing an additional Smack label that may optionally be assigned to an object, the SMACK64MMAP attribute. An mmap operation is allowed if there is no such attribute. If there is a SMACK64MMAP attribute the mmap is permitted only if a subject with that label has all of the access permitted a subject with the current task label. Security aware applications may from time to time wish to reduce their "privilege" to avoid accidental use of privilege. One case where this arises is the environment in which multiple sources provide libraries to perform the same functions. An application may know that it should eschew services made available from a particular vendor, or of a particular version. In support of this a secondary list of Smack rules has been added that is local to the task. This list is consulted only in the case where the global list has approved access. It can only further restrict access. Unlike the global last, if no entry is found on the local list access is granted. An application can add entries to its own list by writing to /smack/load-self. The changes appear large as they involve refactoring the list handling to accomodate there being more than one rule list. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r--security/smack/smack_access.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 7ba8478f599e..86453db4333d 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -70,10 +70,11 @@ int log_policy = SMACK_AUDIT_DENIED;
70 * smk_access_entry - look up matching access rule 70 * smk_access_entry - look up matching access rule
71 * @subject_label: a pointer to the subject's Smack label 71 * @subject_label: a pointer to the subject's Smack label
72 * @object_label: a pointer to the object's Smack label 72 * @object_label: a pointer to the object's Smack label
73 * @rule_list: the list of rules to search
73 * 74 *
74 * This function looks up the subject/object pair in the 75 * This function looks up the subject/object pair in the
75 * access rule list and returns pointer to the matching rule if found, 76 * access rule list and returns the access mode. If no
76 * NULL otherwise. 77 * entry is found returns -ENOENT.
77 * 78 *
78 * NOTE: 79 * NOTE:
79 * Even though Smack labels are usually shared on smack_list 80 * Even though Smack labels are usually shared on smack_list
@@ -85,13 +86,13 @@ int log_policy = SMACK_AUDIT_DENIED;
85 * will be on the list, so checking the pointers may be a worthwhile 86 * will be on the list, so checking the pointers may be a worthwhile
86 * optimization. 87 * optimization.
87 */ 88 */
88int smk_access_entry(char *subject_label, char *object_label) 89int smk_access_entry(char *subject_label, char *object_label,
90 struct list_head *rule_list)
89{ 91{
90 u32 may = MAY_NOT; 92 int may = -ENOENT;
91 struct smack_rule *srp; 93 struct smack_rule *srp;
92 94
93 rcu_read_lock(); 95 list_for_each_entry_rcu(srp, rule_list, list) {
94 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
95 if (srp->smk_subject == subject_label || 96 if (srp->smk_subject == subject_label ||
96 strcmp(srp->smk_subject, subject_label) == 0) { 97 strcmp(srp->smk_subject, subject_label) == 0) {
97 if (srp->smk_object == object_label || 98 if (srp->smk_object == object_label ||
@@ -101,7 +102,6 @@ int smk_access_entry(char *subject_label, char *object_label)
101 } 102 }
102 } 103 }
103 } 104 }
104 rcu_read_unlock();
105 105
106 return may; 106 return may;
107} 107}
@@ -129,7 +129,7 @@ int smk_access_entry(char *subject_label, char *object_label)
129int smk_access(char *subject_label, char *object_label, int request, 129int smk_access(char *subject_label, char *object_label, int request,
130 struct smk_audit_info *a) 130 struct smk_audit_info *a)
131{ 131{
132 u32 may = MAY_NOT; 132 int may = MAY_NOT;
133 int rc = 0; 133 int rc = 0;
134 134
135 /* 135 /*
@@ -181,13 +181,14 @@ int smk_access(char *subject_label, char *object_label, int request,
181 * Beyond here an explicit relationship is required. 181 * Beyond here an explicit relationship is required.
182 * If the requested access is contained in the available 182 * If the requested access is contained in the available
183 * access (e.g. read is included in readwrite) it's 183 * access (e.g. read is included in readwrite) it's
184 * good. 184 * good. A negative response from smk_access_entry()
185 */ 185 * indicates there is no entry for this pair.
186 may = smk_access_entry(subject_label, object_label);
187 /*
188 * This is a bit map operation.
189 */ 186 */
190 if ((request & may) == request) 187 rcu_read_lock();
188 may = smk_access_entry(subject_label, object_label, &smack_rule_list);
189 rcu_read_unlock();
190
191 if (may > 0 && (request & may) == request)
191 goto out_audit; 192 goto out_audit;
192 193
193 rc = -EACCES; 194 rc = -EACCES;
@@ -212,12 +213,27 @@ out_audit:
212 */ 213 */
213int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 214int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
214{ 215{
216 struct task_smack *tsp = current_security();
217 char *sp = smk_of_task(tsp);
218 int may;
215 int rc; 219 int rc;
216 char *sp = smk_of_current();
217 220
221 /*
222 * Check the global rule list
223 */
218 rc = smk_access(sp, obj_label, mode, NULL); 224 rc = smk_access(sp, obj_label, mode, NULL);
219 if (rc == 0) 225 if (rc == 0) {
220 goto out_audit; 226 /*
227 * If there is an entry in the task's rule list
228 * it can further restrict access.
229 */
230 may = smk_access_entry(sp, obj_label, &tsp->smk_rules);
231 if (may < 0)
232 goto out_audit;
233 if ((mode & may) == mode)
234 goto out_audit;
235 rc = -EACCES;
236 }
221 237
222 /* 238 /*
223 * Return if a specific label has been designated as the 239 * Return if a specific label has been designated as the
@@ -228,7 +244,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
228 goto out_audit; 244 goto out_audit;
229 245
230 if (capable(CAP_MAC_OVERRIDE)) 246 if (capable(CAP_MAC_OVERRIDE))
231 return 0; 247 rc = 0;
232 248
233out_audit: 249out_audit:
234#ifdef CONFIG_AUDIT 250#ifdef CONFIG_AUDIT