Skip to content

Commit bdd481f

Browse files
rprobainaintel-lab-lkp
authored andcommitted
audit: fix suffixed '/' filename matching in __audit_inode_child()
When the user specifies a directory to delete with the suffix '/', the audit record fails to collect the filename, resulting in the following logs: type=PATH msg=audit(10/30/2024 14:11:17.796:6304) : item=2 name=(null) type=PATH msg=audit(10/30/2024 14:11:17.796:6304) : item=1 name=(null) It happens because the value of the variables dname, and n->name->name in __audit_inode_child() differ only by the suffix '/'. This commit treats this corner case by cleaning the input and passing the correct filename to audit_compare_dname_path(). Steps to reproduce the issue: # auditctl -w /tmp $ mkdir /tmp/foo $ rm -r /tmp/foo/ or rmdir /tmp/foo/ # ausearch -i | grep PATH | tail -3 This patch is based on a GitHub patch/PR by user @hqh2010. linux-audit/audit-kernel#148 Signed-off-by: Ricardo Robaina <rrobaina@redhat.com>
1 parent 89282be commit bdd481f

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

kernel/auditsc.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2419,7 +2419,8 @@ void __audit_inode_child(struct inode *parent,
24192419
struct audit_names *n, *found_parent = NULL, *found_child = NULL;
24202420
struct audit_entry *e;
24212421
struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS];
2422-
int i;
2422+
int i, dlen, nlen;
2423+
char *fn = NULL;
24232424

24242425
if (context->context == AUDIT_CTX_UNUSED)
24252426
return;
@@ -2443,22 +2444,35 @@ void __audit_inode_child(struct inode *parent,
24432444
if (inode)
24442445
handle_one(inode);
24452446

2447+
dlen = strlen(dname->name);
24462448
/* look for a parent entry first */
24472449
list_for_each_entry(n, &context->names_list, list) {
24482450
if (!n->name ||
24492451
(n->type != AUDIT_TYPE_PARENT &&
24502452
n->type != AUDIT_TYPE_UNKNOWN))
24512453
continue;
24522454

2455+
/* special case, entry name has the sufix "/" */
2456+
nlen = strlen(n->name->name);
2457+
if (dname->name[dlen - 1] != '/' && n->name->name[nlen - 1] == '/') {
2458+
fn = kmalloc(PATH_MAX, GFP_KERNEL);
2459+
if (!fn) {
2460+
audit_panic("out of memory in __audit_inode_child()");
2461+
return;
2462+
}
2463+
strscpy(fn, n->name->name, nlen);
2464+
}
2465+
24532466
if (n->ino == parent->i_ino && n->dev == parent->i_sb->s_dev &&
24542467
!audit_compare_dname_path(dname,
2455-
n->name->name, n->name_len)) {
2468+
fn ? fn : n->name->name, n->name_len)) {
24562469
if (n->type == AUDIT_TYPE_UNKNOWN)
24572470
n->type = AUDIT_TYPE_PARENT;
24582471
found_parent = n;
24592472
break;
24602473
}
24612474
}
2475+
kfree(fn);
24622476

24632477
cond_resched();
24642478

0 commit comments

Comments
 (0)