Error on stop
by Mont Rothstein
When I stop auditd I get an error even though it gives me an OK.
The error is:
Error receiving watch list (Unknown error 4294967274)
I saw a long but closed bug on this. Before I went and appened info to a
closed bug I thought I should ask here first.
I am on audit-1.0.12 is this still a bug in this version, and if it is do I
need to worry about it?
My output from uname -a is:
Linux rheles4rs1.forayadams.foray.com 2.6.9-11.EL #1 Fri May 20 18:17:57 EDT
2005 i686 i686 i386 GNU/Linux
Thanks,
-Mont
18 years, 9 months
[PATCH] Rework of IPC auditing
by Dustin Kirkland
Hi-
I've reworked the handling of IPC auditing altogether. I did this with
Klaus Weidner of atsec over my shoulder for much of it. He helped and
advised exactly where the ipc code should be hooked and approved of the
coverage at this point in terms of LSPP certification. To that extent,
I very much thank Klaus and invite him to add any additional comments to
this post.
There are two key changes in this patch against Al's current git tree:
1) The audit_ipc_perms() function has been split into two different
functions:
- audit_ipc_obj()
- audit_ipc_new_perm()
There's a key shift here... The audit_ipc_obj() collects the uid, gid,
mode, and SElinux context label of the current ipc object. This
audit_ipc_obj() hook is now found in several places. Most notably, it
is hooked in ipcperms(), which is called in various places around the
ipc code permforming a MAC check. Additionally there are several places
where *checkid() is used to validate that an operation is being
performed on a valid object while not necessarily having a nearby
ipcperms() call. In these locations, audit_ipc_obj() is called to
ensure that the information is captured by the audit system.
The audit_ipc_new_perm() function is called any time the permissions on
the ipc object changes. In this case, the NEW permissions are recorded
(and note that an audit_ipc_obj() call exists just a few lines before
each instance).
2) Support for an AUDIT_IPC_NEW_PERM audit message type. This allows
for separate auxiliary audit records for normal operations on an IPC
object and permissions changes. Note that the same struct
audit_aux_data_ipcctl is used and populated, however there are separate
audit_log_format statements based on the type of the message. Finally,
the AUDIT_IPC block of code in audit_free_aux() was extended to handle
aux messages of this new type. No more mem leaks I hope ;-)
Note that this does:
- Change the format of the audit record (sorry test guys)
- And add a new audit record that will need to be tested (sorry again
test guys)
The new auxiliary audit record helps clarify the purpose of the separate
messages. And the separate audit_ipc_* functions eliminates the need
for passing known invalid values where those aren't used and
conditionally not printing those instances (which was messy). In the
old case, it was confusing in that the same message type would mix old
and new ids depending on which code called the audit hook. Now, it's
clear what is being recorded.
Thus, with Klaus, I did an exhaustive examination through the ipc code
and we believe that this patch captures all of the pertinent audit
information about ipc objects for LSPP. Note that the ipc/mqueue.c
POSIX message queue filesystem was NOT hooked, as there do not appear to
by any permissions checks in that code. It's our assumption that the
messages necessary will be covered by audit hooks in the filesystem code
as it looks like this ipc type is built on top of that.
I've compiled and booted the kernel with this patch in all valid
combinations of Audit/AuditSystemCall/SELinux compiled in and out. I
have not tested with SELinux and/or Audit off.
I think at this point this patch is ready for inclusion in our LSPP
kernels and some testing. I have a couple of questions that remain:
- I'd like to run these changes carefully by someone very familiar with
the Linux ipc code. There are some strange nuances between msg.c,
sem.c, and shm.c that I'd like to make sure are interpreted correctly.
Al, is this your area?
- There are a couple of warnings that have been in the ipc compilations
for some time now about possibly using setbuf.* before initialization.
I'm wondering if anyone thinks these compiler warnings are founded and
if anyone has suggestions to silence them?
- Finally a careful look that audit_free_aux() is accurately cleaning
up the memory.
Patch below. Thanks!
:-Dustin
diff --git a/include/linux/audit.h b/include/linux/audit.h
index dd4f759..3614d13 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -82,6 +82,7 @@
#define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */
#define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */
#define AUDIT_CWD 1307 /* Current working directory */
+#define AUDIT_IPC_NEW_PERM 1308 /* IPC new permissions record type */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -315,7 +316,8 @@ extern void auditsc_get_stamp(struct aud
struct timespec *t, unsigned int *serial);
extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
extern uid_t audit_get_loginuid(struct audit_context *ctx);
-extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp);
+extern int audit_ipc_obj(struct kern_ipc_perm *ipcp);
+extern int audit_ipc_new_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
extern int audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
@@ -335,7 +337,8 @@ extern int audit_set_macxattr(const char
#define audit_inode_child(d,i,p) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
-#define audit_ipc_perms(q,u,g,m,i) ({ 0; })
+#define audit_ipc_obj(i) ({ 0; })
+#define audit_ipc_new_perm(q,u,g,m) ({ 0; })
#define audit_socketcall(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_avc_path(dentry, mnt) ({ 0; })
diff --git a/ipc/msg.c b/ipc/msg.c
index 8c30ec2..382594f 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -13,6 +13,9 @@
* mostly rewritten, threaded and wake-one semantics added
* MSGMAX limit removed, sysctl's added
* (c) 1999 Manfred Spraul <manfred(a)colorfullife.com>
+ *
+ * support for audit of ipc object properties and permission changes
+ * Dustin Kirkland <dustin.kirkland(a)us.ibm.com>
*/
#include <linux/capability.h>
@@ -446,6 +449,11 @@ asmlinkage long sys_msgctl (int msqid, i
if (msg_checkid(msq,msqid))
goto out_unlock_up;
ipcp = &msq->q_perm;
+
+ err = audit_ipc_obj(ipcp);
+ if (err)
+ goto out_unlock_up;
+
err = -EPERM;
if (current->euid != ipcp->cuid &&
current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN))
@@ -459,7 +467,8 @@ asmlinkage long sys_msgctl (int msqid, i
switch (cmd) {
case IPC_SET:
{
- if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
+ err = audit_ipc_new_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode);
+ if (err)
goto out_unlock_up;
err = -EPERM;
diff --git a/ipc/sem.c b/ipc/sem.c
index 59696a8..bb5f9f8 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -61,6 +61,9 @@
* (c) 2001 Red Hat Inc <alan(a)redhat.com>
* Lockless wakeup
* (c) 2003 Manfred Spraul <manfred(a)colorfullife.com>
+ *
+ * support for audit of ipc object properties and permission changes
+ * Dustin Kirkland <dustin.kirkland(a)us.ibm.com>
*/
#include <linux/config.h>
@@ -819,6 +822,11 @@ static int semctl_down(int semid, int se
goto out_unlock;
}
ipcp = &sma->sem_perm;
+
+ err = audit_ipc_obj(ipcp);
+ if (err)
+ goto out_unlock;
+
if (current->euid != ipcp->cuid &&
current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
err=-EPERM;
@@ -835,7 +843,8 @@ static int semctl_down(int semid, int se
err = 0;
break;
case IPC_SET:
- if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
+ err = audit_ipc_new_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
+ if (err)
goto out_unlock;
ipcp->uid = setbuf.uid;
ipcp->gid = setbuf.gid;
diff --git a/ipc/shm.c b/ipc/shm.c
index a88c8a0..f419f5e 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -13,6 +13,8 @@
* Shared /dev/zero support, Kanoj Sarcar <kanoj(a)sgi.com>
* Move the mm functionality over to mm/shmem.c, Christoph Rohland <cr(a)sap.com>
*
+ * support for audit of ipc object properties and permission changes
+ * Dustin Kirkland <dustin.kirkland(a)us.ibm.com>
*/
#include <linux/config.h>
@@ -540,6 +542,10 @@ asmlinkage long sys_shmctl (int shmid, i
if(err)
goto out_unlock;
+ err = audit_ipc_obj(&(shp->shm_perm));
+ if (err)
+ goto out_unlock;
+
if (!capable(CAP_IPC_LOCK)) {
err = -EPERM;
if (current->euid != shp->shm_perm.uid &&
@@ -592,6 +598,10 @@ asmlinkage long sys_shmctl (int shmid, i
if(err)
goto out_unlock_up;
+ err = audit_ipc_obj(&(shp->shm_perm));
+ if (err)
+ goto out_unlock_up;
+
if (current->euid != shp->shm_perm.uid &&
current->euid != shp->shm_perm.cuid &&
!capable(CAP_SYS_ADMIN)) {
@@ -625,11 +635,15 @@ asmlinkage long sys_shmctl (int shmid, i
err=-EINVAL;
if(shp==NULL)
goto out_up;
- if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm))))
- goto out_unlock_up;
err = shm_checkid(shp,shmid);
if(err)
goto out_unlock_up;
+ err = audit_ipc_obj(&(shp->shm_perm));
+ if (err)
+ goto out_unlock_up;
+ err = audit_ipc_new_perm(0, setbuf.uid, setbuf.gid, setbuf.mode);
+ if (err)
+ goto out_unlock_up;
err=-EPERM;
if (current->euid != shp->shm_perm.uid &&
current->euid != shp->shm_perm.cuid &&
diff --git a/ipc/util.c b/ipc/util.c
index e37e1e9..be79943 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -10,6 +10,8 @@
* Manfred Spraul <manfred(a)colorfullife.com>
* Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary().
* Mingming Cao <cmm(a)us.ibm.com>
+ * Mar 2006 - support for audit of ipc object properties
+ * Dustin Kirkland <dustin.kirkland(a)us.ibm.com>
*/
#include <linux/config.h>
@@ -467,9 +469,10 @@ void ipc_rcu_putref(void *ptr)
int ipcperms (struct kern_ipc_perm *ipcp, short flag)
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
- int requested_mode, granted_mode;
-
- audit_ipc_context(ipcp);
+ int requested_mode, granted_mode, err;
+
+ if (unlikely((err = audit_ipc_obj(ipcp))))
+ return err;
requested_mode = (flag >> 6) | (flag >> 3) | flag;
granted_mode = ipcp->mode;
if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index cd83289..acbb424 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -414,10 +414,10 @@ static inline void audit_free_aux(struct
dput(axi->dentry);
mntput(axi->mnt);
}
- if ( aux->type == AUDIT_IPC ) {
+ if ( aux->type == AUDIT_IPC ||
+ aux->type == AUDIT_IPC_NEW_PERM ) {
struct audit_aux_data_ipcctl *axi = (void *)aux;
- if (axi->ctx)
- kfree(axi->ctx);
+ kfree(axi->ctx);
}
context->aux = aux->next;
@@ -618,8 +618,15 @@ static void audit_log_exit(struct audit_
case AUDIT_IPC: {
struct audit_aux_data_ipcctl *axi = (void *)aux;
audit_log_format(ab,
- " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s",
- axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx);
+ " iuid=%u igid=%u mode=%x obj=%s",
+ axi->uid, axi->gid, axi->mode, axi->ctx);
+ break; }
+
+ case AUDIT_IPC_NEW_PERM: {
+ struct audit_aux_data_ipcctl *axi = (void *)aux;
+ audit_log_format(ab,
+ " new_qbytes=%lx new_iuid=%u new_igid=%u new_mode=%x",
+ axi->qbytes, axi->uid, axi->gid, axi->mode);
break; }
case AUDIT_SOCKETCALL: {
@@ -1149,7 +1156,36 @@ uid_t audit_get_loginuid(struct audit_co
}
/**
- * audit_ipc_perms - record audit data for ipc
+ * audit_ipc_obj - record audit data for ipc object
+ * @ipcp: ipc permissions
+ *
+ * Returns 0 for success or NULL context or < 0 on error.
+ */
+int audit_ipc_obj(struct kern_ipc_perm *ipcp)
+{
+ struct audit_aux_data_ipcctl *ax;
+ struct audit_context *context = current->audit_context;
+
+ if (likely(!context))
+ return 0;
+
+ ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
+ if (!ax)
+ return -ENOMEM;
+
+ ax->uid = ipcp->uid;
+ ax->gid = ipcp->gid;
+ ax->mode = ipcp->mode;
+ ax->ctx = audit_ipc_context(ipcp);
+
+ ax->d.type = AUDIT_IPC;
+ ax->d.next = context->aux;
+ context->aux = (void *)ax;
+ return 0;
+}
+
+/**
+ * audit_ipc_new_perm - record audit data for new ipc permissions
* @qbytes: msgq bytes
* @uid: msgq user id
* @gid: msgq group id
@@ -1157,7 +1193,7 @@ uid_t audit_get_loginuid(struct audit_co
*
* Returns 0 for success or NULL context or < 0 on error.
*/
-int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp)
+int audit_ipc_new_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
{
struct audit_aux_data_ipcctl *ax;
struct audit_context *context = current->audit_context;
@@ -1173,9 +1209,8 @@ int audit_ipc_perms(unsigned long qbytes
ax->uid = uid;
ax->gid = gid;
ax->mode = mode;
- ax->ctx = audit_ipc_context(ipcp);
- ax->d.type = AUDIT_IPC;
+ ax->d.type = AUDIT_IPC_NEW_PERM;
ax->d.next = context->aux;
context->aux = (void *)ax;
return 0;
18 years, 9 months
change lspp ipc auditing
by Steve Grubb
Hi,
The patch below converts IPC auditing to collect sid's and convert to context
string only if it needs to output an audit record. This patch depends on the
inode audit change patch already being applied.
Signed-off-by: Steve Grubb <sgrubb(a)redhat.com>
diff -urp linux-2.6.16.x86_64.orig/include/linux/security.h linux-2.6.16.x86_64/include/linux/security.h
--- linux-2.6.16.x86_64.orig/include/linux/security.h 2006-03-31 08:32:05.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/security.h 2006-03-31 09:58:48.000000000 -0500
@@ -869,11 +869,6 @@ struct swap_info_struct;
* @ipcp contains the kernel IPC permission structure
* @flag contains the desired (requested) permission set
* Return 0 if permission is granted.
- * @ipc_getsecurity:
- * Copy the security label associated with the ipc object into
- * @buffer. @buffer may be NULL to request the size of the buffer
- * required. @size indicates the size of @buffer in bytes. Return
- * number of bytes used/required on success.
*
* Security hooks for individual messages held in System V IPC message queues
* @msg_msg_alloc_security:
@@ -1223,7 +1218,6 @@ struct security_operations {
void (*task_to_inode)(struct task_struct *p, struct inode *inode);
int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
- int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size);
int (*msg_msg_alloc_security) (struct msg_msg * msg);
void (*msg_msg_free_security) (struct msg_msg * msg);
@@ -1881,11 +1875,6 @@ static inline int security_ipc_permissio
return security_ops->ipc_permission (ipcp, flag);
}
-static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
-{
- return security_ops->ipc_getsecurity(ipcp, buffer, size);
-}
-
static inline int security_msg_msg_alloc (struct msg_msg * msg)
{
return security_ops->msg_msg_alloc_security (msg);
@@ -2521,11 +2510,6 @@ static inline int security_ipc_permissio
return 0;
}
-static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
-{
- return -EOPNOTSUPP;
-}
-
static inline int security_msg_msg_alloc (struct msg_msg * msg)
{
return 0;
diff -urp linux-2.6.16.x86_64.orig/include/linux/selinux.h linux-2.6.16.x86_64/include/linux/selinux.h
--- linux-2.6.16.x86_64.orig/include/linux/selinux.h 2006-03-31 08:32:09.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/selinux.h 2006-03-31 08:55:33.000000000 -0500
@@ -16,6 +16,7 @@
struct selinux_audit_rule;
struct audit_context;
struct inode;
+struct kern_ipc_perm;
#ifdef CONFIG_SECURITY_SELINUX
@@ -98,6 +99,15 @@ int selinux_ctxid_to_string(u32 ctxid, c
*/
void selinux_get_inode_sid(const struct inode *inode, u32 *sid);
+/**
+ * selinux_get_ipc_sid - get the ipc security context ID
+ * @ipcp: ipc structure to get the sid from.
+ * @sid: pointer to security context ID to be filled in.
+ *
+ * Returns nothing
+ */
+void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid);
+
#else
static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -141,6 +151,11 @@ static inline void selinux_get_inode_sid
*sid = 0;
}
+static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid)
+{
+ *sid = 0;
+}
+
#endif /* CONFIG_SECURITY_SELINUX */
#endif /* _LINUX_SELINUX_H */
diff -urp linux-2.6.16.x86_64.orig/kernel/auditsc.c linux-2.6.16.x86_64/kernel/auditsc.c
--- linux-2.6.16.x86_64.orig/kernel/auditsc.c 2006-03-31 08:32:14.000000000 -0500
+++ linux-2.6.16.x86_64/kernel/auditsc.c 2006-03-31 08:55:33.000000000 -0500
@@ -107,7 +107,7 @@ struct audit_aux_data_ipcctl {
uid_t uid;
gid_t gid;
mode_t mode;
- char *ctx;
+ u32 osid;
};
struct audit_aux_data_socketcall {
@@ -457,11 +457,6 @@ static inline void audit_free_aux(struct
dput(axi->dentry);
mntput(axi->mnt);
}
- if ( aux->type == AUDIT_IPC ) {
- struct audit_aux_data_ipcctl *axi = (void *)aux;
- if (axi->ctx)
- kfree(axi->ctx);
- }
context->aux = aux->next;
kfree(aux);
@@ -612,7 +607,7 @@ static void audit_log_task_info(struct a
static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
{
- int i;
+ int i, call_panic = 0;
struct audit_buffer *ab;
struct audit_aux_data *aux;
const char *tty;
@@ -661,8 +656,20 @@ static void audit_log_exit(struct audit_
case AUDIT_IPC: {
struct audit_aux_data_ipcctl *axi = (void *)aux;
audit_log_format(ab,
- " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s",
- axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx);
+ " qbytes=%lx iuid=%u igid=%u mode=%x",
+ axi->qbytes, axi->uid, axi->gid, axi->mode);
+ if (axi->osid != 0) {
+ char *ctx = NULL;
+ u32 len;
+ if (selinux_ctxid_to_string(
+ axi->osid, &ctx, &len)) {
+ audit_log_format(ab, " obj=%u",
+ axi->osid);
+ call_panic = 1;
+ } else
+ audit_log_format(ab, " obj=%s", ctx);
+ kfree(ctx);
+ }
break; }
case AUDIT_SOCKETCALL: {
@@ -697,7 +704,6 @@ static void audit_log_exit(struct audit_
}
}
for (i = 0; i < context->name_count; i++) {
- int call_panic = 0;
unsigned long ino = context->names[i].ino;
unsigned long pino = context->names[i].pino;
@@ -734,16 +740,16 @@ static void audit_log_exit(struct audit_
context->names[i].osid, &ctx, &len)) {
audit_log_format(ab, " obj=%u",
context->names[i].osid);
- call_panic = 1;
+ call_panic = 2;
} else
audit_log_format(ab, " obj=%s", ctx);
kfree(ctx);
}
audit_log_end(ab);
- if (call_panic)
- audit_panic("error converting sid to string");
}
+ if (call_panic)
+ audit_panic("error converting sid to string");
}
/**
@@ -988,7 +994,7 @@ void audit_putname(const char *name)
#endif
}
-void audit_inode_context(int idx, const struct inode *inode)
+static void audit_inode_context(int idx, const struct inode *inode)
{
struct audit_context *context = current->audit_context;
@@ -1161,38 +1167,6 @@ uid_t audit_get_loginuid(struct audit_co
return ctx ? ctx->loginuid : -1;
}
-static char *audit_ipc_context(struct kern_ipc_perm *ipcp)
-{
- struct audit_context *context = current->audit_context;
- char *ctx = NULL;
- int len = 0;
-
- if (likely(!context))
- return NULL;
-
- len = security_ipc_getsecurity(ipcp, NULL, 0);
- if (len == -EOPNOTSUPP)
- goto ret;
- if (len < 0)
- goto error_path;
-
- ctx = kmalloc(len, GFP_ATOMIC);
- if (!ctx)
- goto error_path;
-
- len = security_ipc_getsecurity(ipcp, ctx, len);
- if (len < 0)
- goto error_path;
-
- return ctx;
-
-error_path:
- kfree(ctx);
- audit_panic("error in audit_ipc_context");
-ret:
- return NULL;
-}
-
/**
* audit_ipc_perms - record audit data for ipc
* @qbytes: msgq bytes
@@ -1218,7 +1192,7 @@ int audit_ipc_perms(unsigned long qbytes
ax->uid = uid;
ax->gid = gid;
ax->mode = mode;
- ax->ctx = audit_ipc_context(ipcp);
+ selinux_get_ipc_sid(ipcp, &ax->osid);
ax->d.type = AUDIT_IPC;
ax->d.next = context->aux;
diff -urp linux-2.6.16.x86_64.orig/security/dummy.c linux-2.6.16.x86_64/security/dummy.c
--- linux-2.6.16.x86_64.orig/security/dummy.c 2006-03-31 08:32:15.000000000 -0500
+++ linux-2.6.16.x86_64/security/dummy.c 2006-03-31 11:51:09.000000000 -0500
@@ -563,11 +563,6 @@ static int dummy_ipc_permission (struct
return 0;
}
-static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
-{
- return -EOPNOTSUPP;
-}
-
static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
{
return 0;
@@ -970,7 +965,6 @@ void security_fixup_ops (struct security
set_to_dummy_if_null(ops, task_reparent_to_init);
set_to_dummy_if_null(ops, task_to_inode);
set_to_dummy_if_null(ops, ipc_permission);
- set_to_dummy_if_null(ops, ipc_getsecurity);
set_to_dummy_if_null(ops, msg_msg_alloc_security);
set_to_dummy_if_null(ops, msg_msg_free_security);
set_to_dummy_if_null(ops, msg_queue_alloc_security);
diff -urp linux-2.6.16.x86_64.orig/security/selinux/exports.c linux-2.6.16.x86_64/security/selinux/exports.c
--- linux-2.6.16.x86_64.orig/security/selinux/exports.c 2006-03-31 08:32:15.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/exports.c 2006-03-31 08:55:33.000000000 -0500
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/selinux.h>
#include <linux/fs.h>
+#include <linux/ipc.h>
#include "security.h"
#include "objsec.h"
@@ -50,3 +51,13 @@ void selinux_get_inode_sid(const struct
*sid = 0;
}
+void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid)
+{
+ if (selinux_enabled) {
+ struct ipc_security_struct *isec = ipcp->security;
+ *sid = isec->sid;
+ return;
+ }
+ *sid = 0;
+}
+
diff -urp linux-2.6.16.x86_64.orig/security/selinux/hooks.c linux-2.6.16.x86_64/security/selinux/hooks.c
--- linux-2.6.16.x86_64.orig/security/selinux/hooks.c 2006-03-31 08:32:15.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/hooks.c 2006-03-31 09:58:06.000000000 -0500
@@ -4016,13 +4016,6 @@ static int selinux_ipc_permission(struct
return ipc_has_perm(ipcp, av);
}
-static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
-{
- struct ipc_security_struct *isec = ipcp->security;
-
- return selinux_getsecurity(isec->sid, buffer, size);
-}
-
/* module stacking operations */
static int selinux_register_security (const char *name, struct security_operations *ops)
{
@@ -4285,7 +4278,6 @@ static struct security_operations selinu
.task_to_inode = selinux_task_to_inode,
.ipc_permission = selinux_ipc_permission,
- .ipc_getsecurity = selinux_ipc_getsecurity,
.msg_msg_alloc_security = selinux_msg_msg_alloc_security,
.msg_msg_free_security = selinux_msg_msg_free_security,
18 years, 9 months
moving audit_free() up into do_exit()
by Alexander Viro
If we want to get full information on syscalls that kill the caller
(exit, exit_group, anything oopsing), we really ought to move audit_free()
into do_exit(), just before the exit_mm() call there.
Impact: we'll generate records for such syscall when it's called
(and gets to the point of no return), not when the resulting zombie gets
reaped. If anyone has objections to that, yell _NOW_.
What we get is, among other things, accurate tty=, exe= and subj=
in such records. We also get much simpler locking, since now _all_
access to ->audit_context is done by process itself in a process-synchronous
context. We don't have to bother with atomic allocations on that path
either.
NOTE: it does change the moment when record is generated and if
something in userland depends on having it postponed until the time when
zombie gets reaped, we will have to change such userland code. I doubt
we have any such place, but that definitely needs an ACK from userland
side of things.
18 years, 9 months
[PATCH] change lspp inode auditing
by Steve Grubb
Hi,
This is a first draft patch to change the auditing of inodes for lspp.
Previously, we were gathering the context instead of the sid. Now in this patch,
we gather just the sid and convert to context only if an audit event is being
output. This patch makes no effort to account for policy_load. It also inserts
some functions that are likely going upstream via Se Linux kernel people. So,
that will need to be resolved before this patch is final. In any event its
good enough to test with. This patch brings the performance hit from
146% down to 11%. We need a similar patch for IPC syscall auditing.
-Steve
diff -urp linux-2.6.16.x86_64.orig/include/linux/selinux.h linux-2.6.16.x86_64/include/linux/selinux.h
--- linux-2.6.16.x86_64.orig/include/linux/selinux.h 2006-03-29 10:40:42.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/selinux.h 2006-03-29 10:27:06.000000000 -0500
@@ -13,6 +13,8 @@
#ifndef _LINUX_SELINUX_H
#define _LINUX_SELINUX_H
+#include <linux/fs.h>
+
struct selinux_audit_rule;
struct audit_context;
@@ -76,6 +78,26 @@ void selinux_audit_set_callback(int (*ca
*/
void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
+/**
+ * selinux_ctxid_to_string - map a security context ID to a string
+ * @ctxid: security context ID to be converted.
+ * @ctx: address of context string to be returned
+ * @ctxlen: length of returned context string.
+ *
+ * Returns 0 if successful, -errno if not. On success, the context
+ * string will be allocated internally, and the caller must call
+ * kfree() on it after use.
+ */
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
+
+/**
+ * selinux_get_inode_sid - get the inode's security context ID
+ * @inode: inode structure to get the sid from.
+ *
+ * Returns the sid if successful and 0 if unset
+ */
+u32 selinux_get_inode_sid(const struct inode *inode);
+
#else
static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -107,6 +129,18 @@ static inline void selinux_task_ctxid(st
*ctxid = 0;
}
+static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
+{
+ *ctx = NULL;
+ *ctxlen = 0;
+ return 0;
+}
+
+static inline u32 selinux_get_inode_sid(const struct inode *inode)
+{
+ return 0;
+}
+
#endif /* CONFIG_SECURITY_SELINUX */
#endif /* _LINUX_SELINUX_H */
diff -urp linux-2.6.16.x86_64.orig/kernel/auditsc.c linux-2.6.16.x86_64/kernel/auditsc.c
--- linux-2.6.16.x86_64.orig/kernel/auditsc.c 2006-03-29 10:40:48.000000000 -0500
+++ linux-2.6.16.x86_64/kernel/auditsc.c 2006-03-29 10:26:45.000000000 -0500
@@ -90,7 +90,7 @@ struct audit_names {
uid_t uid;
gid_t gid;
dev_t rdev;
- char *ctx;
+ u32 osid;
};
struct audit_aux_data {
@@ -435,9 +435,6 @@ static inline void audit_free_names(stru
#endif
for (i = 0; i < context->name_count; i++) {
- char *p = context->names[i].ctx;
- context->names[i].ctx = NULL;
- kfree(p);
if (context->names[i].name)
__putname(context->names[i].name);
}
@@ -729,9 +726,24 @@ static void audit_log_exit(struct audit_
context->names[i].gid,
MAJOR(context->names[i].rdev),
MINOR(context->names[i].rdev));
- if (context->names[i].ctx) {
- audit_log_format(ab, " obj=%s",
- context->names[i].ctx);
+ if (context->names[i].osid != 0) {
+ char *ctx = NULL;
+ int len = 0;
+ if (selinux_ctxid_to_string(
+ context->names[i].osid, &ctx, &len) == 0) {
+ ctx = kmalloc(len, gfp_mask);
+ if (ctx) {
+ selinux_ctxid_to_string(
+ context->names[i].osid,
+ &ctx, &len);
+ }
+ }
+ if (ctx)
+ audit_log_format(ab, " obj=%s", ctx);
+ else
+ audit_log_format(ab, " obj=%u",
+ context->names[i].osid);
+ kfree(ctx);
}
audit_log_end(ab);
@@ -983,37 +995,10 @@ void audit_putname(const char *name)
void audit_inode_context(int idx, const struct inode *inode)
{
struct audit_context *context = current->audit_context;
- const char *suffix = security_inode_xattr_getsuffix();
- char *ctx = NULL;
- int len = 0;
-
- if (!suffix)
- goto ret;
-
- len = security_inode_getsecurity(inode, suffix, NULL, 0, 0);
- if (len == -EOPNOTSUPP)
- goto ret;
- if (len < 0)
- goto error_path;
-
- ctx = kmalloc(len, GFP_KERNEL);
- if (!ctx)
- goto error_path;
-
- len = security_inode_getsecurity(inode, suffix, ctx, len, 0);
- if (len < 0)
- goto error_path;
-
- kfree(context->names[idx].ctx);
- context->names[idx].ctx = ctx;
- goto ret;
-
-error_path:
- if (ctx)
- kfree(ctx);
- audit_panic("error in audit_inode_context");
-ret:
- return;
+ if (security_inode_xattr_getsuffix())
+ context->names[idx].osid = selinux_get_inode_sid(inode);
+ else
+ context->names[idx].osid = 0;
}
diff -urp linux-2.6.16.x86_64.orig/security/selinux/exports.c linux-2.6.16.x86_64/security/selinux/exports.c
--- linux-2.6.16.x86_64.orig/security/selinux/exports.c 2006-03-29 10:40:51.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/exports.c 2006-03-29 10:26:45.000000000 -0500
@@ -26,3 +26,24 @@ void selinux_task_ctxid(struct task_stru
else
*ctxid = 0;
}
+
+extern int ss_initialized;
+
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
+{
+ if (ss_initialized)
+ return security_sid_to_context(ctxid, ctx, ctxlen);
+ else {
+ *ctx = NULL;
+ *ctxlen = 0;
+ }
+
+ return 0;
+}
+
+u32 selinux_get_inode_sid(const struct inode *inode)
+{
+ struct inode_security_struct *isec = inode->i_security;
+ return isec->sid;
+}
+
18 years, 9 months
RE: Linux-audit Digest, Vol 18, Issue 31 - Kernel level for RHEL4u2
by Palmer, Gary L.
RHEL4 update 2 is at 2.6.9-22.EL
-----Original Message-----
From: linux-audit-bounces(a)redhat.com
[mailto:linux-audit-bounces@redhat.com] On Behalf Of
linux-audit-request(a)redhat.com
Sent: Thursday, March 30, 2006 3:57 AM
To: linux-audit(a)redhat.com
Subject: Linux-audit Digest, Vol 18, Issue 31
Send Linux-audit mailing list submissions to
linux-audit(a)redhat.com
To subscribe or unsubscribe via the World Wide Web, visit
https://www.redhat.com/mailman/listinfo/linux-audit
or, via email, send a message with subject or body 'help' to
linux-audit-request(a)redhat.com
You can reach the person managing the list at
linux-audit-owner(a)redhat.com
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Linux-audit digest..."
Today's Topics:
1. Re: Error on stop (Steve Grubb)
2. [PATCH] change lspp inode auditing (Steve Grubb)
3. Re: [PATCH] change lspp inode auditing (Stephen Smalley)
4. Re: [PATCH] change lspp inode auditing (Steve Grubb)
5. Re: [PATCH] change lspp inode auditing (Serge E. Hallyn)
6. Re: [PATCH] change lspp inode auditing (Valdis.Kletnieks(a)vt.edu)
7. Re: [PATCH] change lspp inode auditing (Steve Grubb)
8. auditctl -l bug? (Michael C Thompson)
9. moving audit_free() up into do_exit() (Alexander Viro)
10. Re: moving audit_free() up into do_exit() (Steve Grubb)
11. Re: moving audit_free() up into do_exit() (Alexander Viro)
12. Re: moving audit_free() up into do_exit() (Alexander Viro)
----------------------------------------------------------------------
Message: 1
Date: Tue, 28 Mar 2006 19:31:30 -0500
From: Steve Grubb <sgrubb(a)redhat.com>
Subject: Re: Error on stop
To: linux-audit(a)redhat.com
Message-ID: <200603281931.30320.sgrubb(a)redhat.com>
Content-Type: text/plain; charset="utf-8"
On Tuesday 28 March 2006 18:23, Mont Rothstein wrote:
> I am on audit-1.0.12 is this still a bug in this version, and if it
is do I
> need to worry about it?
>
> My output from uname -a is:
>
> Linux rheles4rs1.forayadams.foray.com 2.6.9-11.EL #1 Fri May 20
18:17:57
> EDT 2005 i686 i686 i386 GNU/Linux
I think you need to be on the 2.6.9-.16.EL kernel at a minimum. Offhand
I
don't remember what's the current RHEL4 kernel, but you need to upgrade
kernels for it to work right.
-Steve
------------------------------
Message: 2
Date: Wed, 29 Mar 2006 13:28:42 -0500
From: Steve Grubb <sgrubb(a)redhat.com>
Subject: [PATCH] change lspp inode auditing
To: linux-audit(a)redhat.com
Cc: redhat-lspp(a)redhat.com
Message-ID: <200603291328.42394.sgrubb(a)redhat.com>
Content-Type: text/plain; charset="us-ascii"
Hi,
This is a first draft patch to change the auditing of inodes for lspp.
Previously, we were gathering the context instead of the sid. Now in
this patch,
we gather just the sid and convert to context only if an audit event is
being
output. This patch makes no effort to account for policy_load. It also
inserts
some functions that are likely going upstream via Se Linux kernel
people. So,
that will need to be resolved before this patch is final. In any event
its
good enough to test with. This patch brings the performance hit from
146% down to 11%. We need a similar patch for IPC syscall auditing.
-Steve
diff -urp linux-2.6.16.x86_64.orig/include/linux/selinux.h
linux-2.6.16.x86_64/include/linux/selinux.h
--- linux-2.6.16.x86_64.orig/include/linux/selinux.h 2006-03-29
10:40:42.000000000 -0500
+++ linux-2.6.16.x86_64/include/linux/selinux.h 2006-03-29
10:27:06.000000000 -0500
@@ -13,6 +13,8 @@
#ifndef _LINUX_SELINUX_H
#define _LINUX_SELINUX_H
+#include <linux/fs.h>
+
struct selinux_audit_rule;
struct audit_context;
@@ -76,6 +78,26 @@ void selinux_audit_set_callback(int (*ca
*/
void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
+/**
+ * selinux_ctxid_to_string - map a security context ID to a string
+ * @ctxid: security context ID to be converted.
+ * @ctx: address of context string to be returned
+ * @ctxlen: length of returned context string.
+ *
+ * Returns 0 if successful, -errno if not. On success, the
context
+ * string will be allocated internally, and the caller must call
+ * kfree() on it after use.
+ */
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
+
+/**
+ * selinux_get_inode_sid - get the inode's security context ID
+ * @inode: inode structure to get the sid from.
+ *
+ * Returns the sid if successful and 0 if unset
+ */
+u32 selinux_get_inode_sid(const struct inode *inode);
+
#else
static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -107,6 +129,18 @@ static inline void selinux_task_ctxid(st
*ctxid = 0;
}
+static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32
*ctxlen)
+{
+ *ctx = NULL;
+ *ctxlen = 0;
+ return 0;
+}
+
+static inline u32 selinux_get_inode_sid(const struct inode *inode)
+{
+ return 0;
+}
+
#endif /* CONFIG_SECURITY_SELINUX */
#endif /* _LINUX_SELINUX_H */
diff -urp linux-2.6.16.x86_64.orig/kernel/auditsc.c
linux-2.6.16.x86_64/kernel/auditsc.c
--- linux-2.6.16.x86_64.orig/kernel/auditsc.c 2006-03-29
10:40:48.000000000 -0500
+++ linux-2.6.16.x86_64/kernel/auditsc.c 2006-03-29
10:26:45.000000000 -0500
@@ -90,7 +90,7 @@ struct audit_names {
uid_t uid;
gid_t gid;
dev_t rdev;
- char *ctx;
+ u32 osid;
};
struct audit_aux_data {
@@ -435,9 +435,6 @@ static inline void audit_free_names(stru
#endif
for (i = 0; i < context->name_count; i++) {
- char *p = context->names[i].ctx;
- context->names[i].ctx = NULL;
- kfree(p);
if (context->names[i].name)
__putname(context->names[i].name);
}
@@ -729,9 +726,24 @@ static void audit_log_exit(struct audit_
context->names[i].gid,
MAJOR(context->names[i].rdev),
MINOR(context->names[i].rdev));
- if (context->names[i].ctx) {
- audit_log_format(ab, " obj=%s",
- context->names[i].ctx);
+ if (context->names[i].osid != 0) {
+ char *ctx = NULL;
+ int len = 0;
+ if (selinux_ctxid_to_string(
+ context->names[i].osid, &ctx, &len) ==
0) {
+ ctx = kmalloc(len, gfp_mask);
+ if (ctx) {
+ selinux_ctxid_to_string(
+ context->names[i].osid,
+ &ctx, &len);
+ }
+ }
+ if (ctx)
+ audit_log_format(ab, " obj=%s", ctx);
+ else
+ audit_log_format(ab, " obj=%u",
+
context->names[i].osid);
+ kfree(ctx);
}
audit_log_end(ab);
@@ -983,37 +995,10 @@ void audit_putname(const char *name)
void audit_inode_context(int idx, const struct inode *inode)
{
struct audit_context *context = current->audit_context;
- const char *suffix = security_inode_xattr_getsuffix();
- char *ctx = NULL;
- int len = 0;
-
- if (!suffix)
- goto ret;
-
- len = security_inode_getsecurity(inode, suffix, NULL, 0, 0);
- if (len == -EOPNOTSUPP)
- goto ret;
- if (len < 0)
- goto error_path;
-
- ctx = kmalloc(len, GFP_KERNEL);
- if (!ctx)
- goto error_path;
-
- len = security_inode_getsecurity(inode, suffix, ctx, len, 0);
- if (len < 0)
- goto error_path;
-
- kfree(context->names[idx].ctx);
- context->names[idx].ctx = ctx;
- goto ret;
-
-error_path:
- if (ctx)
- kfree(ctx);
- audit_panic("error in audit_inode_context");
-ret:
- return;
+ if (security_inode_xattr_getsuffix())
+ context->names[idx].osid =
selinux_get_inode_sid(inode);
+ else
+ context->names[idx].osid = 0;
}
diff -urp linux-2.6.16.x86_64.orig/security/selinux/exports.c
linux-2.6.16.x86_64/security/selinux/exports.c
--- linux-2.6.16.x86_64.orig/security/selinux/exports.c 2006-03-29
10:40:51.000000000 -0500
+++ linux-2.6.16.x86_64/security/selinux/exports.c 2006-03-29
10:26:45.000000000 -0500
@@ -26,3 +26,24 @@ void selinux_task_ctxid(struct task_stru
else
*ctxid = 0;
}
+
+extern int ss_initialized;
+
+int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
+{
+ if (ss_initialized)
+ return security_sid_to_context(ctxid, ctx, ctxlen);
+ else {
+ *ctx = NULL;
+ *ctxlen = 0;
+ }
+
+ return 0;
+}
+
+u32 selinux_get_inode_sid(const struct inode *inode)
+{
+ struct inode_security_struct *isec = inode->i_security;
+ return isec->sid;
+}
+
------------------------------
Message: 3
Date: Wed, 29 Mar 2006 14:01:22 -0500
From: Stephen Smalley <sds(a)tycho.nsa.gov>
Subject: Re: [PATCH] change lspp inode auditing
To: Steve Grubb <sgrubb(a)redhat.com>
Cc: redhat-lspp(a)redhat.com, linux-audit(a)redhat.com, James Morris
<jmorris(a)namei.org>
Message-ID: <1143658882.24555.59.camel(a)moss-spartans.epoch.ncsc.mil>
Content-Type: text/plain
On Wed, 2006-03-29 at 13:28 -0500, Steve Grubb wrote:
> Hi,
>
> This is a first draft patch to change the auditing of inodes for
lspp.
> Previously, we were gathering the context instead of the sid. Now in
this patch,
> we gather just the sid and convert to context only if an audit event
is being
> output. This patch makes no effort to account for policy_load. It
also inserts
> some functions that are likely going upstream via Se Linux kernel
people. So,
> that will need to be resolved before this patch is final. In any
event its
> good enough to test with. This patch brings the performance hit from
> 146% down to 11%. We need a similar patch for IPC syscall auditing.
Not that I disagree with this change in approach, but I think that when
it has come up in the past, there has been concern expressed about the
fact that we could end up not being able to generate the context from
the SID when the audit record is being emitted (due to OOM condition),
and the operation has already occurred at that point. Of course, there
are also other potential failure cases at the point, so I'm not sure it
is crucial, as long as audit_panic is called as appropriate. Just
wanted to make sure that this point was understood by everyone. But I
agree that pre-allocating the contexts is insane.
> diff -urp linux-2.6.16.x86_64.orig/include/linux/selinux.h
linux-2.6.16.x86_64/include/linux/selinux.h
> --- linux-2.6.16.x86_64.orig/include/linux/selinux.h 2006-03-29
10:40:42.000000000 -0500
> +++ linux-2.6.16.x86_64/include/linux/selinux.h 2006-03-29
10:27:06.000000000 -0500
> @@ -13,6 +13,8 @@
> #ifndef _LINUX_SELINUX_H
> #define _LINUX_SELINUX_H
>
> +#include <linux/fs.h>
Just put an empty decl for struct inode here, to avoid header
inter-dependencies:
struct inode;
> @@ -76,6 +78,26 @@ void selinux_audit_set_callback(int (*ca
> */
> void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
>
> +/**
> + * selinux_ctxid_to_string - map a security context ID to a
string
> + * @ctxid: security context ID to be converted.
> + * @ctx: address of context string to be returned
> + * @ctxlen: length of returned context string.
> + *
> + * Returns 0 if successful, -errno if not. On success, the
context
> + * string will be allocated internally, and the caller must call
> + * kfree() on it after use.
> + */
> +int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
Didn't Tim's patch for saving and auditing the netlink sender
SID/context have a similar interface, based on James' proposed API for
iptables? Just need to make sure that we settle on a single interface
used by them all. From later comments below, I think we'll want a
gfp_mask provided and I'm not sure we need the *ctxlen at all, as
SELinux handles the allocation internally.
> +/**
> + * selinux_get_inode_sid - get the inode's security context ID
> + * @inode: inode structure to get the sid from.
> + *
> + * Returns the sid if successful and 0 if unset
> + */
> +u32 selinux_get_inode_sid(const struct inode *inode);
I'd favor returning an int (0 == success, -errno for failure) and
providing the SID via pointer arg like other interfaces. Or if there
are no possible error cases, make it void, but still supply the SID via
argument.
> diff -urp linux-2.6.16.x86_64.orig/kernel/auditsc.c
linux-2.6.16.x86_64/kernel/auditsc.c
> --- linux-2.6.16.x86_64.orig/kernel/auditsc.c 2006-03-29
10:40:48.000000000 -0500
> +++ linux-2.6.16.x86_64/kernel/auditsc.c 2006-03-29
10:26:45.000000000 -0500
> @@ -729,9 +726,24 @@ static void audit_log_exit(struct audit_
> context->names[i].gid,
> MAJOR(context->names[i].rdev),
>
MINOR(context->names[i].rdev));
> - if (context->names[i].ctx) {
> - audit_log_format(ab, " obj=%s",
> - context->names[i].ctx);
> + if (context->names[i].osid != 0) {
> + char *ctx = NULL;
> + int len = 0;
> + if (selinux_ctxid_to_string(
> + context->names[i].osid, &ctx, &len) ==
0) {
> + ctx = kmalloc(len, gfp_mask);
> + if (ctx) {
> + selinux_ctxid_to_string(
> + context->names[i].osid,
> + &ctx, &len);
> + }
> + }
Unless I'm confused (quite possible ;), the above sequence shouldn't be
necessary and will actually leak the allocated buffer because SELinux
will overwrite the pointer with its own. The SELinux internal
functions
(e.g. security_sid_to_context) handle the allocation of a context
buffer
to the right size and set *ctx to it, so the caller never needs to play
this game. Some of the hook interfaces unfortunately require the
caller to guess and provide a buffer that they allocate, but I don't
think we want to continue that trend. SELinux should just set *ctx to
the context buffer it allocates and you are done. You should likely
pass the gfp_mask down into the SELinux interface and propagate it down
to the internal code so that we can conform with whatever the caller
needs.
> diff -urp linux-2.6.16.x86_64.orig/security/selinux/exports.c
linux-2.6.16.x86_64/security/selinux/exports.c
> --- linux-2.6.16.x86_64.orig/security/selinux/exports.c
2006-03-29 10:40:51.000000000 -0500
> +++ linux-2.6.16.x86_64/security/selinux/exports.c 2006-03-29
10:26:45.000000000 -0500
> +u32 selinux_get_inode_sid(const struct inode *inode)
> +{
> + struct inode_security_struct *isec = inode->i_security;
> + return isec->sid;
> +}
I think you need to check for selinux_enabled here, c.f. Darrel's
patches for audit-by-context. Keep in mind that SELinux can be runtime
disabled by init (if SELINUX=disabled in /etc/selinux/config).
--
Stephen Smalley
National Security Agency
------------------------------
Message: 4
Date: Wed, 29 Mar 2006 14:15:33 -0500
From: Steve Grubb <sgrubb(a)redhat.com>
Subject: Re: [PATCH] change lspp inode auditing
To: sds(a)tycho.nsa.gov
Cc: redhat-lspp(a)redhat.com, linux-audit(a)redhat.com, James Morris
<jmorris(a)namei.org>
Message-ID: <200603291415.33608.sgrubb(a)redhat.com>
Content-Type: text/plain; charset="utf-8"
On Wednesday 29 March 2006 14:01, Stephen Smalley wrote:
>> This patch brings the performance hit from 146% down to 11%. We need
a
>> similar patch for IPC syscall auditing.
>
> Not that I disagree with this change in approach, but I think that
when
> it has come up in the past, there has been concern expressed about
the
> fact that we could end up not being able to generate the context from
> the SID when the audit record is being emitted (due to OOM
condition),
> and the operation has already occurred at that point.
In that case, the patch writes out the sid number. Given a sid, is
there a way
to find it in the policy on disk? If not, that might be useful to have.
> Of course, there are also other potential failure cases at the point,
so I'm
> not sure it is crucial, as long as audit_panic is called as
> appropriate.
If we record the sid number, do we really need to call audit_panic?
> > @@ -76,6 +78,26 @@ void selinux_audit_set_callback(int (*ca
> > Â */
> > Â void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid);
> > Â
> > +/**
> > + * Â Â selinux_ctxid_to_string - map a security context ID to a
string
> > + * Â Â @ctxid: security context ID to be converted.
> > + * Â Â @ctx: address of context string to be returned
> > + * Â Â @ctxlen: length of returned context string.
> > + *
> > + * Â Â Returns 0 if successful, -errno if not. Â On success, the
context
> > + * Â Â string will be allocated internally, and the caller must
call
> > + * Â Â kfree() on it after use.
> > + */
> > +int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen);
>
> Didn't Tim's patch for saving and auditing the netlink sender
> SID/context have a similar interface, based on James' proposed API
for
> iptables?
Yes, I copy and pasted and changed the name based on a suggestion from
Darrel.
What is the status of that API? Did it go into 2.6.17 tree? I'd like to
code
to that API if it were available.
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â if (context->names[i].osid != 0) {
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â char *ctx = NULL;
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â int len = 0;
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if
(selinux_ctxid_to_string(
> >
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â context->nam
es[i].osid, &ctx, &len) == 0) {
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx =
kmalloc(len, gfp_mask);
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if (ctx)
{
> >
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
  selinux_ctxid_to_string(
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
   context->names[i].osid,
> >
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
          &ctx, &len);
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }
>
> Unless I'm confused (quite possible ;), the above sequence shouldn't
be
> necessary and will actually leak the allocated buffer because SELinux
> will overwrite the pointer with its own.
OK, will look into this.
> Some of the hook interfaces unfortunately require the caller to guess
and
> provide a buffer that they allocate, but I don't think we want to
continue
> that trend.
Agreed, that was messy.
I'll make changes as you suggested and we can try this again. Is there
a place
I can grab James' iptables SE Linux interface to patch the lspp kernel
with?
I'd like to use that if its accepted/done. It'll make merging Tim's
patch
easier.
-Steve
------------------------------
Message: 5
Date: Wed, 29 Mar 2006 13:18:35 -0600
From: "Serge E. Hallyn" <serue(a)us.ibm.com>
Subject: Re: [PATCH] change lspp inode auditing
To: Stephen Smalley <sds(a)tycho.nsa.gov>
Cc: redhat-lspp(a)redhat.com, James Morris <jmorris(a)namei.org>,
linux-audit(a)redhat.com
Message-ID: <20060329191835.GB30125(a)sergelap.austin.ibm.com>
Content-Type: text/plain; charset=us-ascii
Quoting Stephen Smalley (sds(a)tycho.nsa.gov):
> On Wed, 2006-03-29 at 13:28 -0500, Steve Grubb wrote:
> > Hi,
> >
> > This is a first draft patch to change the auditing of inodes for
lspp.
> > Previously, we were gathering the context instead of the sid. Now
in this patch,
> > we gather just the sid and convert to context only if an audit
event is being
> > output. This patch makes no effort to account for policy_load. It
also inserts
> > some functions that are likely going upstream via Se Linux kernel
people. So,
> > that will need to be resolved before this patch is final. In any
event its
> > good enough to test with. This patch brings the performance hit
from
> > 146% down to 11%. We need a similar patch for IPC syscall auditing.
>
> Not that I disagree with this change in approach, but I think that
when
> it has come up in the past, there has been concern expressed about
the
> fact that we could end up not being able to generate the context from
> the SID when the audit record is being emitted (due to OOM
condition),
> and the operation has already occurred at that point. Of course,
there
> are also other potential failure cases at the point, so I'm not sure
it
> is crucial, as long as audit_panic is called as appropriate. Just
> wanted to make sure that this point was understood by everyone. But
I
> agree that pre-allocating the contexts is insane.
Maybe this is a silly idea... but what about just somehow hashing on
(sid,policy_version), where uint policy_version is incremented on each
selinux policy load?
The audit code would fill in an entry for
au_ctx_hash(sid,policy_version),
if it isn't already filled in, when the context would previously have
been
preallocated. But it stores (sid, policy_version) in the audit record,
and grabs the value from the table when it's time to actually log the
entry, i.e. where Steve's current patch fills in the string.
I guess whether this is worth it depends on how likely we are to lose
information with this current patch on a live system.
Anyway, just a thought.
-serge
------------------------------
Message: 6
Date: Wed, 29 Mar 2006 14:34:19 -0500
From: Valdis.Kletnieks(a)vt.edu
Subject: Re: [PATCH] change lspp inode auditing
To: Steve Grubb <sgrubb(a)redhat.com>
Cc: redhat-lspp(a)redhat.com, linux-audit(a)redhat.com, James Morris
<jmorris(a)namei.org>
Message-ID: <200603291934.k2TJYJNu029217(a)turing-police.cc.vt.edu>
Content-Type: text/plain; charset="iso-8859-1"
On Wed, 29 Mar 2006 14:15:33 EST, Steve Grubb said:
> On Wednesday 29 March 2006 14:01, Stephen Smalley wrote:
> >> This patch brings the performance hit from 146% down to 11%. We
need a
> >> similar patch for IPC syscall auditing.
> >
> > Not that I disagree with this change in approach, but I think that
when
> > it has come up in the past, there has been concern expressed about
the
> > fact that we could end up not being able to generate the context
from
> > the SID when the audit record is being emitted (due to OOM
condition),
> > and the operation has already occurred at that point.
>
> In that case, the patch writes out the sid number. Given a sid, is
there a way
> to find it in the policy on disk? If not, that might be useful to
have.
The problem is that by the time you go to snarf it out of the policy on
disk,
it may no longer match the policy in effect at the time of the record
generation.
The hole probably isn't *that* bad if auditd is doing the grovelling.
It's almost
certainly an issue if ausearch is doing the correlation after the
fact....
18 years, 9 months
Format for multiple syscalss in a rule
by Mont Rothstein
The auditctl man page specifies that you may specify multiple syscalls in a
rule, but it doesn't show and I can't figure out the format for this.
Could someone please enlighten me? I am trying to audit all access to files
(read, write, remove). I believe all I need to do is audit open, write, and
rmdir in a single rule. I just can't figure out how to format it.
Thanks,
-Mont
18 years, 9 months
2.6.16-rc5-mm2 - yet another memory leak...
by Valdis.Kletnieks@vt.edu
Yet another leak - this time it seems to be the audit_socketcall()
in sys_socketcall().
When I did this, the laptop had been up for about 16 hours, with no network
connectivity. There were about 400K size-32 slab entries outstanding then - later
on it was well over 1.2M after some more uptime.
dmesg -s 16000000 | grep ' obj ' 1 | cut -f2 -d: | sort | uniq -c | sort -nr | head
199154 c02e72b2 <sys_socketcall+0x4d/0x186>
8412 c01da799 <cond_insertf+0xb5/0x10d>
4949 c01d5007 <ebitmap_read+0xc1/0x1ce>
2136 c01d52b2 <hashtab_insert+0x64/0xc3>
1873 c01d795f <policydb_read+0x2b9/0xbbe>
1454 c01d72ea <type_read+0x1e/0xde>
698 c01cf596 <selinux_file_alloc_security+0x25/0x47>
(Meta-question - why am I tripping over all these leaks?)
18 years, 9 months
auditd hanging the system...
by Valdis.Kletnieks@vt.edu
Running the Fedora devel tree as of a few days ago, and a 2.6.16-rc5-mm3 kernel.
Several times today, my laptop has seized up, with the 'disk activity' light
on solid. After 30 to 120 seconds, it returns. Some poking around after
the last hit finds this:
# ls -l /var/log/audit/
total 25423
-rw-r----- 1 root root 1799972 Mar 14 17:11 audit.log
-r--r----- 1 root root 5242905 Mar 14 17:06 audit.log.1
-r--r----- 1 root root 5242919 Mar 14 17:05 audit.log.2
-r--r----- 1 root root 5242943 Mar 14 15:11 audit.log.3
-r--r----- 1 root root 8388705 Oct 3 14:59 audit.log.4
Wow, something happened at 17:06 or so that caused it to roll through 5 meg of
audit in a minute. So let's take a look at it:
# ausearch -if /var/log/audit/audit.log.1 | uniq -c | more
1 ----
1 time->Wed Dec 31 19:00:00 1969
1526 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
2 type=SOCKETCALL msg=audit(0.000:272): nargs=3 a0=2 a1=2 a2=0
1 type=SYSCALL_PARTIAL msg=audit(0.000:272): success=yes exit=14 items=0 pid=9616 auid=967 uid=967 gid=967 euid=967 suid=967 fsuid=967 egid=967 sgid=967 fsgid=967 tty=(none) comm="gkrellm" exe="/usr/bin/gkrellm" subj=user_u:user_r:user_t:s0
1 type=AVC msg=audit(0.000:272): avc: denied { create } for pid=9616 comm="gkrellm" scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=udp_socket
1 ----
1 time->Wed Dec 31 19:00:00 1969
94 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
190 type=SOCKETCALL msg=audit(0.000:272): nargs=3 a0=2 a1=2 a2=0
1 ----
1 time->Wed Dec 31 19:00:00 1969
294 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
157 type=SOCKETCALL msg=audit(0.000:272): nargs=3 a0=2 a1=2 a2=0
1 ----
1 time->Wed Dec 31 19:00:00 1969
205 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
149 type=SOCKETCALL msg=audit(0.000:272): nargs=3 a0=2 a1=2 a2=0
1 ----
1 time->Wed Dec 31 19:00:00 1969
39 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
147 type=SOCKETCALL msg=audit(0.000:272): nargs=3 a0=2 a1=2 a2=0
1 ----
1 time->Wed Dec 31 19:00:00 1969
189 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
248 type=SOCKETCALL msg=audit(0.000:272): nargs=3 a0=2 a1=2 a2=0
<here we skip several hundred more of these>
1 ----
1 time->Wed Dec 31 19:00:00 1969
296 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 ----
1 time->Wed Dec 31 19:00:00 1969
1 type=AVC_PATH msg=audit(0.000:272): path="socket:[782960]"
1 type=SYSCALL_PARTIAL msg=audit(0.000:272): success=yes exit=0 items=0 pid=9616 auid=967 uid=967 gid=967 euid=967 suid=967 fsuid=967 egid=967 sgid=967 fsgid=967 tty=(none) comm="gkrellm" exe="/usr/bin/gkrellm" subj=user_u:user_r:user_t:s0
1 type=AVC msg=audit(0.000:272): avc: denied { ioctl } for pid=9616 comm="gkrellm" name="[782960]" dev=sockfs ino=782960 scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=udp_socket
1 ----
1 time->Wed Dec 31 19:00:00 1969
42 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 type=SOCKETCALL msg=audit(0.000:267): nargs=5 a0=b a1=1 a2=7 a3=bfb7a408 a4=4
1 type=SOCKETCALL msg=audit(0.000:267): nargs=5 a0=b a1=1 a2=8 a3=bfb7a408 a4=4
198 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=1 a1=1 a2=0
1 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=7 a1=bfb79c90 a2=27
1 type=SOCKADDR msg=audit(0.000:267): saddr=01002F746D702F616C73612D646D69782D393632352D313134323337313131372D373837303635
1 type=SOCKETCALL msg=audit(0.000:267): nargs=2 a0=7 a1=4
194 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 type=SOCKETCALL msg=audit(0.000:267): nargs=5 a0=7 a1=1 a2=7 a3=bfb7a468 a4=4
1 type=SOCKETCALL msg=audit(0.000:267): nargs=5 a0=7 a1=1 a2=8 a3=bfb7a468 a4=4
3 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
1 type=SOCKETCALL msg=audit(0.000:267): nargs=5 a0=7 a1=1 a2=7 a3=bfb7a408 a4=4
1 type=SOCKETCALL msg=audit(0.000:267): nargs=5 a0=7 a1=1 a2=8 a3=bfb7a408 a4=4
1 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=1 a1=1 a2=0
1 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=8 a1=bfb79c90 a2=27
1 type=SOCKADDR msg=audit(0.000:267): saddr=01002F746D702F616C73612D646D69782D393632352D313134323337313133322D383030303731
1 type=SOCKETCALL msg=audit(0.000:267): nargs=2 a0=8 a1=4
852 type=SOCKETCALL msg=audit(0.000:267): nargs=3 a0=4 a1=bfb7a4f8 a2=bfb7a4a0
Obviously looks like something is getting seriously stuck and replicating messages.
Plus, it looks like there's some basic info missing on the 'type=SOCKETCALL',
like the issuing process ID, etc....
18 years, 9 months