diff options
author | Amy Griffis <amy.griffis@hp.com> | 2006-07-13 13:16:02 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-08-03 10:50:21 -0400 |
commit | 3e2efce067cec0099f99ae59f28feda99b02b498 (patch) | |
tree | 94577cb6cb7f223319bb89a805b2d6945d42632e /kernel/auditsc.c | |
parent | 46f5960fdbf359f0c75989854bbaebc1de7a1eb4 (diff) |
[PATCH] fix faulty inode data collection for open() with O_CREAT
When the specified path is an existing file or when it is a symlink, audit
collects the wrong inode number, which causes it to miss the open() event.
Adding a second hook to the open() path fixes this.
Also add audit_copy_inode() to consolidate some code.
Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index ae40ac8c39e7..b939ed2da3ee 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1199,14 +1199,18 @@ void audit_putname(const char *name) | |||
1199 | #endif | 1199 | #endif |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | static void audit_inode_context(int idx, const struct inode *inode) | 1202 | /* Copy inode data into an audit_names. */ |
1203 | static void audit_copy_inode(struct audit_names *name, const struct inode *inode) | ||
1203 | { | 1204 | { |
1204 | struct audit_context *context = current->audit_context; | 1205 | name->ino = inode->i_ino; |
1205 | 1206 | name->dev = inode->i_sb->s_dev; | |
1206 | selinux_get_inode_sid(inode, &context->names[idx].osid); | 1207 | name->mode = inode->i_mode; |
1208 | name->uid = inode->i_uid; | ||
1209 | name->gid = inode->i_gid; | ||
1210 | name->rdev = inode->i_rdev; | ||
1211 | selinux_get_inode_sid(inode, &name->osid); | ||
1207 | } | 1212 | } |
1208 | 1213 | ||
1209 | |||
1210 | /** | 1214 | /** |
1211 | * audit_inode - store the inode and device from a lookup | 1215 | * audit_inode - store the inode and device from a lookup |
1212 | * @name: name being audited | 1216 | * @name: name being audited |
@@ -1240,13 +1244,7 @@ void __audit_inode(const char *name, const struct inode *inode) | |||
1240 | ++context->ino_count; | 1244 | ++context->ino_count; |
1241 | #endif | 1245 | #endif |
1242 | } | 1246 | } |
1243 | context->names[idx].ino = inode->i_ino; | 1247 | audit_copy_inode(&context->names[idx], inode); |
1244 | context->names[idx].dev = inode->i_sb->s_dev; | ||
1245 | context->names[idx].mode = inode->i_mode; | ||
1246 | context->names[idx].uid = inode->i_uid; | ||
1247 | context->names[idx].gid = inode->i_gid; | ||
1248 | context->names[idx].rdev = inode->i_rdev; | ||
1249 | audit_inode_context(idx, inode); | ||
1250 | } | 1248 | } |
1251 | 1249 | ||
1252 | /** | 1250 | /** |
@@ -1302,16 +1300,37 @@ update_context: | |||
1302 | context->names[idx].name_len = AUDIT_NAME_FULL; | 1300 | context->names[idx].name_len = AUDIT_NAME_FULL; |
1303 | context->names[idx].name_put = 0; /* don't call __putname() */ | 1301 | context->names[idx].name_put = 0; /* don't call __putname() */ |
1304 | 1302 | ||
1305 | if (inode) { | 1303 | if (!inode) |
1306 | context->names[idx].ino = inode->i_ino; | 1304 | context->names[idx].ino = (unsigned long)-1; |
1307 | context->names[idx].dev = inode->i_sb->s_dev; | 1305 | else |
1308 | context->names[idx].mode = inode->i_mode; | 1306 | audit_copy_inode(&context->names[idx], inode); |
1309 | context->names[idx].uid = inode->i_uid; | 1307 | } |
1310 | context->names[idx].gid = inode->i_gid; | 1308 | |
1311 | context->names[idx].rdev = inode->i_rdev; | 1309 | /** |
1312 | audit_inode_context(idx, inode); | 1310 | * audit_inode_update - update inode info for last collected name |
1313 | } else | 1311 | * @inode: inode being audited |
1314 | context->names[idx].ino = (unsigned long)-1; | 1312 | * |
1313 | * When open() is called on an existing object with the O_CREAT flag, the inode | ||
1314 | * data audit initially collects is incorrect. This additional hook ensures | ||
1315 | * audit has the inode data for the actual object to be opened. | ||
1316 | */ | ||
1317 | void __audit_inode_update(const struct inode *inode) | ||
1318 | { | ||
1319 | struct audit_context *context = current->audit_context; | ||
1320 | int idx; | ||
1321 | |||
1322 | if (!context->in_syscall || !inode) | ||
1323 | return; | ||
1324 | |||
1325 | if (context->name_count == 0) { | ||
1326 | context->name_count++; | ||
1327 | #if AUDIT_DEBUG | ||
1328 | context->ino_count++; | ||
1329 | #endif | ||
1330 | } | ||
1331 | idx = context->name_count - 1; | ||
1332 | |||
1333 | audit_copy_inode(&context->names[idx], inode); | ||
1315 | } | 1334 | } |
1316 | 1335 | ||
1317 | /** | 1336 | /** |