Skip to content

Commit

Permalink
[PATCH] audit inode patch
Browse files Browse the repository at this point in the history
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 brings the performance hit from 146% down to 23%

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Steve Grubb authored and Al Viro committed May 1, 2006
1 parent 3dc7e31 commit 1b50eed
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 37 deletions.
34 changes: 34 additions & 0 deletions include/linux/selinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

struct selinux_audit_rule;
struct audit_context;
struct inode;

#ifdef CONFIG_SECURITY_SELINUX

Expand Down Expand Up @@ -76,6 +77,27 @@ void selinux_audit_set_callback(int (*callback)(void));
*/
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.
* @sid: pointer to security context ID to be filled in.
*
* Returns nothing
*/
void selinux_get_inode_sid(const struct inode *inode, u32 *sid);

#else

static inline int selinux_audit_rule_init(u32 field, u32 op,
Expand Down Expand Up @@ -107,6 +129,18 @@ static inline void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid)
*ctxid = 0;
}

static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
{
*ctx = NULL;
*ctxlen = 0;
return 0;
}

static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
{
*sid = 0;
}

#endif /* CONFIG_SECURITY_SELINUX */

#endif /* _LINUX_SELINUX_H */
53 changes: 16 additions & 37 deletions kernel/auditsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ struct audit_names {
uid_t uid;
gid_t gid;
dev_t rdev;
char *ctx;
u32 osid;
};

struct audit_aux_data {
Expand Down Expand Up @@ -410,9 +410,6 @@ static inline void audit_free_names(struct audit_context *context)
#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);
}
Expand Down Expand Up @@ -674,6 +671,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
}
}
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;

Expand Down Expand Up @@ -703,12 +701,22 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
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;
u32 len;
if (selinux_ctxid_to_string(
context->names[i].osid, &ctx, &len)) {
audit_log_format(ab, " obj=%u",
context->names[i].osid);
call_panic = 1;
} else
audit_log_format(ab, " obj=%s", ctx);
kfree(ctx);
}

audit_log_end(ab);
if (call_panic)
audit_panic("error converting sid to string");
}
}

Expand Down Expand Up @@ -946,37 +954,8 @@ 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;
selinux_get_inode_sid(inode, &context->names[idx].osid);
}


Expand Down
24 changes: 24 additions & 0 deletions security/selinux/exports.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/selinux.h>
#include <linux/fs.h>

#include "security.h"
#include "objsec.h"
Expand All @@ -26,3 +27,26 @@ void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid)
else
*ctxid = 0;
}

int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen)
{
if (selinux_enabled)
return security_sid_to_context(ctxid, ctx, ctxlen);
else {
*ctx = NULL;
*ctxlen = 0;
}

return 0;
}

void selinux_get_inode_sid(const struct inode *inode, u32 *sid)
{
if (selinux_enabled) {
struct inode_security_struct *isec = inode->i_security;
*sid = isec->sid;
return;
}
*sid = 0;
}

0 comments on commit 1b50eed

Please sign in to comment.