[RFC][PATCH] Smack<->Audit integration
by Ahmed S. Darwish
Hi all,
This is the second step of integrating Audit with Smack.
The AUDIT_SUBJ_USER and AUDIT_OBJ_USER SELinux flags are recycled
for Smack to avoid `auditd' userspace modifications. Smack only
needs auditing on subject/object bases, so those flags were enough.
Patch below setups the new Audit LSM hooks and add a secid field in
smack inode and ipc security structures. The secid field was needed
cause it's the main Audit way of distinguishing kernel objects to
be audited from the remaining ones.
Possibly the last steps would be to:
1- report smack access grants and denials through Audit (like AVC)
2- Letting Audit send an OBJ_USER event in case of a process that
recieved a signal without affecting SELinux.
Thank you for your reviews.
Signed-off-by: Ahmed S. Darwish <darwish.07(a)gmail.com>
---
smack.h | 9 ++
smack_lsm.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 200 insertions(+), 17 deletions(-)
Patch is generated over James security/next branch cause it's the
only tree that currently has the Audit hooks merged:
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2....
diff --git a/security/smack/smack.h b/security/smack/smack.h
index c444f48..2c8bb4c 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -57,6 +57,15 @@ struct inode_smack {
char *smk_inode; /* label of the fso */
struct mutex smk_lock; /* initialization lock */
int smk_flags; /* smack inode flags */
+ int secid; /* security identifier */
+};
+
+/*
+ * IPC smack data
+ */
+struct ipc_smack {
+ char *smk_ipc; /* ipc object label */
+ int secid; /* security identifier */
};
#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index afa7967..5b5e1fd 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -6,6 +6,9 @@
* Author:
* Casey Schaufler <casey(a)schaufler-ca.com>
*
+ * Audit integration by:
+ * Ahmed S. Darwish <darwish.07(a)gmail.com>
+ *
* Copyright (C) 2007 Casey Schaufler <casey(a)schaufler-ca.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -24,6 +27,7 @@
#include <linux/udp.h>
#include <linux/mutex.h>
#include <linux/pipe_fs_i.h>
+#include <linux/audit.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
@@ -75,6 +79,7 @@ struct inode_smack *new_inode_smack(char *smack)
isp->smk_inode = smack;
isp->smk_flags = 0;
+ isp->secid = smack_to_secid(smack);
mutex_init(&isp->smk_lock);
return isp;
@@ -638,6 +643,8 @@ static void smack_inode_post_setxattr(struct dentry *dentry, char *name,
else
isp->smk_inode = smack_known_invalid.smk_known;
+ isp->secid = smack_to_secid(isp->smk_inode);
+
return;
}
@@ -759,6 +766,17 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer,
return -EINVAL;
}
+/**
+ * smack_inode_getsecid - Extract inode's security id
+ * @inode: inode to extract the info from
+ * @secid: where the result will be saved
+ */
+static void smack_inode_getsecid(const struct inode *inode, u32 *secid)
+{
+ struct inode_smack *isp = inode->i_security;
+ *secid = isp->secid;
+}
+
/*
* File Hooks
*/
@@ -1344,6 +1362,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
char *sp;
+ struct smack_known *skp;
struct inode_smack *nsp = inode->i_security;
struct socket_smack *ssp;
struct socket *sock;
@@ -1352,12 +1371,14 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
if (value == NULL || size > SMK_LABELLEN)
return -EACCES;
- sp = smk_import(value, size);
- if (sp == NULL)
+ skp = smk_import_entry(value, size);
+ if (skp == NULL)
return -EINVAL;
+ sp = skp->smk_known;
if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
nsp->smk_inode = sp;
+ nsp->secid = skp->smk_secid;
return 0;
}
/*
@@ -1471,9 +1492,16 @@ static char *smack_of_shm(struct shmid_kernel *shp)
*/
static int smack_shm_alloc_security(struct shmid_kernel *shp)
{
- struct kern_ipc_perm *isp = &shp->shm_perm;
+ struct ipc_smack *isp;
+ struct kern_ipc_perm *ipcp = &shp->shm_perm;
- isp->security = current->security;
+ isp = kzalloc(sizeof(struct ipc_smack), GFP_KERNEL);
+ if (isp == NULL)
+ return -ENOMEM;
+
+ isp->smk_ipc = current->security;
+ isp->secid = smack_to_secid(isp->smk_ipc);
+ ipcp->security = isp;
return 0;
}
@@ -1485,9 +1513,9 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp)
*/
static void smack_shm_free_security(struct shmid_kernel *shp)
{
- struct kern_ipc_perm *isp = &shp->shm_perm;
+ struct kern_ipc_perm *ipcp = &shp->shm_perm;
- isp->security = NULL;
+ kfree(ipcp->security);
}
/**
@@ -1579,9 +1607,16 @@ static char *smack_of_sem(struct sem_array *sma)
*/
static int smack_sem_alloc_security(struct sem_array *sma)
{
- struct kern_ipc_perm *isp = &sma->sem_perm;
+ struct ipc_smack *isp;
+ struct kern_ipc_perm *ipcp = &sma->sem_perm;
+
+ isp = kzalloc(sizeof(struct ipc_smack), GFP_KERNEL);
+ if (isp == NULL)
+ return -ENOMEM;
- isp->security = current->security;
+ isp->smk_ipc = current->security;
+ isp->secid = smack_to_secid(isp->smk_ipc);
+ ipcp->security = isp;
return 0;
}
@@ -1595,7 +1630,7 @@ static void smack_sem_free_security(struct sem_array *sma)
{
struct kern_ipc_perm *isp = &sma->sem_perm;
- isp->security = NULL;
+ kfree(isp->security);
}
/**
@@ -1682,9 +1717,16 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
*/
static int smack_msg_queue_alloc_security(struct msg_queue *msq)
{
- struct kern_ipc_perm *kisp = &msq->q_perm;
+ struct ipc_smack *isp;
+ struct kern_ipc_perm *ipcp = &msq->q_perm;
- kisp->security = current->security;
+ isp = kzalloc(sizeof(struct ipc_smack), GFP_KERNEL);
+ if (isp == NULL)
+ return -ENOMEM;
+
+ isp->smk_ipc = current->security;
+ isp->secid = smack_to_secid(isp->smk_ipc);
+ ipcp->security = isp;
return 0;
}
@@ -1696,9 +1738,9 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq)
*/
static void smack_msg_queue_free_security(struct msg_queue *msq)
{
- struct kern_ipc_perm *kisp = &msq->q_perm;
+ struct kern_ipc_perm *ipcp = &msq->q_perm;
- kisp->security = NULL;
+ kfree(ipcp->security);
}
/**
@@ -1800,18 +1842,30 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
/**
* smack_ipc_permission - Smack access for ipc_permission()
- * @ipp: the object permissions
+ * @ipcp: the object permissions
* @flag: access requested
*
* Returns 0 if current has read and write access, error code otherwise
*/
-static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
+static int smack_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
{
- char *isp = ipp->security;
int may;
+ struct ipc_smack *isp = ipcp->security;
may = smack_flags_to_may(flag);
- return smk_curacc(isp, may);
+ return smk_curacc(isp->smk_ipc, may);
+}
+
+/**
+ * smack_ipc_getsecid - extract Smack security id
+ * @ipcp: the object permissions
+ * @secid: where result will be saved
+ */
+static void smack_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
+{
+ struct inode_smack *isp = ipcp->security;
+
+ *secid = isp->secid;
}
/* module stacking operations */
@@ -1967,6 +2021,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
else
isp->smk_inode = final;
+ isp->secid = smack_to_secid(isp->smk_inode);
isp->smk_flags |= SMK_INODE_INSTANT;
unlockandout:
@@ -2391,6 +2446,116 @@ static int smack_key_permission(key_ref_t key_ref,
#endif /* CONFIG_KEYS */
/*
+ * Smack Audit hooks
+ *
+ * Audit requires an internal representation of each Smack specific
+ * rule which works as a glue between the audit hooks. Since smack_known
+ * repository entries are added but never deleted, we'll use the
+ * smack_known entry related to the given audit rule as the needed
+ * smack representation.
+ *
+ * This will also save us from searching the smack labels repository
+ * each time the audit_rule_match hook get called.
+ */
+#ifdef CONFIG_AUDIT
+
+/**
+ * smack_audit_rule_init - Initialize a smack audit rule
+ * @field: Message flags given from user-space (audit.h)
+ * @op: Required operation (Only equality testing is allowed)
+ * @rulestr: Given user-space rule
+ * @vrule: Where we'll save our own audit rule representation
+ *
+ * The label to be audited (rulestr) is created if necessay
+ */
+static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
+{
+ struct smack_known **smk_rule = (struct smack_known **)vrule;
+ *smk_rule = NULL;
+
+ if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
+ return -EINVAL;
+
+ if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
+ return -EINVAL;
+
+ *smk_rule = smk_import_entry(rulestr, 0);
+
+ return 0;
+}
+
+/**
+ * smack_audit_rule_known - Distinguish smack audit rules from others
+ * @krule: rule of interest, in internal kernel representation format
+ *
+ * This is used to filter rules related to Smack from other saved
+ * Audit rules. If it's proved that this rule belongs to us, the
+ * audit_rule_match hook will be used to check a specific kernel
+ * object against its smack audit rule.
+ */
+static int smack_audit_rule_known(struct audit_krule *krule)
+{
+ struct audit_field *f;
+ int i;
+
+ for (i = 0; i < krule->field_count; i++) {
+ f = &krule->fields[i];
+
+ if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * smack_audit_rule_match - Audit given secid identified object ?
+ * @secid: Security id to test
+ * @field: Message flags given from user-space
+ * @op: Required operation (only equality is allowed)
+ * @vrule: Smack audit rule that will be checked against the secid object
+ * @actx: audit context associated with the check (used for Audit logging)
+ *
+ * This is the core Audit hook. It's used to identify objects like
+ * syscalls and inodes requested from user-space to be audited from
+ * remaining kernel objects.
+ */
+static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
+ struct audit_context *actx)
+{
+ struct smack_known *smk_rule = vrule;
+
+ if (!smk_rule) {
+ audit_log(actx, GFP_KERNEL, AUDIT_SELINUX_ERR,
+ "Smack: missing rule\n");
+ return -ENOENT;
+ }
+
+ if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
+ return 0;
+
+ if (op == AUDIT_EQUAL)
+ return (smk_rule->smk_secid == secid);
+ if (op == AUDIT_NOT_EQUAL)
+ return (smk_rule->smk_secid != secid);
+
+ return 0;
+}
+
+/**
+ * smack_audit_rule_free - free internal audit rule representation
+ * @vrule: rule to be freed.
+ *
+ * No memory was allocated in audit_rule_init.
+ */
+static void smack_audit_rule_free(void *vrule)
+{
+ /* No-op */
+}
+
+#endif /* CONFIG_AUDIT */
+
+/*
* smack_secid_to_secctx - return the smack label for a secid
* @secid: incoming integer
* @secdata: destination
@@ -2476,6 +2641,7 @@ struct security_operations smack_ops = {
.inode_getsecurity = smack_inode_getsecurity,
.inode_setsecurity = smack_inode_setsecurity,
.inode_listsecurity = smack_inode_listsecurity,
+ .inode_getsecid = smack_inode_getsecid,
.file_permission = smack_file_permission,
.file_alloc_security = smack_file_alloc_security,
@@ -2506,6 +2672,7 @@ struct security_operations smack_ops = {
.task_to_inode = smack_task_to_inode,
.ipc_permission = smack_ipc_permission,
+ .ipc_getsecid = smack_ipc_getsecid,
.msg_msg_alloc_security = smack_msg_msg_alloc_security,
.msg_msg_free_security = smack_msg_msg_free_security,
@@ -2550,12 +2717,22 @@ struct security_operations smack_ops = {
.sk_free_security = smack_sk_free_security,
.sock_graft = smack_sock_graft,
.inet_conn_request = smack_inet_conn_request,
+
/* key management security hooks */
#ifdef CONFIG_KEYS
.key_alloc = smack_key_alloc,
.key_free = smack_key_free,
.key_permission = smack_key_permission,
#endif /* CONFIG_KEYS */
+
+ /* Audit hooks */
+#ifdef CONFIG_AUDIT
+ .audit_rule_init = smack_audit_rule_init,
+ .audit_rule_known = smack_audit_rule_known,
+ .audit_rule_match = smack_audit_rule_match,
+ .audit_rule_free = smack_audit_rule_free,
+#endif /* CONFIG_AUDIT */
+
.secid_to_secctx = smack_secid_to_secctx,
.secctx_to_secid = smack_secctx_to_secid,
.release_secctx = smack_release_secctx,
Regards,
--
"Better to light a candle, than curse the darkness"
Ahmed S. Darwish
Homepage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com
16 years, 12 months
New Version (2090) of Certification Test Suite
by Jon Wallace
HP has posted an updated version of the audit-test suite for the audit and MLS
portions of CAPP/LSPP/RBACPP certification on RHEL5.1.
http://sourceforge.net/projects/audit-test/
The suite (2090) is available as a tarball, a source rpm, and as a noarch
rpm which will install files into /usr/local/eal4_testing/audit-test.
There are 3 README files which describe how to run the tests, how to
develop tests, and how to configure the test server for network tests.
These tests are known to pass on RHEL5.1 plus the updated packages listed
in our security target in both CAPP mode (optional targeted policy) and
LSPP mode (mls policy) on x86_64 and ia64 architectures. Code exists for
other architectures but no other architectures have been tested with this
version of the test suite. The updated tests fix failures that were due to
changes in some of the pam audit records.
We would appreciate feedback as well as patches through the
sourceforge project trackers if you use and update the suite.
We are especially interested in hearing from people running the
tests on other distros, with or without SELinux.
Thanks,
Jon
16 years, 12 months
[PATCH] Audit: standardize string audit interfaces
by Eric Paris
This patch standardized the string auditing interfaces. No userspace
changes will be visible and this is all just cleanup and consistancy
work. We have the following string audit interfaces to use:
void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len);
void audit_log_n_string(struct audit_buffer *ab, const char *buf, size_t n);
void audit_log_string(struct audit_buffer *ab, const char *buf);
void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string, size_t n);
void audit_log_untrustedstring(struct audit_buffer *ab, const char *string);
This may be the first step to possibly fixing some of the issues that
people have with the string output from the kernel audit system. But we
still don't have an agreed upon solution to that problem.
Signed-off-by: Eric Paris <eparis(a)redhat.com>
---
drivers/char/tty_audit.c | 2 +-
include/linux/audit.h | 22 ++++++++++++++--------
kernel/audit.c | 19 +++++++++----------
kernel/auditsc.c | 8 ++++----
security/selinux/avc.c | 2 +-
5 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index 7722466..ae032c5 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -92,7 +92,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
get_task_comm(name, tsk);
audit_log_untrustedstring(ab, name);
audit_log_format(ab, " data=");
- audit_log_n_untrustedstring(ab, buf->valid, buf->data);
+ audit_log_n_untrustedstring(ab, buf->data, buf->valid);
audit_log_end(ab);
}
buf->valid = 0;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 2af9ec0..93afdc5 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -522,16 +522,20 @@ extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
extern void audit_log_end(struct audit_buffer *ab);
-extern void audit_log_hex(struct audit_buffer *ab,
- const unsigned char *buf,
- size_t len);
extern int audit_string_contains_control(const char *string,
size_t len);
+extern void audit_log_n_hex(struct audit_buffer *ab,
+ const unsigned char *buf,
+ size_t len);
+extern void audit_log_n_string(struct audit_buffer *ab,
+ const char *buf,
+ size_t n);
+#define audit_log_string(a,b) audit_log_n_string(a, b, strlen(b));
+extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
+ const char *string,
+ size_t n);
extern void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string);
-extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
- size_t n,
- const char *string);
extern void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
struct path *path);
@@ -548,9 +552,11 @@ extern int audit_enabled;
#define audit_log_vformat(b,f,a) do { ; } while (0)
#define audit_log_format(b,f,...) do { ; } while (0)
#define audit_log_end(b) do { ; } while (0)
-#define audit_log_hex(a,b,l) do { ; } while (0)
-#define audit_log_untrustedstring(a,s) do { ; } while (0)
+#define audit_log_n_hex(a,b,l) do { ; } while (0)
+#define audit_log_n_string(a,c,l) do { ; } while (0)
+#define audit_log_string(a,c) do { ; } while (0)
#define audit_log_n_untrustedstring(a,n,s) do { ; } while (0)
+#define audit_log_untrustedstring(a,s) do { ; } while (0)
#define audit_log_d_path(b, p, d) do { ; } while (0)
#define audit_enabled 0
#endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 10c4930..a79d6d6 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -659,8 +659,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
audit_log_format(ab, " msg=");
size = nlmsg_len(nlh);
- audit_log_n_untrustedstring(ab, size,
- data);
+ audit_log_n_untrustedstring(ab, data, size);
}
audit_set_pid(ab, pid);
audit_log_end(ab);
@@ -1198,7 +1197,7 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
* This function will take the passed buf and convert it into a string of
* ascii hex digits. The new string is placed onto the skb.
*/
-void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
+void audit_log_n_hex(struct audit_buffer *ab, const unsigned char *buf,
size_t len)
{
int i, avail, new_len;
@@ -1234,8 +1233,8 @@ void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf,
* Format a string of no more than slen characters into the audit buffer,
* enclosed in quote marks.
*/
-static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
- const char *string)
+void audit_log_n_string(struct audit_buffer *ab, const char *string,
+ size_t slen)
{
int avail, new_len;
unsigned char *ptr;
@@ -1291,13 +1290,13 @@ int audit_string_contains_control(const char *string, size_t len)
* The caller specifies the number of characters in the string to log, which may
* or may not be the entire string.
*/
-void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
- const char *string)
+void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string,
+ size_t len)
{
if (audit_string_contains_control(string, len))
- audit_log_hex(ab, string, len);
+ audit_log_n_hex(ab, string, len);
else
- audit_log_n_string(ab, len, string);
+ audit_log_n_string(ab, string, len);
}
/**
@@ -1310,7 +1309,7 @@ void audit_log_n_untrustedstring(struct audit_buffer *ab, size_t len,
*/
void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
{
- audit_log_n_untrustedstring(ab, strlen(string), string);
+ audit_log_n_untrustedstring(ab, string, strlen(string));
}
/* This is a helper-function to print the escaped d_path */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 782262e..62ad0d7 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1095,7 +1095,7 @@ static int audit_log_single_execve_arg(struct audit_context *context,
audit_log_format(*ab, "[%d]", i);
audit_log_format(*ab, "=");
if (has_cntl)
- audit_log_hex(*ab, buf, to_send);
+ audit_log_n_hex(*ab, buf, to_send);
else
audit_log_format(*ab, "\"%s\"", buf);
audit_log_format(*ab, "\n");
@@ -1306,7 +1306,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
struct audit_aux_data_sockaddr *axs = (void *)aux;
audit_log_format(ab, "saddr=");
- audit_log_hex(ab, axs->a, axs->len);
+ audit_log_n_hex(ab, axs->a, axs->len);
break; }
case AUDIT_FD_PAIR: {
@@ -1370,8 +1370,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
default:
/* log the name's directory component */
audit_log_format(ab, " name=");
- audit_log_n_untrustedstring(ab, n->name_len,
- n->name);
+ audit_log_n_untrustedstring(ab, n->name,
+ n->name_len);
}
} else
audit_log_format(ab, " name=(null)");
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 187964e..bd67c2c 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -643,7 +643,7 @@ void avc_audit(u32 ssid, u32 tsid,
if (*p)
audit_log_untrustedstring(ab, p);
else
- audit_log_hex(ab, p, len);
+ audit_log_n_hex(ab, p, len);
break;
}
}
17 years
audit 1.6.9 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
soon. The Changelog is:
- Apply hidden attribute cleanup patch (Miloslav Trmac)
- Apply auparse expression interface patch (Miloslav Trmac)
- Fix potential memleak in audit event dispatcher
- Change default audispd queue depth to 80
- Update system-config-audit to version 0.4.6 (Miloslav Trmac)
- audisp-prelude alerts now controlled by config file
- Updated syscall table for 2.6.25 kernel
- Apply patch correcting acct field being misencoded (Miloslav Trmac)
- Added watched account login detection for prelude plugin
This release adds new syscalls from the 2.6.25 kernel. it also improves the
audisp-prelude plugin by giving a configuration file where individual alerts
can be enable disabled as well as a custom profile name set for prelude. The
plugin was also improved by adding the capability to watch for login events
of admin selected accounts and send an alert. Currently this only works on
successful logins, but will be updated to include some failed attempts, too.
Please let me know if you run across any problems with this release.
-Steve
17 years
[PATCH] Fix acct quoting in audit_log_acct_message())
by Miloslav Trmac
Hello,
audit_log_acct_message() is currently quoting acct differently from all
other users: it adds quotes to acct if it is represented in hexadecimal,
not when it is represented as-is.
The attached patch fixes it - but it also changes the format of some of
the most-often used messages. It might be better to leave the message
format alone, and add a special case to libauparse and other
applications that parse the logs - I have no idea.
Mirek
17 years
[PATCH, RFC] Add expression support to libauparse
by Miloslav Trmac
Hello,
this patch extends libauparse to support arbitrary boolean expressions
and searching for record type ranges.
It seems best to define expression syntax and add a single
ausearch_add_expression() call, rather than build the expression from
atomic subexpressions. The defined syntax could be shared by all tools
that link to libauparse, and programs would be able to run (and display
meaningful error messages, as opposed to crashing when a relocation can
not be resloved) even if the installed libauparse version does not
support the used filter.
Attached is a description of the expression syntax. Please check
whether the design is reasonably future-proof. A nicer alternative to
using three different sets of comparison operators would be welcome.
Mirek
LEXICAL STRUCTURE
White space (ASCII space, tab and new-line characters) between tokens
is ignored. The following tokens are recognized:
Punctuation
( ) \
Logical operators
! && ||
Comparison operators
< <= == > >= !== i= i!= r= r!=
Unquoted strings
Any non-empty sequence of ASCII letters, digits, and the _ sym-
bol.
Quoted strings
A sequence of characters surrounded by the " quotes. The \
character starts an escape sequence. The only defined escape
sequences are \\ and \". The semantics of other escape
sequences is undefined.
Anywhere an unquoted string is valid, a quoted string is valid as well,
and vice versa. In particular, field names may be specified using
quoted strings, and field values may be specified using unquoted
strings.
EXPRESSION SYNTAX
The primary expression has the following form:
field comparison-operator value
field is either a string, which specifies the first field with that
name within the current audit record, or the \ escape character fol-
lowed by a string, which specifies a virtual field with the specified
name (virtual fields are defined in a later section).
field is a string. operator specifies the comparison to perform
r= r!= Get the "raw" string of field, and compare it to value. For
fields in audit records, the "raw" string is the exact string
stored in the audit record (with all escaping and unprintable
character encoding left alone); applications can read the "raw"
string using auparse get field str(3). Each virtual field may
define a "raw" string. If field is not present or does not
define a "raw" string, the result of the comparison is false
(regardless of the operator).
i= i!= Get the "interpreted" string of field, and compare it to value.
For fields in audit records, the "interpreted" string is an
"user-readable" interpretation of the field value; applications
can read the "interpreted" string using auparse inter-
pret field(3). Each virtual field may define an "interpreted"
string. If field is not present or does not define an "inter-
preted" string, the result of the comparison is false (regard-
less of the operator).
< <= == > >= !==
Evaluate the "value" of field, and compare it to value. A
"value" may be defined for any field or virtual field, but no
"value" is currently defined for any audit record field. The
rules of parsing value for comparing it with the "value" of
field are specific for each field. If field is not present, the
result of the comparison is false (regardless of the operator).
If field does not define a "value", an error is reported when
parsing the expression.
If E1 and E2 are valid expressions, then ! E1, E1 && E2, and E1 || E2
are valid expressions as well, with the usual C semantics and evalua-
tion priorities. Note that ! field op value is interpreted as !(field
op value), not as (!field) op value.
VIRTUAL FIELDS
The following virtual fields are defined:
\timestamp
The value is the timestamp of the current event. value must
have the ts:seconds.milli format, where seconds and milli are
decimal numbers specifying the seconds and milliseconds part of
the timestamp, respectively.
\record_type
The value is the type of the current record. value is either
the record type name, or a decimal number specifying the type.
SEMANTICS
The expression as a whole applies to a single record. The expression
is true for a specified event if it is true for any record associated
with the event.
EXAMPLES
As a demonstration of the semantics of handling missing fields, the
following expression is true if field is present:
(field r= "") || (field r!= "")
and the same expression surrounded by !( and ) is true if field is not
present.
FUTURE DIRECTIONS
New escape sequences for quoted strings may be defined.
For currently defined virtual fields that do not define a "raw" or
"interpreted" string, the definition may be added. Therefore, don’t
rely on the fact that comparing the "raw" or "interpreted" string of
the field with any value is false.
New formats of value constants for the \timestamp virtual field may be
added.
17 years
How to retrieve pointer arguments' value
by Marius.bao
Hi,
Some of the syscalls provide pointer arguments, but the audit just
provide the pointer value, not the data it pointers to. How can I
retrieve the value the argument pointers to?
Thanks in advance!
17 years
Re: [PATCH] Fix acct quoting in audit_log_acct_message())
by Miloslav Trmac
Tomas Mraz napsal(a):
> This proposal is just for starting the discussion.
>
> 1. Messages contain <name>=<value> pairs separated by spaces.
> 2. All <names> are just alphanumeric sequences.
> 3. Values can be either:
> a) byte sequences with the following special characters encoded as %XX
> where XX is hexadecimal value of the encoded byte. Special characters
> are: bytes with value <= 0x20 or >= 0x7F, '%', '(', ')', and '='.
Perhaps we should reserve more characters for future features - at least
'"', '\'' and '\\', maybe everything but [a-zA-Z0-9_-].
From the previous thread - the currently used hexadecimal format is
good for non-ASCII data (2 characters per byte instead of 3 bytes); It
probably won't be better for most messages - perhaps it should be left
as a third alternative, e.g. \xaa55abcdef.
One more proposal:
4. If a value is undefined, the name=value pair is not present. Special
values ("?", "(null)", "") are never used to represent unknown
field values.
> b) recursively embedded messages enclosed in '(' and ')' parentheses.
> type=USER_START msg=audit(1204632061.112:32361): user pid=10902 uid=0
> auid=0 subj=system_u:system_r:crond_t:s0-s0:c0.c1023
> msg='op=PAM:session_open acct=root exe="/usr/sbin/crond" (hostname=?,
> addr=?, terminal=cron res=success)'
>
> becomes:
>
> type=USER_START msg=(audit=1204632061.112:3236 src=user pid=10902 uid=0
> auid=0 subj=system_u:system_r:crond_t:s0-s0:c0.c1023
> msg=(op=PAM:session_open acct=root exe=/usr/sbin/crond hostname=? addr=?
> terminal=cron res=success))
[Should there be only one trailing )? ] Using "msg" for both the kernel
and user-space part is ambiguous - perhaps "kmsg"/"umsg" or just
"k"/"u"? Or, preferably, don't nest the kernel fields at all - the
nesting carries no information.
> type=AVC msg=audit(1204601533.621:32307): avc: denied { read write }
> for pid=9822 comm="tmpwatch" path="socket:[14038]" dev=sockfs ino=14038
> scontext=system_u:system_r:tmpreaper_t:s0-s0:c0.c1023
> tcontext=system_u:system_r:crond_t:s0-s0:c0.c1023 tclass=tcp_socket
>
> becomes:
>
> type=AVC msg=(audit=1204601533.621:32307 src=avc kind=denied
> acts=read:write pid=9822 comm=tmpwatch path=socket:[14038] dev=sockfs
> ino=14038 scontext=system_u:system_r:tmpreaper_t:s0-s0:c0.c1023
> tcontext=system_u:system_r:crond_t:s0-s0:c0.c1023 tclass=tcp_socket)
(auparse already defines names for some of the fields, the names should
be reused.)
Mirek
17 years
[PATCH-v2 -mm 0/9] LSM-neutral Audit (SELinux audit separation)
by Ahmed S. Darwish
Hi everybody,
A series of 9 patches to let Audit be LSM netural. This is done
for proper future audit<->SMACK integration which will also be
useful for any future LSM.
Basically, patches add below new LSM hooks:
1- secid extraction:
inode_getsecid(inode, secid)
ipc_getsecid(ipcp, secid)
2- LSM-specific Audit rules manipulation:
audit_rule_init(field, op, rulestr, lsmrule)
audit_rule_known(krule)
audit_rule_match(secid, field, op, rule, actx)
audit_rule_free(rule)
and remove ,now redundant, equivalent SELinux exported interfaces.
Initial work and idea by: Casey Schaufler <casey(a)schaufler-ca.com>
Thanks to Paul Moore <paul.moore(a)hp.com> for his deep review of first
version.
include/linux/audit.h | 29 ++++++++
include/linux/security.h | 102 +++++++++++++++++++++++++++++
include/linux/selinux.h | 134 ---------------------------------------
kernel/audit.c | 24 ++----
kernel/audit.h | 25 -------
kernel/auditfilter.c | 99 ++++++++++------------------
kernel/auditsc.c | 74 +++++++++++----------
net/netlink/af_netlink.c | 3 +-
security/dummy.c | 47 +++++++++++++
security/security.c | 35 ++++++++++
security/selinux/exports.c | 42 ------------
security/selinux/hooks.c | 27 +++++++
security/selinux/include/audit.h | 65 ++++++++++++++++++
security/selinux/ss/services.c | 45 +++++++++----
14 files changed, 420 insertions(+), 331 deletions(-)
Regards,
--
"Better to light a candle, than curse the darkness"
Ahmed S. Darwish
Homepage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com
17 years
auditing nfs
by Bob Kryger
So, I'm looking to audit file access (via syscalls
create,open,unlink,etc. because I want every file in the filesystem and
do not want to have to specify an audit rule for each dir/file) that are
accessed via nfs from the nfs server. It seems, I assume because nfs is
in the kernel, that I am not getting any audit messages for those nfs
files access.
Is my assumption correct?
Any suggestions for auditing from the nfs server side?
BTW: not a list subscriber, please reply directly.
Thanks
Bob
--
Bob Kryger Office: 212-813-8677
Systems/Network Administrator Cell: 917-913-6670
SAC Capital, Synapse Group email: bobk(a)sac.com
540 Madison Ave AIM: sacbobk
New York, NY 10022
DISCLAIMER: This e-mail message and any attachments are intended solely for the use of the individual or entity to which it is addressed and may contain information that is confidential or legally privileged. If you are not the intended recipient, you are hereby notified that any dissemination, distribution, copying or other use of this message or its attachments is strictly prohibited. If you have received this message in error, please notify the sender immediately and permanently delete this message and any attachments.
17 years