Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756904AbZKJQNS (ORCPT ); Tue, 10 Nov 2009 11:13:18 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756885AbZKJQNQ (ORCPT ); Tue, 10 Nov 2009 11:13:16 -0500 Received: from adelie.canonical.com ([91.189.90.139]:59804 "EHLO adelie.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756870AbZKJQNM (ORCPT ); Tue, 10 Nov 2009 11:13:12 -0500 From: John Johansen To: linux-kernel@vger.kernel.org Cc: linux-security-module@vger.kernel.org, John Johansen Subject: [PATCH 02/12] AppArmor: basic auditing infrastructure. Date: Tue, 10 Nov 2009 08:12:55 -0800 Message-Id: <1257869585-7092-3-git-send-email-john.johansen@canonical.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1257869585-7092-1-git-send-email-john.johansen@canonical.com> References: <1257869585-7092-1-git-send-email-john.johansen@canonical.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8433 Lines: 282 Update kenel audit range comments to show AppArmor's registered range of 1500-1599. This range used to be reserved for LSPP but LSPP uses the SELinux range and the range was given to AppArmor. Patch is not in mainline -- pending AppArmor code submission to lkml Add the core routine for AppArmor auditing. Signed-off-by: John Johansen --- include/linux/audit.h | 10 ++- security/apparmor/audit.c | 161 +++++++++++++++++++++++++++++++++++++ security/apparmor/include/audit.h | 57 +++++++++++++ 3 files changed, 227 insertions(+), 1 deletions(-) create mode 100644 security/apparmor/audit.c create mode 100644 security/apparmor/include/audit.h diff --git a/include/linux/audit.h b/include/linux/audit.h index 3c7a358..a1db25b 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -33,7 +33,7 @@ * 1200 - 1299 messages internal to the audit daemon * 1300 - 1399 audit event messages * 1400 - 1499 SE Linux use - * 1500 - 1599 kernel LSPP events + * 1500 - 1599 AppArmor use * 1600 - 1699 kernel crypto events * 1700 - 1799 kernel anomaly records * 1800 - 1899 kernel integrity events @@ -122,6 +122,14 @@ #define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */ #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */ +#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */ +#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */ +#define AUDIT_APPARMOR_DENIED 1503 +#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */ +#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */ +#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */ +#define AUDIT_APPARMOR_KILL 1507 /* AppArmor killing processes */ + #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c new file mode 100644 index 0000000..54f4dc3 --- /dev/null +++ b/security/apparmor/audit.c @@ -0,0 +1,161 @@ +/* + * AppArmor security module + * + * This file contains AppArmor auditing functions + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009 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 +#include + +#include "include/apparmor.h" +#include "include/audit.h" +#include "include/policy.h" + +const char *audit_mode_names[] = { + "normal", + "quiet_denied", + "quiet", + "noquiet", + "all" +}; + +static char *aa_audit_type[] = { + "APPARMOR_AUDIT", + "APPARMOR_ALLOWED", + "APPARMOR_DENIED", + "APPARMOR_HINT", + "APPARMOR_STATUS", + "APPARMOR_ERROR", + "APPARMOR_KILLED" +}; + +/* + * 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 + */ + +static int aa_audit_base(int type, struct aa_profile *profile, + struct aa_audit *sa, struct audit_context *audit_cxt, + void (*cb) (struct audit_buffer *, void *)) +{ + struct audit_buffer *ab = NULL; + struct task_struct *task = sa->task ? sa->task : current; + + if (profile && PROFILE_KILL(profile) && type == AUDIT_APPARMOR_DENIED) + type = AUDIT_APPARMOR_KILL; + + /* ab freed below in audit_log_end */ + ab = audit_log_start(audit_cxt, sa->gfp_mask, type); + + if (!ab) { + AA_ERROR("(%d) Unable to log event of type (%d)\n", + -ENOMEM, type); + sa->error = -ENOMEM; + goto out; + } + + if (aa_g_audit_header) + audit_log_format(ab, "type=%s ", + aa_audit_type[type - AUDIT_APPARMOR_AUDIT]); + + if (sa->operation) + audit_log_format(ab, "operation=\"%s\"", sa->operation); + + if (sa->info) { + audit_log_format(ab, " info=\"%s\"", sa->info); + if (sa->error) + audit_log_format(ab, " error=%d", sa->error); + } + + audit_log_format(ab, " pid=%d", task->pid); + + if (profile) { + pid_t pid = task->real_parent->pid; + audit_log_format(ab, " parent=%d", pid); + audit_log_format(ab, " profile="); + audit_log_untrustedstring(ab, profile->fqname); + + if (profile->ns != default_namespace) { + audit_log_format(ab, " namespace="); + audit_log_untrustedstring(ab, profile->ns->base.name); + } + } + + if (cb) + cb(ab, sa); + + audit_log_end(ab); + +out: + if (type == AUDIT_APPARMOR_KILL) + (void)send_sig_info(SIGKILL, NULL, task); + + return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error; +} + +/** + * aa_audit - Log an audit event to the audit subsystem + * @type: audit type for the message + * @profile: profile to check against + * @sa: audit event + * @cb: optional callback fn for type specific fields + * + * Handle default message switching based off of audit mode flags + */ +int aa_audit(int type, struct aa_profile *profile, struct aa_audit *sa, + void (*cb) (struct audit_buffer *, void *)) +{ + struct audit_context *audit_cxt; + audit_cxt = aa_g_logsyscall ? current->audit_context : NULL; + + if (type == AUDIT_APPARMOR_AUTO) { + if (likely(!sa->error)) { + if (PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) + return 0; + type = AUDIT_APPARMOR_AUDIT; + } else if (PROFILE_COMPLAIN(profile)) + type = AUDIT_APPARMOR_ALLOWED; + else + type = AUDIT_APPARMOR_DENIED; + } + if (PROFILE_AUDIT_MODE(profile) == AUDIT_QUIET || + (type == AUDIT_APPARMOR_DENIED && + PROFILE_AUDIT_MODE(profile) == AUDIT_QUIET)) + return sa->error; + + return aa_audit_base(type, profile, sa, audit_cxt, cb); +} + +/** + * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem + * @profile: profile to check against + * @gfp: memory allocation flags + * @msg: string describing syscall being rejected + * @cb: optional callback fn for type specific fields + */ +int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, + const char *msg, + void (*cb) (struct audit_buffer *, void *)) +{ + struct aa_audit sa = { + .operation = "syscall", + .info = msg, + .gfp_mask = gfp, + .error = -EACCES, + }; + + return aa_audit_base(AUDIT_APPARMOR_DENIED, profile, &sa, + current->audit_context, NULL); +} diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h new file mode 100644 index 0000000..618527f --- /dev/null +++ b/security/apparmor/include/audit.h @@ -0,0 +1,57 @@ +/* + * AppArmor security module + * + * This file contains AppArmor auditing function definitions. + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009 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. + */ + +#ifndef __AA_AUDIT_H +#define __AA_AUDIT_H + +#include +#include +#include +#include + +struct aa_profile; + +extern const char *audit_mode_names[]; +#define AUDIT_MAX_INDEX 5 + +#define AUDIT_APPARMOR_AUTO 0 /* auto choose audit message type */ + +enum audit_mode { + AUDIT_NORMAL, /* follow normal auditing of accesses */ + AUDIT_QUIET_DENIED, /* quiet all denied access messages */ + AUDIT_QUIET, /* quiet all messages */ + AUDIT_NOQUIET, /* do not quiet audit messages */ + AUDIT_ALL /* audit all accesses */ +}; + +/* + * aa_audit - AppArmor auditing structure + * Structure is populated by access control code and passed to aa_audit which + * provides for a single point of logging. + */ +struct aa_audit { + struct task_struct *task; + gfp_t gfp_mask; + int error; + const char *operation; + const char *info; +}; + +int aa_audit(int type, struct aa_profile *profile, struct aa_audit *sa, + void (*cb) (struct audit_buffer *, void *)); + +int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, const char *, + void (*cb) (struct audit_buffer *, void *)); + +#endif /* __AA_AUDIT_H */ -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/