* Stephen Smalley (sds(a)tycho.nsa.gov) wrote:
On Tue, 2005-02-22 at 09:54 -0800, Chris Wright wrote:
> The dev value is actually rdev. So it's not bogus if you're accessing,
> for example, /dev/hda1. Reasonable question whether that's both
> intentional and sufficient. Given namespace possibilities, I assumed
> that dev/ino pair was dumped to uniquely identify the object.
Yes, this looks like a bug to me in the audit code, particularly as the
existing filter code lets you filter based on rdev and ino (whereas I'd
expect you would want to filter based on a specific object identified by
(dev,ino) pair). Should path_lookup() be passing nd->dentry->d_inode-
>i_sb->s_dev to audit_inode() instead?
That's what I was thinking, Erich said he'd give the patch a test. I
kept rdev and added dev. But, from the perspective of the converstaion
we had in the other thread (re: supplemental groups), shouldn't the
security attributes of the object be dumped as well? Here's a patch to
try Erich, but I think I'll spin up another one to dump uid/gid too.
thanks,
-chris
===== kernel/auditsc.c 1.6 vs edited =====
--- 1.6/kernel/auditsc.c 2005-01-30 22:33:47 -08:00
+++ edited/kernel/auditsc.c 2005-02-24 11:10:04 -08:00
@@ -89,6 +89,7 @@ enum audit_state {
struct audit_names {
const char *name;
unsigned long ino;
+ dev_t dev;
dev_t rdev;
};
@@ -338,7 +339,7 @@ static int audit_filter_rules(struct tas
case AUDIT_DEVMAJOR:
if (ctx) {
for (j = 0; j < ctx->name_count; j++) {
- if (MAJOR(ctx->names[j].rdev)==value) {
+ if (MAJOR(ctx->names[j].dev)==value) {
++result;
break;
}
@@ -348,7 +349,7 @@ static int audit_filter_rules(struct tas
case AUDIT_DEVMINOR:
if (ctx) {
for (j = 0; j < ctx->name_count; j++) {
- if (MINOR(ctx->names[j].rdev)==value) {
+ if (MINOR(ctx->names[j].dev)==value) {
++result;
break;
}
@@ -620,8 +621,12 @@ static void audit_log_exit(struct audit_
context->names[i].ino);
/* FIXME: should use format_dev_t, but ab structure is
* opaque. */
- if (context->names[i].rdev != -1)
+ if (context->names[i].dev != -1)
audit_log_format(ab, " dev=%02x:%02x",
+ MAJOR(context->names[i].dev),
+ MINOR(context->names[i].dev));
+ if (context->names[i].rdev != -1)
+ audit_log_format(ab, " rdev=%02x:%02x",
MAJOR(context->names[i].rdev),
MINOR(context->names[i].rdev));
audit_log_end(ab);
@@ -812,6 +817,7 @@ void audit_getname(const char *name)
BUG_ON(context->name_count >= AUDIT_NAMES);
context->names[context->name_count].name = name;
context->names[context->name_count].ino = (unsigned long)-1;
+ context->names[context->name_count].dev = -1;
context->names[context->name_count].rdev = -1;
++context->name_count;
}
@@ -859,7 +865,7 @@ EXPORT_SYMBOL(audit_putname);
/* Store the inode and device from a lookup. Called from
* fs/namei.c:path_lookup(). */
-void audit_inode(const char *name, unsigned long ino, dev_t rdev)
+void audit_inode(const char *name, unsigned long ino, dev_t dev, dev_t rdev)
{
int idx;
struct audit_context *context = current->audit_context;
@@ -886,6 +892,7 @@ void audit_inode(const char *name, unsig
#endif
}
context->names[idx].ino = ino;
+ context->names[idx].dev = dev;
context->names[idx].rdev = rdev;
}
===== fs/namei.c 1.118 vs edited =====
--- 1.118/fs/namei.c 2005-01-20 21:00:21 -08:00
+++ edited/fs/namei.c 2005-02-24 11:02:46 -08:00
@@ -983,6 +983,7 @@ int fastcall path_lookup(const char *nam
&& nd && nd->dentry && nd->dentry->d_inode))
audit_inode(name,
nd->dentry->d_inode->i_ino,
+ nd->dentry->d_inode->i_sb->s_dev,
nd->dentry->d_inode->i_rdev);
return retval;
}
===== include/linux/audit.h 1.2 vs edited =====
--- 1.2/include/linux/audit.h 2005-01-30 22:33:47 -08:00
+++ edited/include/linux/audit.h 2005-02-24 10:58:24 -08:00
@@ -141,7 +141,7 @@ extern void audit_syscall_entry(struct t
extern void audit_syscall_exit(struct task_struct *task, int return_code);
extern void audit_getname(const char *name);
extern void audit_putname(const char *name);
-extern void audit_inode(const char *name, unsigned long ino, dev_t rdev);
+extern void audit_inode(const char *name, unsigned long ino, dev_t dev, dev_t rdev);
/* Private API (for audit.c only) */
extern int audit_receive_filter(int type, int pid, int uid, int seq,
@@ -157,7 +157,7 @@ extern uid_t audit_get_loginuid(struct a
#define audit_syscall_exit(t,r) do { ; } while (0)
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
-#define audit_inode(n,i,d) do { ; } while (0)
+#define audit_inode(n,i,d, r) do { ; } while (0)
#define audit_get_loginuid(c) ({ -1; })
#endif