| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * AppArmor security module | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file contains AppArmor auditing functions | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 1998-2008 Novell/SUSE | 
					
						
							|  |  |  |  * Copyright 2009-2010 Canonical Ltd. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation, version 2 of the | 
					
						
							|  |  |  |  * License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/audit.h>
 | 
					
						
							|  |  |  | #include <linux/socket.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "include/apparmor.h"
 | 
					
						
							|  |  |  | #include "include/audit.h"
 | 
					
						
							|  |  |  | #include "include/policy.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 13:30:36 +01:00
										 |  |  | const char *const op_table[] = { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	"null", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"sysctl", | 
					
						
							|  |  |  | 	"capable", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"unlink", | 
					
						
							|  |  |  | 	"mkdir", | 
					
						
							|  |  |  | 	"rmdir", | 
					
						
							|  |  |  | 	"mknod", | 
					
						
							|  |  |  | 	"truncate", | 
					
						
							|  |  |  | 	"link", | 
					
						
							|  |  |  | 	"symlink", | 
					
						
							|  |  |  | 	"rename_src", | 
					
						
							|  |  |  | 	"rename_dest", | 
					
						
							|  |  |  | 	"chmod", | 
					
						
							|  |  |  | 	"chown", | 
					
						
							|  |  |  | 	"getattr", | 
					
						
							|  |  |  | 	"open", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"file_perm", | 
					
						
							|  |  |  | 	"file_lock", | 
					
						
							|  |  |  | 	"file_mmap", | 
					
						
							|  |  |  | 	"file_mprotect", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"create", | 
					
						
							|  |  |  | 	"post_create", | 
					
						
							|  |  |  | 	"bind", | 
					
						
							|  |  |  | 	"connect", | 
					
						
							|  |  |  | 	"listen", | 
					
						
							|  |  |  | 	"accept", | 
					
						
							|  |  |  | 	"sendmsg", | 
					
						
							|  |  |  | 	"recvmsg", | 
					
						
							|  |  |  | 	"getsockname", | 
					
						
							|  |  |  | 	"getpeername", | 
					
						
							|  |  |  | 	"getsockopt", | 
					
						
							|  |  |  | 	"setsockopt", | 
					
						
							|  |  |  | 	"socket_shutdown", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"ptrace", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"exec", | 
					
						
							|  |  |  | 	"change_hat", | 
					
						
							|  |  |  | 	"change_profile", | 
					
						
							|  |  |  | 	"change_onexec", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"setprocattr", | 
					
						
							|  |  |  | 	"setrlimit", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"profile_replace", | 
					
						
							|  |  |  | 	"profile_load", | 
					
						
							|  |  |  | 	"profile_remove" | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 13:30:36 +01:00
										 |  |  | const char *const audit_mode_names[] = { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	"normal", | 
					
						
							|  |  |  | 	"quiet_denied", | 
					
						
							|  |  |  | 	"quiet", | 
					
						
							|  |  |  | 	"noquiet", | 
					
						
							|  |  |  | 	"all" | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-14 13:30:36 +01:00
										 |  |  | static const char *const aa_audit_type[] = { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	"AUDIT", | 
					
						
							|  |  |  | 	"ALLOWED", | 
					
						
							|  |  |  | 	"DENIED", | 
					
						
							|  |  |  | 	"HINT", | 
					
						
							|  |  |  | 	"STATUS", | 
					
						
							|  |  |  | 	"ERROR", | 
					
						
							| 
									
										
										
										
											2013-02-18 16:13:34 -08:00
										 |  |  | 	"KILLED", | 
					
						
							| 
									
										
										
										
											2012-02-22 00:20:26 -08:00
										 |  |  | 	"AUTO" | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Currently AppArmor auditing is fed straight into the audit framework. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * TODO: | 
					
						
							|  |  |  |  * netlink interface for complain mode | 
					
						
							|  |  |  |  * user auditing, - send user auditing to netlink interface | 
					
						
							|  |  |  |  * system control of whether user audit messages go to system log | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * audit_base - core AppArmor function. | 
					
						
							|  |  |  |  * @ab: audit buffer to fill (NOT NULL) | 
					
						
							|  |  |  |  * @ca: audit structure containing data to audit (NOT NULL) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Record common AppArmor audit data from @sa | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void audit_pre(struct audit_buffer *ab, void *ca) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct common_audit_data *sa = ca; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (aa_g_audit_header) { | 
					
						
							|  |  |  | 		audit_log_format(ab, "apparmor="); | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		audit_log_string(ab, aa_audit_type[sa->aad->type]); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	if (sa->aad->op) { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 		audit_log_format(ab, " operation="); | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		audit_log_string(ab, op_table[sa->aad->op]); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	if (sa->aad->info) { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 		audit_log_format(ab, " info="); | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		audit_log_string(ab, sa->aad->info); | 
					
						
							|  |  |  | 		if (sa->aad->error) | 
					
						
							|  |  |  | 			audit_log_format(ab, " error=%d", sa->aad->error); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	if (sa->aad->profile) { | 
					
						
							|  |  |  | 		struct aa_profile *profile = sa->aad->profile; | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 		if (profile->ns != root_ns) { | 
					
						
							|  |  |  | 			audit_log_format(ab, " namespace="); | 
					
						
							|  |  |  | 			audit_log_untrustedstring(ab, profile->ns->base.hname); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		audit_log_format(ab, " profile="); | 
					
						
							|  |  |  | 		audit_log_untrustedstring(ab, profile->base.hname); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	if (sa->aad->name) { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 		audit_log_format(ab, " name="); | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		audit_log_untrustedstring(ab, sa->aad->name); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * aa_audit_msg - Log a message to the audit subsystem | 
					
						
							|  |  |  |  * @sa: audit event structure (NOT NULL) | 
					
						
							|  |  |  |  * @cb: optional callback fn for type specific fields (MAYBE NULL) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void aa_audit_msg(int type, struct common_audit_data *sa, | 
					
						
							|  |  |  | 		  void (*cb) (struct audit_buffer *, void *)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	sa->aad->type = type; | 
					
						
							| 
									
										
										
										
											2012-04-02 15:48:12 -07:00
										 |  |  | 	common_lsm_audit(sa, audit_pre, cb); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * aa_audit - Log a profile based audit event to the audit subsystem | 
					
						
							|  |  |  |  * @type: audit type for the message | 
					
						
							|  |  |  |  * @profile: profile to check against (NOT NULL) | 
					
						
							|  |  |  |  * @gfp: allocation flags to use | 
					
						
							|  |  |  |  * @sa: audit event (NOT NULL) | 
					
						
							|  |  |  |  * @cb: optional callback fn for type specific fields (MAYBE NULL) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Handle default message switching based off of audit mode flags | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: error on failure | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, | 
					
						
							|  |  |  | 	     struct common_audit_data *sa, | 
					
						
							|  |  |  | 	     void (*cb) (struct audit_buffer *, void *)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BUG_ON(!profile); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (type == AUDIT_APPARMOR_AUTO) { | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		if (likely(!sa->aad->error)) { | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 			if (AUDIT_MODE(profile) != AUDIT_ALL) | 
					
						
							|  |  |  | 				return 0; | 
					
						
							|  |  |  | 			type = AUDIT_APPARMOR_AUDIT; | 
					
						
							|  |  |  | 		} else if (COMPLAIN_MODE(profile)) | 
					
						
							|  |  |  | 			type = AUDIT_APPARMOR_ALLOWED; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			type = AUDIT_APPARMOR_DENIED; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (AUDIT_MODE(profile) == AUDIT_QUIET || | 
					
						
							|  |  |  | 	    (type == AUDIT_APPARMOR_DENIED && | 
					
						
							|  |  |  | 	     AUDIT_MODE(profile) == AUDIT_QUIET)) | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		return sa->aad->error; | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) | 
					
						
							|  |  |  | 		type = AUDIT_APPARMOR_KILL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!unconfined(profile)) | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 		sa->aad->profile = profile; | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	aa_audit_msg(type, sa, cb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	if (sa->aad->type == AUDIT_APPARMOR_KILL) | 
					
						
							| 
									
										
										
										
											2012-04-04 15:01:42 -04:00
										 |  |  | 		(void)send_sig_info(SIGKILL, NULL, | 
					
						
							| 
									
										
										
										
											2013-10-08 05:37:26 -07:00
										 |  |  | 				    sa->u.tsk ?  sa->u.tsk : current); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) | 
					
						
							|  |  |  | 		return complain_error(sa->aad->error); | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 09:37:02 -07:00
										 |  |  | 	return sa->aad->error; | 
					
						
							| 
									
										
										
										
											2010-07-29 14:47:58 -07:00
										 |  |  | } |