audit: complex interfield comparison helper
Rather than code the same loop over and over implement a helper function which uses some pointer magic to make it generic enough to be used numerous places as we implement more audit interfield comparisons Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
		
							parent
							
								
									02d86a568c
								
							
						
					
					
						commit
						b34b039324
					
				| @ -463,25 +463,53 @@ static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int audit_compare_id(uid_t uid1, | ||||
| 			    struct audit_names *name, | ||||
| 			    unsigned long name_offset, | ||||
| 			    struct audit_field *f, | ||||
| 			    struct audit_context *ctx) | ||||
| { | ||||
| 	struct audit_names *n; | ||||
| 	unsigned long addr; | ||||
| 	uid_t uid2; | ||||
| 	int rc; | ||||
| 
 | ||||
| 	if (name) { | ||||
| 		addr = (unsigned long)name; | ||||
| 		addr += name_offset; | ||||
| 
 | ||||
| 		uid2 = *(uid_t *)addr; | ||||
| 		rc = audit_comparator(uid1, f->op, uid2); | ||||
| 		if (rc) | ||||
| 			return rc; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ctx) { | ||||
| 		list_for_each_entry(n, &ctx->names_list, list) { | ||||
| 			addr = (unsigned long)n; | ||||
| 			addr += name_offset; | ||||
| 
 | ||||
| 			uid2 = *(uid_t *)addr; | ||||
| 
 | ||||
| 			rc = audit_comparator(uid1, f->op, uid2); | ||||
| 			if (rc) | ||||
| 				return rc; | ||||
| 		} | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int audit_field_compare(struct task_struct *tsk, | ||||
| 			       const struct cred *cred, | ||||
| 			       struct audit_field *f, | ||||
| 			       struct audit_context *ctx, | ||||
| 			       struct audit_names *name) | ||||
| { | ||||
| 	struct audit_names *n; | ||||
| 
 | ||||
| 	switch (f->val) { | ||||
| 	case AUDIT_COMPARE_UID_TO_OBJ_UID: | ||||
| 		if (name) { | ||||
| 			return audit_comparator(cred->uid, f->op, name->uid); | ||||
| 		} else if (ctx) { | ||||
| 			list_for_each_entry(n, &ctx->names_list, list) { | ||||
| 				if (audit_comparator(cred->uid, f->op, n->uid)) | ||||
| 					return 1; | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
| 		return audit_compare_id(cred->uid, | ||||
| 					name, offsetof(struct audit_names, uid), | ||||
| 					f, ctx); | ||||
| 	default: | ||||
| 		WARN(1, "Missing AUDIT_COMPARE define.  Report as a bug\n"); | ||||
| 		return 0; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user