]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
ec1fe13db99a07238924c4e01bb8ca9a542bea62
[thirdparty/kernel/stable-queue.git] /
1 From 79f6530cb59e2a0af6953742a33cc29e98ca631c Mon Sep 17 00:00:00 2001
2 From: Jeff Layton <jlayton@redhat.com>
3 Date: Mon, 8 Jul 2013 15:59:36 -0700
4 Subject: audit: fix mq_open and mq_unlink to add the MQ root as a hidden parent audit_names record
5
6 From: Jeff Layton <jlayton@redhat.com>
7
8 commit 79f6530cb59e2a0af6953742a33cc29e98ca631c upstream.
9
10 The old audit PATH records for mq_open looked like this:
11
12 type=PATH msg=audit(1366282323.982:869): item=1 name=(null) inode=6777
13 dev=00:0c mode=041777 ouid=0 ogid=0 rdev=00:00
14 obj=system_u:object_r:tmpfs_t:s15:c0.c1023
15 type=PATH msg=audit(1366282323.982:869): item=0 name="test_mq" inode=26732
16 dev=00:0c mode=0100700 ouid=0 ogid=0 rdev=00:00
17 obj=staff_u:object_r:user_tmpfs_t:s15:c0.c1023
18
19 ...with the audit related changes that went into 3.7, they now look like this:
20
21 type=PATH msg=audit(1366282236.776:3606): item=2 name=(null) inode=66655
22 dev=00:0c mode=0100700 ouid=0 ogid=0 rdev=00:00
23 obj=staff_u:object_r:user_tmpfs_t:s15:c0.c1023
24 type=PATH msg=audit(1366282236.776:3606): item=1 name=(null) inode=6926
25 dev=00:0c mode=041777 ouid=0 ogid=0 rdev=00:00
26 obj=system_u:object_r:tmpfs_t:s15:c0.c1023
27 type=PATH msg=audit(1366282236.776:3606): item=0 name="test_mq"
28
29 Both of these look wrong to me. As Steve Grubb pointed out:
30
31 "What we need is 1 PATH record that identifies the MQ. The other PATH
32 records probably should not be there."
33
34 Fix it to record the mq root as a parent, and flag it such that it
35 should be hidden from view when the names are logged, since the root of
36 the mq filesystem isn't terribly interesting. With this change, we get
37 a single PATH record that looks more like this:
38
39 type=PATH msg=audit(1368021604.836:484): item=0 name="test_mq" inode=16914
40 dev=00:0c mode=0100644 ouid=0 ogid=0 rdev=00:00
41 obj=unconfined_u:object_r:user_tmpfs_t:s0
42
43 In order to do this, a new audit_inode_parent_hidden() function is
44 added. If we do it this way, then we avoid having the existing callers
45 of audit_inode needing to do any sort of flag conversion if auditing is
46 inactive.
47
48 Signed-off-by: Jeff Layton <jlayton@redhat.com>
49 Reported-by: Jiri Jaburek <jjaburek@redhat.com>
50 Cc: Steve Grubb <sgrubb@redhat.com>
51 Cc: Eric Paris <eparis@redhat.com>
52 Cc: Al Viro <viro@zeniv.linux.org.uk>
53 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
54 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
55 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
56
57 ---
58 include/linux/audit.h | 26 ++++++++++++++++++++++----
59 ipc/mqueue.c | 2 ++
60 kernel/audit.h | 1 +
61 kernel/auditsc.c | 12 +++++++++---
62 4 files changed, 34 insertions(+), 7 deletions(-)
63
64 --- a/include/linux/audit.h
65 +++ b/include/linux/audit.h
66 @@ -103,8 +103,11 @@ extern void __audit_syscall_exit(int ret
67 extern struct filename *__audit_reusename(const __user char *uptr);
68 extern void __audit_getname(struct filename *name);
69 extern void audit_putname(struct filename *name);
70 +
71 +#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
72 +#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
73 extern void __audit_inode(struct filename *name, const struct dentry *dentry,
74 - unsigned int parent);
75 + unsigned int flags);
76 extern void __audit_inode_child(const struct inode *parent,
77 const struct dentry *dentry,
78 const unsigned char type);
79 @@ -148,10 +151,22 @@ static inline void audit_getname(struct
80 if (unlikely(!audit_dummy_context()))
81 __audit_getname(name);
82 }
83 -static inline void audit_inode(struct filename *name, const struct dentry *dentry,
84 +static inline void audit_inode(struct filename *name,
85 + const struct dentry *dentry,
86 unsigned int parent) {
87 + if (unlikely(!audit_dummy_context())) {
88 + unsigned int flags = 0;
89 + if (parent)
90 + flags |= AUDIT_INODE_PARENT;
91 + __audit_inode(name, dentry, flags);
92 + }
93 +}
94 +static inline void audit_inode_parent_hidden(struct filename *name,
95 + const struct dentry *dentry)
96 +{
97 if (unlikely(!audit_dummy_context()))
98 - __audit_inode(name, dentry, parent);
99 + __audit_inode(name, dentry,
100 + AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN);
101 }
102 static inline void audit_inode_child(const struct inode *parent,
103 const struct dentry *dentry,
104 @@ -311,7 +326,7 @@ static inline void audit_putname(struct
105 { }
106 static inline void __audit_inode(struct filename *name,
107 const struct dentry *dentry,
108 - unsigned int parent)
109 + unsigned int flags)
110 { }
111 static inline void __audit_inode_child(const struct inode *parent,
112 const struct dentry *dentry,
113 @@ -321,6 +336,9 @@ static inline void audit_inode(struct fi
114 const struct dentry *dentry,
115 unsigned int parent)
116 { }
117 +static inline void audit_inode_parent_hidden(struct filename *name,
118 + const struct dentry *dentry)
119 +{ }
120 static inline void audit_inode_child(const struct inode *parent,
121 const struct dentry *dentry,
122 const unsigned char type)
123 --- a/ipc/mqueue.c
124 +++ b/ipc/mqueue.c
125 @@ -823,6 +823,7 @@ SYSCALL_DEFINE4(mq_open, const char __us
126 error = ro;
127 goto out;
128 }
129 + audit_inode_parent_hidden(name, root);
130 filp = do_create(ipc_ns, root->d_inode,
131 &path, oflag, mode,
132 u_attr ? &attr : NULL);
133 @@ -868,6 +869,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __
134 if (IS_ERR(name))
135 return PTR_ERR(name);
136
137 + audit_inode_parent_hidden(name, mnt->mnt_root);
138 err = mnt_want_write(mnt);
139 if (err)
140 goto out_name;
141 --- a/kernel/audit.h
142 +++ b/kernel/audit.h
143 @@ -85,6 +85,7 @@ struct audit_names {
144
145 struct filename *name;
146 int name_len; /* number of chars to log */
147 + bool hidden; /* don't log this record */
148 bool name_put; /* call __putname()? */
149
150 unsigned long ino;
151 --- a/kernel/auditsc.c
152 +++ b/kernel/auditsc.c
153 @@ -1399,8 +1399,11 @@ static void audit_log_exit(struct audit_
154 }
155
156 i = 0;
157 - list_for_each_entry(n, &context->names_list, list)
158 + list_for_each_entry(n, &context->names_list, list) {
159 + if (n->hidden)
160 + continue;
161 audit_log_name(context, n, NULL, i++, &call_panic);
162 + }
163
164 /* Send end of event record to help user space know we are finished */
165 ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
166 @@ -1769,14 +1772,15 @@ void audit_putname(struct filename *name
167 * __audit_inode - store the inode and device from a lookup
168 * @name: name being audited
169 * @dentry: dentry being audited
170 - * @parent: does this dentry represent the parent?
171 + * @flags: attributes for this particular entry
172 */
173 void __audit_inode(struct filename *name, const struct dentry *dentry,
174 - unsigned int parent)
175 + unsigned int flags)
176 {
177 struct audit_context *context = current->audit_context;
178 const struct inode *inode = dentry->d_inode;
179 struct audit_names *n;
180 + bool parent = flags & AUDIT_INODE_PARENT;
181
182 if (!context->in_syscall)
183 return;
184 @@ -1831,6 +1835,8 @@ out:
185 if (parent) {
186 n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
187 n->type = AUDIT_TYPE_PARENT;
188 + if (flags & AUDIT_INODE_HIDDEN)
189 + n->hidden = true;
190 } else {
191 n->name_len = AUDIT_NAME_FULL;
192 n->type = AUDIT_TYPE_NORMAL;