diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/auditsc.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 0160a68b4d7f..d147585e9ef3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -2189,6 +2189,7 @@ out: | |||
| 2189 | * __audit_inode_child - collect inode info for created/removed objects | 2189 | * __audit_inode_child - collect inode info for created/removed objects |
| 2190 | * @parent: inode of dentry parent | 2190 | * @parent: inode of dentry parent |
| 2191 | * @dentry: dentry being audited | 2191 | * @dentry: dentry being audited |
| 2192 | * @type: AUDIT_TYPE_* value that we're looking for | ||
| 2192 | * | 2193 | * |
| 2193 | * For syscalls that create or remove filesystem objects, audit_inode | 2194 | * For syscalls that create or remove filesystem objects, audit_inode |
| 2194 | * can only collect information for the filesystem object's parent. | 2195 | * can only collect information for the filesystem object's parent. |
| @@ -2199,13 +2200,13 @@ out: | |||
| 2199 | * unsuccessful attempts. | 2200 | * unsuccessful attempts. |
| 2200 | */ | 2201 | */ |
| 2201 | void __audit_inode_child(const struct inode *parent, | 2202 | void __audit_inode_child(const struct inode *parent, |
| 2202 | const struct dentry *dentry) | 2203 | const struct dentry *dentry, |
| 2204 | const unsigned char type) | ||
| 2203 | { | 2205 | { |
| 2204 | struct audit_context *context = current->audit_context; | 2206 | struct audit_context *context = current->audit_context; |
| 2205 | const char *found_parent = NULL, *found_child = NULL; | ||
| 2206 | const struct inode *inode = dentry->d_inode; | 2207 | const struct inode *inode = dentry->d_inode; |
| 2207 | const char *dname = dentry->d_name.name; | 2208 | const char *dname = dentry->d_name.name; |
| 2208 | struct audit_names *n; | 2209 | struct audit_names *n, *found_parent = NULL, *found_child = NULL; |
| 2209 | 2210 | ||
| 2210 | if (!context->in_syscall) | 2211 | if (!context->in_syscall) |
| 2211 | return; | 2212 | return; |
| @@ -2213,63 +2214,65 @@ void __audit_inode_child(const struct inode *parent, | |||
| 2213 | if (inode) | 2214 | if (inode) |
| 2214 | handle_one(inode); | 2215 | handle_one(inode); |
| 2215 | 2216 | ||
| 2216 | /* parent is more likely, look for it first */ | 2217 | /* look for a parent entry first */ |
| 2217 | list_for_each_entry(n, &context->names_list, list) { | 2218 | list_for_each_entry(n, &context->names_list, list) { |
| 2218 | if (!n->name) | 2219 | if (!n->name || n->type != AUDIT_TYPE_PARENT) |
| 2219 | continue; | 2220 | continue; |
| 2220 | 2221 | ||
| 2221 | if (n->ino == parent->i_ino && | 2222 | if (n->ino == parent->i_ino && |
| 2222 | !audit_compare_dname_path(dname, n->name, n->name_len)) { | 2223 | !audit_compare_dname_path(dname, n->name, n->name_len)) { |
| 2223 | found_parent = n->name; | 2224 | found_parent = n; |
| 2224 | goto add_names; | 2225 | break; |
| 2225 | } | 2226 | } |
| 2226 | } | 2227 | } |
| 2227 | 2228 | ||
| 2228 | /* no matching parent, look for matching child */ | 2229 | /* is there a matching child entry? */ |
| 2229 | list_for_each_entry(n, &context->names_list, list) { | 2230 | list_for_each_entry(n, &context->names_list, list) { |
| 2230 | if (!n->name) | 2231 | /* can only match entries that have a name */ |
| 2232 | if (!n->name || n->type != type) | ||
| 2233 | continue; | ||
| 2234 | |||
| 2235 | /* if we found a parent, make sure this one is a child of it */ | ||
| 2236 | if (found_parent && (n->name != found_parent->name)) | ||
| 2231 | continue; | 2237 | continue; |
| 2232 | 2238 | ||
| 2233 | /* strcmp() is the more likely scenario */ | ||
| 2234 | if (!strcmp(dname, n->name) || | 2239 | if (!strcmp(dname, n->name) || |
| 2235 | !audit_compare_dname_path(dname, n->name, | 2240 | !audit_compare_dname_path(dname, n->name, |
| 2241 | found_parent ? | ||
| 2242 | found_parent->name_len : | ||
| 2236 | AUDIT_NAME_FULL)) { | 2243 | AUDIT_NAME_FULL)) { |
| 2237 | if (inode) | 2244 | found_child = n; |
| 2238 | audit_copy_inode(n, dentry, inode); | 2245 | break; |
| 2239 | else | ||
| 2240 | n->ino = (unsigned long)-1; | ||
| 2241 | n->type = AUDIT_TYPE_NORMAL; | ||
| 2242 | found_child = n->name; | ||
| 2243 | goto add_names; | ||
| 2244 | } | 2246 | } |
| 2245 | } | 2247 | } |
| 2246 | 2248 | ||
| 2247 | add_names: | ||
| 2248 | if (!found_parent) { | 2249 | if (!found_parent) { |
| 2249 | n = audit_alloc_name(context, AUDIT_TYPE_NORMAL); | 2250 | /* create a new, "anonymous" parent record */ |
| 2251 | n = audit_alloc_name(context, AUDIT_TYPE_PARENT); | ||
| 2250 | if (!n) | 2252 | if (!n) |
| 2251 | return; | 2253 | return; |
| 2252 | audit_copy_inode(n, NULL, parent); | 2254 | audit_copy_inode(n, NULL, parent); |
| 2253 | } | 2255 | } |
| 2254 | 2256 | ||
| 2255 | if (!found_child) { | 2257 | if (!found_child) { |
| 2256 | n = audit_alloc_name(context, AUDIT_TYPE_NORMAL); | 2258 | found_child = audit_alloc_name(context, type); |
| 2257 | if (!n) | 2259 | if (!found_child) |
| 2258 | return; | 2260 | return; |
| 2259 | 2261 | ||
| 2260 | /* Re-use the name belonging to the slot for a matching parent | 2262 | /* Re-use the name belonging to the slot for a matching parent |
| 2261 | * directory. All names for this context are relinquished in | 2263 | * directory. All names for this context are relinquished in |
| 2262 | * audit_free_names() */ | 2264 | * audit_free_names() */ |
| 2263 | if (found_parent) { | 2265 | if (found_parent) { |
| 2264 | n->name = found_parent; | 2266 | found_child->name = found_parent->name; |
| 2265 | n->name_len = AUDIT_NAME_FULL; | 2267 | found_child->name_len = AUDIT_NAME_FULL; |
| 2266 | /* don't call __putname() */ | 2268 | /* don't call __putname() */ |
| 2267 | n->name_put = false; | 2269 | found_child->name_put = false; |
| 2268 | } | 2270 | } |
| 2269 | |||
| 2270 | if (inode) | ||
| 2271 | audit_copy_inode(n, dentry, inode); | ||
| 2272 | } | 2271 | } |
| 2272 | if (inode) | ||
| 2273 | audit_copy_inode(found_child, dentry, inode); | ||
| 2274 | else | ||
| 2275 | found_child->ino = (unsigned long)-1; | ||
| 2273 | } | 2276 | } |
| 2274 | EXPORT_SYMBOL_GPL(__audit_inode_child); | 2277 | EXPORT_SYMBOL_GPL(__audit_inode_child); |
| 2275 | 2278 | ||
