diff options
author | Amy Griffis <amy.griffis@hp.com> | 2006-07-13 13:16:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-08-03 10:50:30 -0400 |
commit | 73d3ec5abad3f1730ac8530899d2c14d92f3ad63 (patch) | |
tree | c2829a1e36ca155eecc7d4b8648fe9755247bec5 | |
parent | 3e2efce067cec0099f99ae59f28feda99b02b498 (diff) |
[PATCH] fix missed create event for directory audit
When an object is created via a symlink into an audited directory, audit misses
the event due to not having collected the inode data for the directory. Modify
__audit_inode_child() to copy the parent inode data if a parent wasn't found in
audit_names[].
Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namei.c | 2 | ||||
-rw-r--r-- | include/linux/audit.h | 8 | ||||
-rw-r--r-- | include/linux/fsnotify.h | 6 | ||||
-rw-r--r-- | kernel/auditsc.c | 16 |
4 files changed, 21 insertions, 11 deletions
diff --git a/fs/namei.c b/fs/namei.c index 47a7bad92d2a..0ab26cbdacc0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1357,7 +1357,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) | |||
1357 | return -ENOENT; | 1357 | return -ENOENT; |
1358 | 1358 | ||
1359 | BUG_ON(victim->d_parent->d_inode != dir); | 1359 | BUG_ON(victim->d_parent->d_inode != dir); |
1360 | audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino); | 1360 | audit_inode_child(victim->d_name.name, victim->d_inode, dir); |
1361 | 1361 | ||
1362 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); | 1362 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); |
1363 | if (error) | 1363 | if (error) |
diff --git a/include/linux/audit.h b/include/linux/audit.h index e7e5e5348987..bf196c05826c 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -327,7 +327,7 @@ extern void __audit_getname(const char *name); | |||
327 | extern void audit_putname(const char *name); | 327 | extern void audit_putname(const char *name); |
328 | extern void __audit_inode(const char *name, const struct inode *inode); | 328 | extern void __audit_inode(const char *name, const struct inode *inode); |
329 | extern void __audit_inode_child(const char *dname, const struct inode *inode, | 329 | extern void __audit_inode_child(const char *dname, const struct inode *inode, |
330 | unsigned long pino); | 330 | const struct inode *parent); |
331 | extern void __audit_inode_update(const struct inode *inode); | 331 | extern void __audit_inode_update(const struct inode *inode); |
332 | static inline void audit_getname(const char *name) | 332 | static inline void audit_getname(const char *name) |
333 | { | 333 | { |
@@ -339,10 +339,10 @@ static inline void audit_inode(const char *name, const struct inode *inode) { | |||
339 | __audit_inode(name, inode); | 339 | __audit_inode(name, inode); |
340 | } | 340 | } |
341 | static inline void audit_inode_child(const char *dname, | 341 | static inline void audit_inode_child(const char *dname, |
342 | const struct inode *inode, | 342 | const struct inode *inode, |
343 | unsigned long pino) { | 343 | const struct inode *parent) { |
344 | if (unlikely(current->audit_context)) | 344 | if (unlikely(current->audit_context)) |
345 | __audit_inode_child(dname, inode, pino); | 345 | __audit_inode_child(dname, inode, parent); |
346 | } | 346 | } |
347 | static inline void audit_inode_update(const struct inode *inode) { | 347 | static inline void audit_inode_update(const struct inode *inode) { |
348 | if (unlikely(current->audit_context)) | 348 | if (unlikely(current->audit_context)) |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index cc5dec70c32c..d4f219ffaa5d 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -67,7 +67,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, | |||
67 | if (source) { | 67 | if (source) { |
68 | inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); | 68 | inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); |
69 | } | 69 | } |
70 | audit_inode_child(new_name, source, new_dir->i_ino); | 70 | audit_inode_child(new_name, source, new_dir); |
71 | } | 71 | } |
72 | 72 | ||
73 | /* | 73 | /* |
@@ -98,7 +98,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | |||
98 | inode_dir_notify(inode, DN_CREATE); | 98 | inode_dir_notify(inode, DN_CREATE); |
99 | inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name, | 99 | inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name, |
100 | dentry->d_inode); | 100 | dentry->d_inode); |
101 | audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino); | 101 | audit_inode_child(dentry->d_name.name, dentry->d_inode, inode); |
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
@@ -109,7 +109,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
109 | inode_dir_notify(inode, DN_CREATE); | 109 | inode_dir_notify(inode, DN_CREATE); |
110 | inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, | 110 | inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, |
111 | dentry->d_name.name, dentry->d_inode); | 111 | dentry->d_name.name, dentry->d_inode); |
112 | audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino); | 112 | audit_inode_child(dentry->d_name.name, dentry->d_inode, inode); |
113 | } | 113 | } |
114 | 114 | ||
115 | /* | 115 | /* |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b939ed2da3ee..b1356fc63b26 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1251,7 +1251,7 @@ void __audit_inode(const char *name, const struct inode *inode) | |||
1251 | * audit_inode_child - collect inode info for created/removed objects | 1251 | * audit_inode_child - collect inode info for created/removed objects |
1252 | * @dname: inode's dentry name | 1252 | * @dname: inode's dentry name |
1253 | * @inode: inode being audited | 1253 | * @inode: inode being audited |
1254 | * @pino: inode number of dentry parent | 1254 | * @parent: inode of dentry parent |
1255 | * | 1255 | * |
1256 | * For syscalls that create or remove filesystem objects, audit_inode | 1256 | * For syscalls that create or remove filesystem objects, audit_inode |
1257 | * can only collect information for the filesystem object's parent. | 1257 | * can only collect information for the filesystem object's parent. |
@@ -1262,7 +1262,7 @@ void __audit_inode(const char *name, const struct inode *inode) | |||
1262 | * unsuccessful attempts. | 1262 | * unsuccessful attempts. |
1263 | */ | 1263 | */ |
1264 | void __audit_inode_child(const char *dname, const struct inode *inode, | 1264 | void __audit_inode_child(const char *dname, const struct inode *inode, |
1265 | unsigned long pino) | 1265 | const struct inode *parent) |
1266 | { | 1266 | { |
1267 | int idx; | 1267 | int idx; |
1268 | struct audit_context *context = current->audit_context; | 1268 | struct audit_context *context = current->audit_context; |
@@ -1276,7 +1276,7 @@ void __audit_inode_child(const char *dname, const struct inode *inode, | |||
1276 | if (!dname) | 1276 | if (!dname) |
1277 | goto update_context; | 1277 | goto update_context; |
1278 | for (idx = 0; idx < context->name_count; idx++) | 1278 | for (idx = 0; idx < context->name_count; idx++) |
1279 | if (context->names[idx].ino == pino) { | 1279 | if (context->names[idx].ino == parent->i_ino) { |
1280 | const char *name = context->names[idx].name; | 1280 | const char *name = context->names[idx].name; |
1281 | 1281 | ||
1282 | if (!name) | 1282 | if (!name) |
@@ -1304,6 +1304,16 @@ update_context: | |||
1304 | context->names[idx].ino = (unsigned long)-1; | 1304 | context->names[idx].ino = (unsigned long)-1; |
1305 | else | 1305 | else |
1306 | audit_copy_inode(&context->names[idx], inode); | 1306 | audit_copy_inode(&context->names[idx], inode); |
1307 | |||
1308 | /* A parent was not found in audit_names, so copy the inode data for the | ||
1309 | * provided parent. */ | ||
1310 | if (!found_name) { | ||
1311 | idx = context->name_count++; | ||
1312 | #if AUDIT_DEBUG | ||
1313 | context->ino_count++; | ||
1314 | #endif | ||
1315 | audit_copy_inode(&context->names[idx], parent); | ||
1316 | } | ||
1307 | } | 1317 | } |
1308 | 1318 | ||
1309 | /** | 1319 | /** |