aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-07-08 18:59:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 13:33:19 -0400
commit79f6530cb59e2a0af6953742a33cc29e98ca631c (patch)
tree3778b26699b0f217a3c888853faaf0e15c760fc2
parentf9f0a7d0dcbd19e9705e8b96a4b408f035e25c93 (diff)
audit: fix mq_open and mq_unlink to add the MQ root as a hidden parent audit_names record
The old audit PATH records for mq_open looked like this: type=PATH msg=audit(1366282323.982:869): item=1 name=(null) inode=6777 dev=00:0c mode=041777 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tmpfs_t:s15:c0.c1023 type=PATH msg=audit(1366282323.982:869): item=0 name="test_mq" inode=26732 dev=00:0c mode=0100700 ouid=0 ogid=0 rdev=00:00 obj=staff_u:object_r:user_tmpfs_t:s15:c0.c1023 ...with the audit related changes that went into 3.7, they now look like this: type=PATH msg=audit(1366282236.776:3606): item=2 name=(null) inode=66655 dev=00:0c mode=0100700 ouid=0 ogid=0 rdev=00:00 obj=staff_u:object_r:user_tmpfs_t:s15:c0.c1023 type=PATH msg=audit(1366282236.776:3606): item=1 name=(null) inode=6926 dev=00:0c mode=041777 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:tmpfs_t:s15:c0.c1023 type=PATH msg=audit(1366282236.776:3606): item=0 name="test_mq" Both of these look wrong to me. As Steve Grubb pointed out: "What we need is 1 PATH record that identifies the MQ. The other PATH records probably should not be there." Fix it to record the mq root as a parent, and flag it such that it should be hidden from view when the names are logged, since the root of the mq filesystem isn't terribly interesting. With this change, we get a single PATH record that looks more like this: type=PATH msg=audit(1368021604.836:484): item=0 name="test_mq" inode=16914 dev=00:0c mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:user_tmpfs_t:s0 In order to do this, a new audit_inode_parent_hidden() function is added. If we do it this way, then we avoid having the existing callers of audit_inode needing to do any sort of flag conversion if auditing is inactive. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reported-by: Jiri Jaburek <jjaburek@redhat.com> Cc: Steve Grubb <sgrubb@redhat.com> Cc: Eric Paris <eparis@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/audit.h26
-rw-r--r--ipc/mqueue.c2
-rw-r--r--kernel/audit.h1
-rw-r--r--kernel/auditsc.c12
4 files changed, 34 insertions, 7 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index b20b03852f21..729a4d165bcc 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -103,8 +103,11 @@ extern void __audit_syscall_exit(int ret_success, long ret_value);
103extern struct filename *__audit_reusename(const __user char *uptr); 103extern struct filename *__audit_reusename(const __user char *uptr);
104extern void __audit_getname(struct filename *name); 104extern void __audit_getname(struct filename *name);
105extern void audit_putname(struct filename *name); 105extern void audit_putname(struct filename *name);
106
107#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
108#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
106extern void __audit_inode(struct filename *name, const struct dentry *dentry, 109extern void __audit_inode(struct filename *name, const struct dentry *dentry,
107 unsigned int parent); 110 unsigned int flags);
108extern void __audit_inode_child(const struct inode *parent, 111extern void __audit_inode_child(const struct inode *parent,
109 const struct dentry *dentry, 112 const struct dentry *dentry,
110 const unsigned char type); 113 const unsigned char type);
@@ -148,10 +151,22 @@ static inline void audit_getname(struct filename *name)
148 if (unlikely(!audit_dummy_context())) 151 if (unlikely(!audit_dummy_context()))
149 __audit_getname(name); 152 __audit_getname(name);
150} 153}
151static inline void audit_inode(struct filename *name, const struct dentry *dentry, 154static inline void audit_inode(struct filename *name,
155 const struct dentry *dentry,
152 unsigned int parent) { 156 unsigned int parent) {
157 if (unlikely(!audit_dummy_context())) {
158 unsigned int flags = 0;
159 if (parent)
160 flags |= AUDIT_INODE_PARENT;
161 __audit_inode(name, dentry, flags);
162 }
163}
164static inline void audit_inode_parent_hidden(struct filename *name,
165 const struct dentry *dentry)
166{
153 if (unlikely(!audit_dummy_context())) 167 if (unlikely(!audit_dummy_context()))
154 __audit_inode(name, dentry, parent); 168 __audit_inode(name, dentry,
169 AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN);
155} 170}
156static inline void audit_inode_child(const struct inode *parent, 171static inline void audit_inode_child(const struct inode *parent,
157 const struct dentry *dentry, 172 const struct dentry *dentry,
@@ -311,7 +326,7 @@ static inline void audit_putname(struct filename *name)
311{ } 326{ }
312static inline void __audit_inode(struct filename *name, 327static inline void __audit_inode(struct filename *name,
313 const struct dentry *dentry, 328 const struct dentry *dentry,
314 unsigned int parent) 329 unsigned int flags)
315{ } 330{ }
316static inline void __audit_inode_child(const struct inode *parent, 331static inline void __audit_inode_child(const struct inode *parent,
317 const struct dentry *dentry, 332 const struct dentry *dentry,
@@ -321,6 +336,9 @@ static inline void audit_inode(struct filename *name,
321 const struct dentry *dentry, 336 const struct dentry *dentry,
322 unsigned int parent) 337 unsigned int parent)
323{ } 338{ }
339static inline void audit_inode_parent_hidden(struct filename *name,
340 const struct dentry *dentry)
341{ }
324static inline void audit_inode_child(const struct inode *parent, 342static inline void audit_inode_child(const struct inode *parent,
325 const struct dentry *dentry, 343 const struct dentry *dentry,
326 const unsigned char type) 344 const unsigned char type)
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index e4e47f647446..ae1996d3c539 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -823,6 +823,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
823 error = ro; 823 error = ro;
824 goto out; 824 goto out;
825 } 825 }
826 audit_inode_parent_hidden(name, root);
826 filp = do_create(ipc_ns, root->d_inode, 827 filp = do_create(ipc_ns, root->d_inode,
827 &path, oflag, mode, 828 &path, oflag, mode,
828 u_attr ? &attr : NULL); 829 u_attr ? &attr : NULL);
@@ -868,6 +869,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
868 if (IS_ERR(name)) 869 if (IS_ERR(name))
869 return PTR_ERR(name); 870 return PTR_ERR(name);
870 871
872 audit_inode_parent_hidden(name, mnt->mnt_root);
871 err = mnt_want_write(mnt); 873 err = mnt_want_write(mnt);
872 if (err) 874 if (err)
873 goto out_name; 875 goto out_name;
diff --git a/kernel/audit.h b/kernel/audit.h
index 1c95131ef760..123c9b7c3979 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -85,6 +85,7 @@ struct audit_names {
85 85
86 struct filename *name; 86 struct filename *name;
87 int name_len; /* number of chars to log */ 87 int name_len; /* number of chars to log */
88 bool hidden; /* don't log this record */
88 bool name_put; /* call __putname()? */ 89 bool name_put; /* call __putname()? */
89 90
90 unsigned long ino; 91 unsigned long ino;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 3c8a601324a2..9845cb32b60a 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1399,8 +1399,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
1399 } 1399 }
1400 1400
1401 i = 0; 1401 i = 0;
1402 list_for_each_entry(n, &context->names_list, list) 1402 list_for_each_entry(n, &context->names_list, list) {
1403 if (n->hidden)
1404 continue;
1403 audit_log_name(context, n, NULL, i++, &call_panic); 1405 audit_log_name(context, n, NULL, i++, &call_panic);
1406 }
1404 1407
1405 /* Send end of event record to help user space know we are finished */ 1408 /* Send end of event record to help user space know we are finished */
1406 ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); 1409 ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
@@ -1769,14 +1772,15 @@ void audit_putname(struct filename *name)
1769 * __audit_inode - store the inode and device from a lookup 1772 * __audit_inode - store the inode and device from a lookup
1770 * @name: name being audited 1773 * @name: name being audited
1771 * @dentry: dentry being audited 1774 * @dentry: dentry being audited
1772 * @parent: does this dentry represent the parent? 1775 * @flags: attributes for this particular entry
1773 */ 1776 */
1774void __audit_inode(struct filename *name, const struct dentry *dentry, 1777void __audit_inode(struct filename *name, const struct dentry *dentry,
1775 unsigned int parent) 1778 unsigned int flags)
1776{ 1779{
1777 struct audit_context *context = current->audit_context; 1780 struct audit_context *context = current->audit_context;
1778 const struct inode *inode = dentry->d_inode; 1781 const struct inode *inode = dentry->d_inode;
1779 struct audit_names *n; 1782 struct audit_names *n;
1783 bool parent = flags & AUDIT_INODE_PARENT;
1780 1784
1781 if (!context->in_syscall) 1785 if (!context->in_syscall)
1782 return; 1786 return;
@@ -1831,6 +1835,8 @@ out:
1831 if (parent) { 1835 if (parent) {
1832 n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL; 1836 n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
1833 n->type = AUDIT_TYPE_PARENT; 1837 n->type = AUDIT_TYPE_PARENT;
1838 if (flags & AUDIT_INODE_HIDDEN)
1839 n->hidden = true;
1834 } else { 1840 } else {
1835 n->name_len = AUDIT_NAME_FULL; 1841 n->name_len = AUDIT_NAME_FULL;
1836 n->type = AUDIT_TYPE_NORMAL; 1842 n->type = AUDIT_TYPE_NORMAL;