Using audit for service monitoring...
by Randy Zagar
If I wanted to use the audit subsystem to log something like stale NFS
handles, would this work?
# ESTALE == -13
auditctl -a exit,always -S all -F exit=-13
More importantly, is this an appropriate use of the audit subsystem, or
should I be doing this some other way?
If this is the right way to do it, how can I easily determine which
syscalls can return ESTALE? Using '-S all' seems wasteful...
Suggestions always welcome,
-RZ
--
Randy Zagar Sr. Unix Systems Administrator
E-mail: zagar(a)arlut.utexas.edu Applied Research Laboratories
Phone: 512 835-3131 Univ. of Texas at Austin
18 years, 2 months
watching files in selinuxfs
by Debora Velarde
When in enforcing mode, I am only able to audit files in selinuxfs by
inode, not by path. I am running as auditadm_r.
/* Try adding audit rule with -F path */
# auditctl -a exit,always -S open -F path=/selinux/enforce
Error sending add rule request (Permission denied)
# auditctl -l
No rules
/* Try adding audit rule with -w path syntax */
# auditctl -w /selinux/enforce
Error sending add rule request (Permission denied)
/* Try adding audit rule with -F inode */
# ls -i /selinux/enforce
4 /selinux/enforce
# auditctl -a exit,always -S open -F inode=4
# auditctl -l
LIST_RULES: exit,always inode=4 (0x4) syscall=open
Since it is possible to audit the files, this might only require a
documentation change. Perhaps adding a comment to the auditctl man page
would be sufficient?
-debbie
18 years, 2 months
[PATCH] newrole auditing of failures due to user actions
by Michael C Thompson
This patch introduces two new point in the code where audit records are
generated for newrole. Both points are when the attempt to newrole fails.
The first point is when the default type could not be determine for the
specified role - this is audited because, as sgrubb pointed out, it is
currently non-tracked path to probe the policy.
The second point is when the desired context to change to is invalid.
There record format remains unchanged. Failing to validate the desired
context will result in the old and new contexts being recorded intact to
the log. For the default type, the old and new contexts have not yet
been obtained, so they are recorded in the log as XXX_context=?
Signed-off-by: Michael Thompson <thompsmc(a)us.ibm.com>
----
18 years, 2 months
Audit Subsystem Documentation
by Azrael
Where can I find documentation regarding the underlying audit subsystem within the Linux kernel?
Specifically, the protocol docs for NETLINK_AUDIT, so that I may query the subsystem from any sort
of language that supports NETLINK socket communication.
Does such documentation even exist? If not, could somebody provide me with samples or a basic
idea/flow of how it all works? I'd be willing to write it all down for public viewing if it
hasn't yet been done and if someone can get me started.
Thanks,
Azrael
18 years, 2 months
[RFC 1/1] NetLabel: add audit support for configuration changes
by paul.moore@hp.com
This patch is a first attempt at adding auditing support to NetLabel, based on
a conversation with Steve Grubb on irc last Friday (9/22). I wanted to send
this out to the audit mailing list first to get some feedback on such things
as message types and message formats. Once I have collected your feedback I
plan on posting the next version of the patch to both the netdev and audit
mailing lists for inclusion in 2.6.19.
So please, if you have comments/concerns/etc. please share them now so this
does not get help up later - thank you.
---
include/linux/audit.h | 6 ++
net/netlabel/netlabel_cipso_v4.c | 37 +++++++++---
net/netlabel/netlabel_domainhash.c | 36 +++++++++++-
net/netlabel/netlabel_unlabeled.c | 28 +++++++--
net/netlabel/netlabel_user.c | 110 +++++++++++++++++++++++++++++++++++++
net/netlabel/netlabel_user.h | 6 ++
6 files changed, 208 insertions(+), 15 deletions(-)
Index: net-2.6/include/linux/audit.h
===================================================================
--- net-2.6.orig/include/linux/audit.h
+++ net-2.6/include/linux/audit.h
@@ -95,6 +95,12 @@
#define AUDIT_MAC_POLICY_LOAD 1403 /* Policy file load */
#define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */
#define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */
+#define AUDIT_MAC_UNLBL_ACCEPT 1406 /* NetLabel: allow unlabeled traffic */
+#define AUDIT_MAC_UNLBL_DENY 1407 /* NetLabel: deny unlabeled traffic */
+#define AUDIT_MAC_CIPSOV4_ADD 1408 /* NetLabel: add CIPSOv4 DOI entry */
+#define AUDIT_MAC_CIPSOV4_DEL 1409 /* NetLabel: del CIPSOv4 DOI entry */
+#define AUDIT_MAC_MAP_ADD 1410 /* NetLabel: add LSM domain mapping */
+#define AUDIT_MAC_MAP_DEL 1411 /* NetLabel: del LSM domain mapping */
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
Index: net-2.6/net/netlabel/netlabel_cipso_v4.c
===================================================================
--- net-2.6.orig/net/netlabel/netlabel_cipso_v4.c
+++ net-2.6/net/netlabel/netlabel_cipso_v4.c
@@ -32,6 +32,7 @@
#include <linux/socket.h>
#include <linux/string.h>
#include <linux/skbuff.h>
+#include <linux/audit.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -162,8 +163,7 @@ static int netlbl_cipsov4_add_std(struct
int nla_a_rem;
int nla_b_rem;
- if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
- !info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
+ if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
!info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
return -EINVAL;
@@ -344,8 +344,7 @@ static int netlbl_cipsov4_add_pass(struc
int ret_val;
struct cipso_v4_doi *doi_def = NULL;
- if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
- !info->attrs[NLBL_CIPSOV4_A_TAGLST])
+ if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
return -EINVAL;
doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
@@ -381,21 +380,34 @@ static int netlbl_cipsov4_add(struct sk_
{
int ret_val = -EINVAL;
- u32 map_type;
+ u32 type;
+ u32 doi;
+ const char *type_str = "(unknown)";
+ struct audit_buffer *audit_buf;
- if (!info->attrs[NLBL_CIPSOV4_A_MTYPE])
+ if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
+ !info->attrs[NLBL_CIPSOV4_A_MTYPE])
return -EINVAL;
- map_type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
- switch (map_type) {
+ type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
+ switch (type) {
case CIPSO_V4_MAP_STD:
+ type_str = "std";
ret_val = netlbl_cipsov4_add_std(info);
break;
case CIPSO_V4_MAP_PASS:
+ type_str = "pass";
ret_val = netlbl_cipsov4_add_pass(info);
break;
}
+ if (ret_val == 0) {
+ doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD);
+ audit_log_format(audit_buf, " doi=%u type=%s", doi, type_str);
+ audit_log_end(audit_buf);
+ }
+
return ret_val;
}
@@ -653,13 +665,20 @@ static int netlbl_cipsov4_listall(struct
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
{
int ret_val = -EINVAL;
- u32 doi;
+ u32 doi = 0;
+ struct audit_buffer *audit_buf;
if (info->attrs[NLBL_CIPSOV4_A_DOI]) {
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
ret_val = cipso_v4_doi_remove(doi, netlbl_cipsov4_doi_free);
}
+ if (ret_val == 0) {
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL);
+ audit_log_format(audit_buf, " doi=%u", doi);
+ audit_log_end(audit_buf);
+ }
+
return ret_val;
}
Index: net-2.6/net/netlabel/netlabel_domainhash.c
===================================================================
--- net-2.6.orig/net/netlabel/netlabel_domainhash.c
+++ net-2.6/net/netlabel/netlabel_domainhash.c
@@ -35,12 +35,14 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
+#include <linux/audit.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <asm/bug.h>
#include "netlabel_mgmt.h"
#include "netlabel_domainhash.h"
+#include "netlabel_user.h"
struct netlbl_domhsh_tbl {
struct list_head *tbl;
@@ -197,6 +199,8 @@ int netlbl_domhsh_add(struct netlbl_dom_
{
int ret_val;
u32 bkt;
+ struct audit_buffer *audit_buf;
+ char *audit_domain;
switch (entry->type) {
case NETLBL_NLTYPE_UNLABELED:
@@ -236,6 +240,25 @@ int netlbl_domhsh_add(struct netlbl_dom_
spin_unlock(&netlbl_domhsh_def_lock);
} else
ret_val = -EINVAL;
+ if (ret_val == 0) {
+ if (entry->domain != NULL)
+ audit_domain = entry->domain;
+ else
+ audit_domain = "(default)";
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD);
+ audit_log_format(audit_buf, " domain=%s", audit_domain);
+ switch (entry->type) {
+ case NETLBL_NLTYPE_UNLABELED:
+ audit_log_format(audit_buf, " protocol=unlbl");
+ break;
+ case NETLBL_NLTYPE_CIPSOV4:
+ audit_log_format(audit_buf,
+ " protocol=cipsov4 doi=%u",
+ entry->type_def.cipsov4->doi);
+ break;
+ }
+ audit_log_end(audit_buf);
+ }
rcu_read_unlock();
if (ret_val != 0) {
@@ -280,6 +303,8 @@ int netlbl_domhsh_remove(const char *dom
{
int ret_val = -ENOENT;
struct netlbl_dom_map *entry;
+ struct audit_buffer *audit_buf;
+ char *audit_domain;
rcu_read_lock();
if (domain != NULL)
@@ -316,8 +341,17 @@ int netlbl_domhsh_remove(const char *dom
ret_val = -ENOENT;
spin_unlock(&netlbl_domhsh_def_lock);
}
- if (ret_val == 0)
+ if (ret_val == 0) {
+ if (entry->domain != NULL)
+ audit_domain = entry->domain;
+ else
+ audit_domain = "(default)";
+ audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL);
+ audit_log_format(audit_buf, " domain=%s", audit_domain);
+ audit_log_end(audit_buf);
+
call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
+ }
remove_return:
rcu_read_unlock();
Index: net-2.6/net/netlabel/netlabel_unlabeled.c
===================================================================
--- net-2.6.orig/net/netlabel/netlabel_unlabeled.c
+++ net-2.6/net/netlabel/netlabel_unlabeled.c
@@ -64,6 +64,25 @@ static struct nla_policy netlbl_unlabel_
};
/*
+ * Helper Functions
+ */
+
+/**
+ * netlbl_unlabel_acceptflg_set - Set the unlabeled accept flag
+ * @value: desired value
+ *
+ * Description:
+ * Set the value of the unlabeled accept flag to @value.
+ *
+ */
+static void netlbl_unlabel_acceptflg_set(u8 value)
+{
+ atomic_set(&netlabel_unlabel_accept_flg, value);
+ netlbl_audit_nomsg((value ?
+ AUDIT_MAC_UNLBL_ACCEPT : AUDIT_MAC_UNLBL_DENY));
+}
+
+/*
* NetLabel Command Handlers
*/
@@ -79,18 +98,17 @@ static struct nla_policy netlbl_unlabel_
*/
static int netlbl_unlabel_accept(struct sk_buff *skb, struct genl_info *info)
{
- int ret_val = -EINVAL;
u8 value;
if (info->attrs[NLBL_UNLABEL_A_ACPTFLG]) {
value = nla_get_u8(info->attrs[NLBL_UNLABEL_A_ACPTFLG]);
if (value == 1 || value == 0) {
- atomic_set(&netlabel_unlabel_accept_flg, value);
- ret_val = 0;
+ netlbl_unlabel_acceptflg_set(value);
+ return 0;
}
}
- return ret_val;
+ return -EINVAL;
}
/**
@@ -238,7 +256,7 @@ int netlbl_unlabel_defconf(void)
if (ret_val != 0)
return ret_val;
- atomic_set(&netlabel_unlabel_accept_flg, 1);
+ netlbl_unlabel_acceptflg_set(1);
return 0;
}
Index: net-2.6/net/netlabel/netlabel_user.c
===================================================================
--- net-2.6.orig/net/netlabel/netlabel_user.c
+++ net-2.6/net/netlabel/netlabel_user.c
@@ -32,6 +32,8 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/socket.h>
+#include <linux/audit.h>
+#include <linux/tty.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -74,3 +76,111 @@ int netlbl_netlink_init(void)
return 0;
}
+
+/*
+ * NetLabel Audit Functions
+ */
+
+/**
+ * netlbl_audit_start_common - Start an audit message
+ * @type: audit message type
+ *
+ * Description:
+ * Start an audit message using the type specified in @type and fill the audit
+ * message with some fields common to all NetLabel audit messages. Returns
+ * a pointer to the audit buffer on success, NULL on failure.
+ *
+ */
+struct audit_buffer *netlbl_audit_start_common(int type)
+{
+ struct audit_context *audit_ctx = current->audit_context;
+ struct audit_buffer *audit_buf;
+ uid_t audit_loginuid;
+ const char *audit_tty;
+ char audit_comm[sizeof(current->comm)];
+ struct vm_area_struct *vma;
+
+ audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type);
+ if (audit_buf == NULL)
+ return NULL;
+
+ switch (type) {
+ case AUDIT_MAC_UNLBL_ACCEPT:
+ audit_log_format(audit_buf,
+ "netlabel: module=unlbl action=accept");
+ break;
+ case AUDIT_MAC_UNLBL_DENY:
+ audit_log_format(audit_buf,
+ "netlabel: module=unlbl action=deny");
+ break;
+ case AUDIT_MAC_CIPSOV4_ADD:
+ audit_log_format(audit_buf,
+ "netlabel: module=cipsov4 action=add");
+ break;
+ case AUDIT_MAC_CIPSOV4_DEL:
+ audit_log_format(audit_buf,
+ "netlabel: module=cipsov4 action=del");
+ break;
+ case AUDIT_MAC_MAP_ADD:
+ audit_log_format(audit_buf,
+ "netlabel: module=map action=add");
+ break;
+ case AUDIT_MAC_MAP_DEL:
+ audit_log_format(audit_buf,
+ "netlabel: module=map action=del");
+ break;
+ }
+
+ audit_loginuid = audit_get_loginuid(audit_ctx);
+ if (current->signal &&
+ current->signal->tty &&
+ current->signal->tty->name)
+ audit_tty = current->signal->tty->name;
+ else
+ audit_tty = "(none)";
+ get_task_comm(audit_comm, current);
+
+ audit_log_format(audit_buf,
+ " auid=%u uid=%u euid=%u tty=%s pid=%d",
+ audit_loginuid,
+ current->uid,
+ current->euid,
+ audit_tty,
+ current->pid);
+ audit_log_format(audit_buf, " comm=");
+ audit_log_untrustedstring(audit_buf, audit_comm);
+ if (current->mm) {
+ down_read(¤t->mm->mmap_sem);
+ vma = current->mm->mmap;
+ while (vma) {
+ if ((vma->vm_flags & VM_EXECUTABLE) &&
+ vma->vm_file) {
+ audit_log_d_path(audit_buf,
+ " exe=",
+ vma->vm_file->f_dentry,
+ vma->vm_file->f_vfsmnt);
+ break;
+ }
+ vma = vma->vm_next;
+ }
+ up_read(¤t->mm->mmap_sem);
+ }
+
+ return audit_buf;
+}
+
+/**
+ * netlbl_audit_nomsg - Send an audit message without additional text
+ * @type: audit message type
+ *
+ * Description:
+ * Send an audit message with only the common NetLabel audit fields.
+ *
+ */
+void netlbl_audit_nomsg(int type)
+{
+ struct audit_buffer *audit_buf;
+
+ audit_buf = netlbl_audit_start_common(type);
+ audit_log_end(audit_buf);
+}
Index: net-2.6/net/netlabel/netlabel_user.h
===================================================================
--- net-2.6.orig/net/netlabel/netlabel_user.h
+++ net-2.6/net/netlabel/netlabel_user.h
@@ -34,6 +34,7 @@
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/capability.h>
+#include <linux/audit.h>
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/netlabel.h>
@@ -75,4 +76,9 @@ static inline void *netlbl_netlink_hdr_p
int netlbl_netlink_init(void);
+/* NetLabel Audit Functions */
+
+struct audit_buffer *netlbl_audit_start_common(int type);
+void netlbl_audit_nomsg(int type);
+
#endif
--
paul moore
linux security @ hp
18 years, 2 months
[PATCH] name_count array overrun
by Steve Grubb
Hello,
The below patch closes an unbounded use of name_count. This can lead to oopses
in some new file systems.
Signed-off-by: Steve Grubb <sgrubb(a)redhat.com>
diff -urp linux-2.6.17.x86_64.orig/kernel/auditsc.c linux-2.6.17.x86_64/kernel/auditsc.c
--- linux-2.6.17.x86_64.orig/kernel/auditsc.c 2006-08-29 11:21:20.000000000 -0400
+++ linux-2.6.17.x86_64/kernel/auditsc.c 2006-08-29 15:15:28.000000000 -0400
@@ -1281,7 +1281,15 @@ void __audit_inode(const char *name, con
* associated name? */
if (context->name_count >= AUDIT_NAMES - AUDIT_NAMES_RESERVED)
return;
- idx = context->name_count++;
+ idx = context->name_count;
+ if (context->name_count == (AUDIT_NAMES - 1)) {
+ printk(KERN_DEBUG
+ "name_count maxed and losing entry [%d]=%s\n",
+ context->name_count,
+ context->names[context->name_count].name ?:
+ "(null)");
+ } else
+ context->name_count++;
context->names[idx].name = NULL;
#if AUDIT_DEBUG
++context->ino_count;
@@ -1333,7 +1341,13 @@ void __audit_inode_child(const char *dna
}
update_context:
- idx = context->name_count++;
+ idx = context->name_count;
+ if (context->name_count == (AUDIT_NAMES - 1)) {
+ printk(KERN_DEBUG "name_count maxed and losing entry [%d]=%s\n",
+ context->name_count,
+ context->names[context->name_count].name ?: "(null)");
+ } else
+ context->name_count++;
#if AUDIT_DEBUG
context->ino_count++;
#endif
@@ -1351,7 +1365,15 @@ update_context:
/* A parent was not found in audit_names, so copy the inode data for the
* provided parent. */
if (!found_name) {
- idx = context->name_count++;
+ idx = context->name_count;
+ if (context->name_count == (AUDIT_NAMES - 1)) {
+ printk(KERN_DEBUG
+ "name_count maxed and losing entry [%d]=%s\n",
+ context->name_count,
+ context->names[context->name_count].name ?:
+ "(null)");
+ } else
+ context->name_count++;
#if AUDIT_DEBUG
context->ino_count++;
#endif
18 years, 2 months
type for 3rd party events
by Steve Grubb
Hi,
There is a request for a message type to be allocated allowing 3rd party
kernel modules the ability to send audit events. This would be similar to the
AUDIT_TRUSTED_APP type allocated for user space apps. I'm undecided about a
name and could use some suggestions. My only thoughts right now are
AUDIT_KERNEL_MODULE. Anyone have a better type name for 3rd party use?
Thanks,
-Steve
18 years, 3 months
NetLabel audit messages
by Paul Moore
In order to meet certain certification requirements, the NetLabel kernel
subsystem needs to write a small number of audit messages. From what I
can tell this is going to require a new message type as well as
agreement on the content and formatting of the messages themselves. Am
I missing anything?
For the new message type, I would like to propose the following:
#define AUDIT_NLBL 1480
For the messages themselves, here is what I was thinking:
"netlabel: <protocol> op=<operation> pid=<pid> tty=<tty> comm=<name>
exe=<path> uid=<uid> auid=<auid> euid=<euid> suid=<suid>
fsuid=<fsuid> gid=<gid> egid=<euid> sgid=<suid>
fsgid=<fsuid> [<cipsov4 extras>|<managment extras>]"
<protocol> => cipsov4 | unlabeled | management
<operation> => (for protocol == cipsov4) add | del
(for protocol == unlabeled) accept | deny
(for protocol == management) map_add | map_delete
<cipsov4 extras> => doi=<DOI #> type=<DOI type>
<DOI #> => (CIPSO DOI value, i.e. unsigned 32-bit value)
<DOI type> => std | pass
<mangement extras> => domain=<domain> protocol=<protocol> [doi=<DOI #>]
<domain> => "(domain string, i.e. foo_t)" | default
Comments and suggestions are welcome.
--
paul moore
linux security @ hp
18 years, 3 months
audit 1.2.7 released
by Steve Grubb
Hi,
I've just released a new version of the audit daemon. It can be downloaded
from http://people.redhat.com/sgrubb/audit It will also be in rawhide
tomorrow. The Changelog is:
- Fix logging messages to use addr if passed.
- Apply patches from Tony Jones correcting no kernel support messages
- Updated syscall tables for 2.6.18 kernel
- Remove deprecated functions: audit_log, audit_log_avc, audit_log_if_enabled
- Disallow syscall auditing on exclude list
- Improve time handling in ausearch and aureport (#191394)
- Attempt to reconstruct full path from relative for searching
Please let me know if there are any problems with this release.
-Steve
18 years, 3 months
[PATCH] Add variadic-style alternative function for avc logging
by Eamon Walsh
The attached patch adds a new function audit_log_user_avc_message_fmt
that behaves just like audit_log_user_avc_message, but takes a format
string and argument list instead of a fixed message string.
This change will make it easier to use libaudit from SElinux userspace
object managers, since the libselinux logging callback takes a
format-string and variable length list.
If desired, I can send a patch to introduce this alternative for the
other calls as well.
Signed-off-by: Eamon Walsh <ewalsh(a)tycho.nsa.gov>
docs/audit_log_user_avc_message.3 | 12 +++++++++++-
lib/audit_logging.c | 25 +++++++++++++++++++++++++
lib/libaudit.h | 3 +++
3 files changed, 39 insertions(+), 1 deletion(-)
--
Eamon Walsh <ewalsh(a)tycho.nsa.gov>
National Security Agency
18 years, 3 months