From: Dustin Kirkland <dustin.kirkland(a)us.ibm.com>
Subject: [PATCH 1/1] audit: misc bug and warning fixes
This patch fixes a couple of bugs revealed in new features recently added to -mm1:
* fixes warnings due to inconsistent use of const struct inode *inode
* fixes bug that prevent a kernel from booting with audit on, and SELinux off
due to a missing function in security/dummy.c
* fixes a bug that throws spurious audit_panic() messages due to a missing return
just before an error_path label
* some reasonable house cleaning in audit_ipc_context(), audit_inode_context(), and
audit_log_task_context()
Signed-off-by: Dustin Kirkland <dustin.kirkland(a)us.ibm.com>
---
David-
This is a patch freshly generated against your current git tree. This
patch incorporates several minor changes that I've put on the list in
the past week (though not in canonical patch format). Once you give
this a look over, I'd appreciate you merging into your git tree soon.
Thanks,
:-Dustin
diff --git a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1121,8 +1121,8 @@ 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);
- int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t
size, int err);
+ const char *(*inode_xattr_getsuffix) (void);
+ int (*inode_getsecurity)(const 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);
@@ -1628,7 +1628,7 @@ static inline const char *security_inode
return security_ops->inode_xattr_getsuffix();
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void
*buffer, size_t size, int err)
+static inline int security_inode_getsecurity(const struct inode *inode, const char *name,
void *buffer, size_t size, int err)
{
if (unlikely (IS_PRIVATE (inode)))
return 0;
@@ -2280,7 +2280,7 @@ static inline const char *security_inode
return NULL ;
}
-static inline int security_inode_getsecurity(struct inode *inode, const char *name, void
*buffer, size_t size, int err)
+static inline int security_inode_getsecurity(const struct inode *inode, const char *name,
void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -888,21 +888,20 @@ static void audit_log_task_context(struc
}
ctx = kmalloc(len, GFP_KERNEL);
- if (!ctx) {
+ if (!ctx)
goto error_path;
- return;
- }
len = security_getprocattr(current, "current", ctx, len);
if (len < 0 )
goto error_path;
audit_log_format(ab, " subj=%s", ctx);
+ return;
error_path:
if (ctx)
kfree(ctx);
- audit_panic("security_getprocattr error in audit_log_task_context");
+ audit_panic("error in audit_log_task_context");
return;
}
@@ -1301,13 +1300,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 +1317,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 +1558,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 +1576,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
@@ -377,7 +377,7 @@ static int dummy_inode_removexattr (stru
return 0;
}
-static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer,
size_t size, int err)
+static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void
*buffer, size_t size, int err)
{
return -EOPNOTSUPP;
}
@@ -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);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2273,7 +2273,7 @@ static const char *selinux_inode_xattr_g
*
* Permission check is handled by selinux_inode_getxattr hook.
*/
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer,
size_t size, int err)
+static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void
*buffer, size_t size, int err)
{
struct inode_security_struct *isec = inode->i_security;