diff options
Diffstat (limited to 'security/smack/smack_access.c')
| -rw-r--r-- | security/smack/smack_access.c | 52 | 
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;   * smk_access_entry - look up matching access rule   * @subject_label: a pointer to the subject's Smack label   * @object_label: a pointer to the object's Smack label + * @rule_list: the list of rules to search   *   * This function looks up the subject/object pair in the - * access rule list and returns pointer to the matching rule if found, - * NULL otherwise. + * access rule list and returns the access mode. If no + * entry is found returns -ENOENT.   *   * NOTE:   * Even though Smack labels are usually shared on smack_list @@ -85,13 +86,13 @@ int log_policy = SMACK_AUDIT_DENIED;   * will be on the list, so checking the pointers may be a worthwhile   * optimization.   */ -int smk_access_entry(char *subject_label, char *object_label) +int smk_access_entry(char *subject_label, char *object_label, +			struct list_head *rule_list)  { -	u32 may = MAY_NOT; +	int may = -ENOENT;  	struct smack_rule *srp; -	rcu_read_lock(); -	list_for_each_entry_rcu(srp, &smack_rule_list, list) { +	list_for_each_entry_rcu(srp, rule_list, list) {  		if (srp->smk_subject == subject_label ||  		    strcmp(srp->smk_subject, subject_label) == 0) {  			if (srp->smk_object == object_label || @@ -101,7 +102,6 @@ int smk_access_entry(char *subject_label, char *object_label)  			}  		}  	} -	rcu_read_unlock();  	return may;  } @@ -129,7 +129,7 @@ int smk_access_entry(char *subject_label, char *object_label)  int smk_access(char *subject_label, char *object_label, int request,  	       struct smk_audit_info *a)  { -	u32 may = MAY_NOT; +	int may = MAY_NOT;  	int rc = 0;  	/* @@ -181,13 +181,14 @@ int smk_access(char *subject_label, char *object_label, int request,  	 * Beyond here an explicit relationship is required.  	 * If the requested access is contained in the available  	 * access (e.g. read is included in readwrite) it's -	 * good. -	 */ -	may = smk_access_entry(subject_label, object_label); -	/* -	 * This is a bit map operation. +	 * good. A negative response from smk_access_entry() +	 * indicates there is no entry for this pair.  	 */ -	if ((request & may) == request) +	rcu_read_lock(); +	may = smk_access_entry(subject_label, object_label, &smack_rule_list); +	rcu_read_unlock(); + +	if (may > 0 && (request & may) == request)  		goto out_audit;  	rc = -EACCES; @@ -212,12 +213,27 @@ out_audit:   */  int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)  { +	struct task_smack *tsp = current_security(); +	char *sp = smk_of_task(tsp); +	int may;  	int rc; -	char *sp = smk_of_current(); +	/* +	 * Check the global rule list +	 */  	rc = smk_access(sp, obj_label, mode, NULL); -	if (rc == 0) -		goto out_audit; +	if (rc == 0) { +		/* +		 * If there is an entry in the task's rule list +		 * it can further restrict access. +		 */ +		may = smk_access_entry(sp, obj_label, &tsp->smk_rules); +		if (may < 0) +			goto out_audit; +		if ((mode & may) == mode) +			goto out_audit; +		rc = -EACCES; +	}  	/*  	 * 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)  		goto out_audit;  	if (capable(CAP_MAC_OVERRIDE)) -		return 0; +		rc = 0;  out_audit:  #ifdef CONFIG_AUDIT  | 
