On Mon, 2005-11-07 at 12:19 +0000, David Woodhouse wrote:
On Mon, 2005-11-07 at 13:00 +0100, Jiri Slaby wrote:
> There should be something like if (len == -EOPNOTSUPP) goto ret, where ret
> should be right before return NULL.
Yeah, that would seem to make sense.
> Or am I missing something? David, it's from your tree, do you have any
> comments, ideas?
At the moment I'm mostly just collecting patches in a repository for
those working in earnest on LSPP -- particularly when it comes to
selinux, I'm mostly clueless. Deferring to Dustin, whose code this is.
Ok, I've gotten to the bottom of this "audit on, selinux off" problem
and tested the fix. Attached is a patch against David's current git
tree.
The changes integrate:
- Jiri's suggested handling of EOPNOTSUPP. Avoids audit_panic() calls
in EOPNOTSUPP situations
- David's suggested correction of a couple of warnings (using the const
char* suffix assignment at the top of audit_inode_context())
- And the real reason why this kernel wouldn't boot when SELinux was
off... There was a missing dummy() function that should be stubbed in
and return NULL when SELinux is off.
Thanks for your help reporting this, Jiri. Our linux-audit mailing list
really should have shaken out this bug earlier.
:-Dustin
diff --git a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1121,7 +1121,7 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
- char *(*inode_xattr_getsuffix) (void);
+ const char *(*inode_xattr_getsuffix) (void);
int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t
size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value,
size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1301,13 +1301,16 @@ 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 (!security_inode_xattr_getsuffix())
- return;
+ if (!suffix)
+ goto ret;
- len = security_inode_getsecurity(inode, (char *)security_inode_xattr_getsuffix(), NULL,
0, 0);
+ len = security_inode_getsecurity(inode, suffix, NULL, 0, 0);
+ if (len == -EOPNOTSUPP)
+ goto ret;
if (len < 0)
goto error_path;
@@ -1315,17 +1318,18 @@ void audit_inode_context(int idx, const
if (!ctx)
goto error_path;
- len = security_inode_getsecurity(inode, (char *)security_inode_xattr_getsuffix(), ctx,
len, 0);
+ len = security_inode_getsecurity(inode, suffix, ctx, len, 0);
if (len < 0)
goto error_path;
context->names[idx].ctx = ctx;
- return;
+ goto ret;
error_path:
if (ctx)
kfree(ctx);
audit_panic("error in audit_inode_context");
+ret:
return;
}
@@ -1555,6 +1559,8 @@ char *audit_ipc_context(struct kern_ipc_
return NULL;
len = security_ipc_getsecurity(ipcp, NULL, 0);
+ if (len == -EOPNOTSUPP)
+ goto ret;
if (len < 0)
goto error_path;
@@ -1571,6 +1577,7 @@ char *audit_ipc_context(struct kern_ipc_
error_path:
kfree(ctx);
audit_panic("error in audit_ipc_context");
+ret:
return NULL;
}
diff --git a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -392,6 +392,11 @@ static int dummy_inode_listsecurity(stru
return 0;
}
+static const char *dummy_inode_xattr_getsuffix(void)
+{
+ return NULL;
+}
+
static int dummy_file_permission (struct file *file, int mask)
{
return 0;
@@ -895,6 +900,7 @@ void security_fixup_ops (struct security
set_to_dummy_if_null(ops, inode_getxattr);
set_to_dummy_if_null(ops, inode_listxattr);
set_to_dummy_if_null(ops, inode_removexattr);
+ set_to_dummy_if_null(ops, inode_xattr_getsuffix);
set_to_dummy_if_null(ops, inode_getsecurity);
set_to_dummy_if_null(ops, inode_setsecurity);
set_to_dummy_if_null(ops, inode_listsecurity);
--
Dustin Kirkland <dustin.kirkland(a)us.ibm.com>