From nobody Fri Jun 12 15:46:54 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 457CB3BD64E for ; Wed, 13 May 2026 21:48:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778708912; cv=none; b=LolccahHEAT5huepr9dgrAEyf5QvdbOTSfa9Trg0twzdLA5mhjHOxxSNouSYfK6fBfh3oa93lqW8nC3iDm+E2e3rl6aYtWFSkIJczkzXd6k6oIfltyuzc8II+FrpNkFuCZ3BdrvtGwcHDAZx16OLaPsBxFAuptYOIKdNkEQ2G14= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778708912; c=relaxed/simple; bh=uu+bktVHC//HeqT3EC+V/mJaCzeHvEil0EeIkn1suLc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=G2tz3p3Gb4lcvswzYn7EZRQYJBz8/d3qxH2XZkRXTiML91kub8vUTSrorJgw/HIFWn7xhGdWQDAWKNAkjqjbfjkf4aTRWM5g7PFpV11vF9IZXQzCVJUGsEWfc6lXLRrl+1xgZgTnOVn5OVQrJf8N/gQd/yB3kGU2GVIJivaaHOs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=J7TyRfuW; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="J7TyRfuW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778708910; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=paYre+lXXBmot/+mhqXIObNvV0JozfP0u0qd+2X1e58=; b=J7TyRfuWSKovBfKbBfIhwRkMT73/IwKRHxz8plOTXCVMZOMHmFaXaxA+hF2jEgYfjtWXuO Co+APNacv7+LcSiXNHGy71GVUjTXHFDIE1jNYfMyntON9ENu2j6TuIlm6B5WiG1ozetj4Q FnUv3EfK7IOC6qlBS5DOLKuw/ZtTHJA= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-184-dv6ZE3SdPe2iH0hh19xO-Q-1; Wed, 13 May 2026 17:48:26 -0400 X-MC-Unique: dv6ZE3SdPe2iH0hh19xO-Q-1 X-Mimecast-MFC-AGG-ID: dv6ZE3SdPe2iH0hh19xO-Q_1778708905 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C8A41195608F; Wed, 13 May 2026 21:48:25 +0000 (UTC) Received: from wsxc.redhat.com (unknown [10.96.134.76]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AFACC19560A2; Wed, 13 May 2026 21:48:22 +0000 (UTC) From: Ricardo Robaina To: audit@vger.kernel.org, linux-kernel@vger.kernel.org Cc: paul@paul-moore.com, eparis@redhat.com, rgb@redhat.com, longman@redhat.com, Ricardo Robaina Subject: [PATCH v2 1/2] audit: fix removal of dangling executable rules Date: Wed, 13 May 2026 18:47:59 -0300 Message-ID: <7f0a259c6e6b5a1da6578fb83b531276425aa030.1778704210.git.rrobaina@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" When an audited executable is deleted from the disk, its dentry becomes negative. Any later attempt to delete the associated audit rule will lead to audit_alloc_mark() encountering this negative dentry and immediately aborting, returning -ENOENT. This early abort prevents the subsystem from allocating the temporary fsnotify mark needed to construct the search key, meaning the kernel cannot find the existing rule in its own lists to delete it. This leaves a dangling rule in memory, resulting in the following error while attempting to delete the rule: # ./audit-dupe-exe-deadlock.sh No rules Error deleting rule (No such file or directory) There was an error while processing parameters # auditctl -l -a always,exit -S all -F exe=3D/tmp/file -F path=3D/tmp/file -F key=3Ddr # auditctl -D Error deleting rule (No such file or directory) There was an error while processing parameters This patch fixes this issue by removing the d_really_is_negative() check. By doing so, a dummy mark can be successfully generated for the deleted path, which allows the audit subsystem to properly match and flush the dangling rule. Fixes: 76a53de6f7ff ("VFS/audit: introduce kern_path_parent() for audit") Acked-by: Waiman Long Acked-by: Richard Guy Briggs Signed-off-by: Ricardo Robaina --- Changes in v2: - New patch order: now patch 1/2 (was 2/2 in v1) per maintainer feedback kernel/audit_fsnotify.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index 711454f9f724..ae0e75403f76 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -84,10 +84,6 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audi= t_krule *krule, char *pa dentry =3D kern_path_parent(pathname, &path); if (IS_ERR(dentry)) return ERR_CAST(dentry); /* returning an error */ - if (d_really_is_negative(dentry)) { - audit_mark =3D ERR_PTR(-ENOENT); - goto out; - } =20 audit_mark =3D kzalloc_obj(*audit_mark); if (unlikely(!audit_mark)) { --=20 2.53.0 From nobody Fri Jun 12 15:46:54 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67ADB26B742 for ; Wed, 13 May 2026 21:48:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778708922; cv=none; b=HkFPbFBP0ddJ/6Y/jWLBo++JSN041W1ci56EVjv21o4CSu6RrFJSSxgqmA68dsmGkpgMqFo7usIttiZqOLOiUDwTyrJb1AzjYy9bcahkX2QA/KI3RTPff120U1RkHok5pKqbZEDBd7b3GgQK77dHg+mzjgTvV4w5/8ub0JI/e+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778708922; c=relaxed/simple; bh=EsBIRk9HWMHJcPU/soKLqsfsag0QlM8aCJrVnURAges=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZIbIDZXj/QPFODSrm0cDK+1vNJl3C+/CJum91JXN75uohoMCOL4nn3vmmJljd/u2Hqsbt+kBkJnrAnXSnNL85DMQ4/ercw4bZHWI6T5ouAMcC9f0LRy/wnvCFqd+Cd+db3XG7r/LhkN3ThYqrd+XUck4HXpvtAiZ7CXOlyXl+RM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=eqm1ykQP; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="eqm1ykQP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778708919; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CrHUG5g46uKiSlRtzV6WZtWo/zfRtm+wd/ymeqXvZmw=; b=eqm1ykQPz/7R3LsMM1PXqLett0HAIYEtTTA/dTZGNVqiF+U1/ml3P1RpTWjvXbJJ9KjCaP 7ztjasSQdxPIXzvbYX5X15dSDjy+Z/0nWHks3/dSxAsrBLtM/mgrxCqfdPqH9qnSwYnxcB 5erfNvBjKAdmJJWCHhSCmY54EfSX0NE= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-694-4tGAg1zzMUStvgvkNQqQCw-1; Wed, 13 May 2026 17:48:36 -0400 X-MC-Unique: 4tGAg1zzMUStvgvkNQqQCw-1 X-Mimecast-MFC-AGG-ID: 4tGAg1zzMUStvgvkNQqQCw_1778708915 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 09AFD195604F; Wed, 13 May 2026 21:48:35 +0000 (UTC) Received: from wsxc.redhat.com (unknown [10.96.134.76]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 85F6619560A2; Wed, 13 May 2026 21:48:32 +0000 (UTC) From: Ricardo Robaina To: audit@vger.kernel.org, linux-kernel@vger.kernel.org Cc: paul@paul-moore.com, eparis@redhat.com, rgb@redhat.com, longman@redhat.com, Ricardo Robaina Subject: [PATCH v2 2/2] audit: fix recursive locking deadlock in audit_dupe_exe() Date: Wed, 13 May 2026 18:48:00 -0300 Message-ID: In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" A deadlock occurs in the audit subsystem when duplicating executable-related rules. When a file is moved (e.g., via do_renameat2()), the VFS layer locks the parent directory (I_MUTEX_PARENT), which synchronously triggers an fsnotify_move event. If an existing executable audit rule matches the file being moved, the audit subsystem catches this event and calls audit_dupe_exe() to duplicate the watch and update the rule. Then, audit_alloc_mark() would call kern_path_parent() to resolve the path, leading to a blind attempt to acquire the exact same I_MUTEX_PARENT lock already held by the task, resulting in the following recursive locking deadlock: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D WARNING: possible recursive locking detected 6.12.0-55.27.1.el10_0.x86_64+debug #1 Not tainted -------------------------------------------- mv/5099 is trying to acquire lock: ffff888132845358 (&inode->i_sb->s_type->i_mutex_dir_key/1){+.+.}-{3:3}, at: __kern_path_locked+0x10a/0x2f0 but task is already holding lock: ffff888132846b58 (&inode->i_sb->s_type->i_mutex_dir_key/1){+.+.}-{3:3}, at: lock_two_directories+0x13f/0x2b0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&inode->i_sb->s_type->i_mutex_dir_key/1); lock(&inode->i_sb->s_type->i_mutex_dir_key/1); *** DEADLOCK *** May be due to missing lock nesting notation 6 locks held by mv/5099: #0: ffff888112a9c440 (sb_writers#13) at: do_renameat2+0x34c/0xbc0 #1: ffff888112a9c790 (&type->s_vfs_rename_key#3) at: do_renameat2+0x415/0xbc0 #2: ffff888132846b58 (&inode->i_sb->s_type->i_mutex_dir_key/1) at: lock_two_directories+0x13f/0x2b0 #3: ffff888132845358 (&inode->i_sb->s_type->i_mutex_dir_key/5) at: lock_two_directories+0x175/0x2b0 #4: ffffffffb3a1fb10 (&fsnotify_mark_srcu) at: fsnotify+0x454/0x28a0 #5: ffffffffaf886230 (audit_filter_mutex) at: audit_update_watch+0x36/0x11e0 stack backtrace: Call Trace: dump_stack_lvl+0x6f/0xb0 print_deadlock_bug.cold+0xbd/0xca validate_chain+0x83a/0xf00 __lock_acquire+0xcac/0x1d20 lock_acquire.part.0+0x11b/0x360 down_write_nested+0x9f/0x230 __kern_path_locked+0x10a/0x2f0 kern_path_locked+0x26/0x40 audit_alloc_mark+0xfb/0x4f0 audit_dupe_exe+0x6c/0xe0 audit_dupe_rule+0x6c2/0xc00 audit_update_watch+0x4cc/0x11e0 audit_watch_handle_event+0x12c/0x1b0 send_to_group+0x5d0/0x8b0 fsnotify+0x615/0x28a0 fsnotify_move+0x1d8/0x630 vfs_rename+0xdcd/0x1df0 do_renameat2+0x9d4/0xbc0 __x64_sys_renameat+0x192/0x260 do_syscall_64+0x92/0x180 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f0491fe8c4e Code: 0f 1f 40 00 48 8b 15 c1 e1 16 00 f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 49 89 ca b8 08 01 00 00 0f 05 <48> 3d 00 f0 ff ff 77 0a c3 66 0f 1f 84 00 00 00 00 00 48 8b 15 89 RSP: 002b:00007ffc7210bf38 EFLAGS: 00000246 ORIG_RAX: 0000000000000108 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f0491fe8c4e RDX: 0000000000000003 RSI: 00007ffc7210e6c8 RDI: 00000000ffffff9c RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000001 R10: 00005575eb2dae2a R11: 0000000000000246 R12: 00005575eb2dae2a R13: 00007ffc7210e6c8 R14: 0000000000000003 R15: 00000000ffffff9c The aforementioned deadlock can be consistently reproduced by running the script below: audit-dupe-exe-deadlock.sh -------------------------- #!/bin/bash auditctl -D mkdir -p /tmp/foo touch /tmp/file auditctl -a always,exit -F exe=3D/tmp/file -F path=3D/tmp/file -S all -k dr mv /tmp/file /tmp/foo/file rm -Rf /tmp/foo This patch fixes the issue by introducing struct audit_watch_ctx to pass the fsnotify event context down to audit_alloc_mark(). By utilizing the already-resolved directory inode provided by the event, we bypass the kern_path_parent() path resolution entirely, safely avoiding the recursive lock. Furthermore, it explicitly allows duplicate fsnotify marks (allow_dups =3D 1) during the rename update, allowing the new rule's mark to safely coexist with the old rule's mark until the old rule is freed. ps.: this issue was identified and reproduced during a comprehensive code coverage analysis of the audit subsystem. The full report is available at the link below. Fixes: 34d99af52ad4 ("audit: implement audit by executable") Link: https://people.redhat.com/rrobaina/audit-code-coverage-analysis.pdf Acked-by: Waiman Long Acked-by: Richard Guy Briggs Signed-off-by: Ricardo Robaina --- Changes in v2: - New patch order: now patch 2/2 (was 1/2 in v1) per maintainer feedback - Refactored audit_alloc_mark() to use local dir/child inode variables, eliminating code duplication in the critical execution path - Unified fsnotify_add_inode_mark() call using allow_dups variable: allow_dups=3D0 for manual rule additions (ctx=3D=3DNULL, no duplicates al= lowed), allow_dups=3D1 for fsnotify events (ctx!=3DNULL, temporary coexistence du= ring rename operations) kernel/audit.h | 13 ++++++++++--- kernel/audit_fsnotify.c | 32 +++++++++++++++++++++++--------- kernel/audit_watch.c | 25 +++++++++++++++++-------- kernel/auditfilter.c | 9 +++++---- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/kernel/audit.h b/kernel/audit.h index ac81fa02bcd7..2f988f6257d2 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -256,8 +256,13 @@ extern int audit_del_rule(struct audit_entry *entry); extern void audit_free_rule_rcu(struct rcu_head *head); extern struct list_head audit_filter_list[]; =20 -extern struct audit_entry *audit_dupe_rule(struct audit_krule *old); +struct audit_watch_ctx { + struct inode *dir; + struct inode *child; +}; =20 +extern struct audit_entry *audit_dupe_rule(struct audit_krule *old, + struct audit_watch_ctx *ctx); extern void audit_log_d_path_exe(struct audit_buffer *ab, struct mm_struct *mm); =20 @@ -280,13 +285,15 @@ extern char *audit_watch_path(struct audit_watch *wat= ch); extern int audit_watch_compare(struct audit_watch *watch, u64 ino, dev_t d= ev); =20 extern struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *kr= ule, - char *pathname, int len); + char *pathname, int len, + struct audit_watch_ctx *ctx); extern char *audit_mark_path(struct audit_fsnotify_mark *mark); extern void audit_remove_mark(struct audit_fsnotify_mark *audit_mark); extern void audit_remove_mark_rule(struct audit_krule *krule); extern int audit_mark_compare(struct audit_fsnotify_mark *mark, u64 ino, dev_t dev); -extern int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old= ); +extern int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old, + struct audit_watch_ctx *ctx); extern int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark); =20 diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index ae0e75403f76..fa33d57e4320 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -71,19 +71,30 @@ static void audit_update_mark(struct audit_fsnotify_mar= k *audit_mark, audit_mark->ino =3D inode ? inode->i_ino : AUDIT_INO_UNSET; } =20 -struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, ch= ar *pathname, int len) +struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, ch= ar *pathname, + int len, struct audit_watch_ctx *ctx) { struct audit_fsnotify_mark *audit_mark; struct path path; struct dentry *dentry; - int ret; + struct inode *dir, *child; + int ret, allow_dups; =20 if (pathname[0] !=3D '/' || pathname[len-1] =3D=3D '/') return ERR_PTR(-EINVAL); =20 - dentry =3D kern_path_parent(pathname, &path); - if (IS_ERR(dentry)) - return ERR_CAST(dentry); /* returning an error */ + if (!ctx) { + dentry =3D kern_path_parent(pathname, &path); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); /* returning an error */ + dir =3D d_inode(path.dentry); + child =3D d_inode(dentry); + allow_dups =3D 0; + } else { + dir =3D ctx->dir; + child =3D ctx->child; + allow_dups =3D 1; + } =20 audit_mark =3D kzalloc_obj(*audit_mark); if (unlikely(!audit_mark)) { @@ -94,18 +105,21 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct au= dit_krule *krule, char *pa fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_group); audit_mark->mark.mask =3D AUDIT_FS_EVENTS; audit_mark->path =3D pathname; - audit_update_mark(audit_mark, dentry->d_inode); audit_mark->rule =3D krule; =20 - ret =3D fsnotify_add_inode_mark(&audit_mark->mark, path.dentry->d_inode, = 0); + audit_update_mark(audit_mark, child); + ret =3D fsnotify_add_inode_mark(&audit_mark->mark, dir, allow_dups); + if (ret < 0) { audit_mark->path =3D NULL; fsnotify_put_mark(&audit_mark->mark); audit_mark =3D ERR_PTR(ret); } out: - dput(dentry); - path_put(&path); + if (!ctx) { + dput(dentry); + path_put(&path); + } return audit_mark; } =20 diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 33577f0f54ef..2c72e13be42c 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -244,7 +244,8 @@ static void audit_watch_log_rule_change(struct audit_kr= ule *r, struct audit_watc /* Update inode info in audit rules based on filesystem event. */ static void audit_update_watch(struct audit_parent *parent, const struct qstr *dname, dev_t dev, - u64 ino, unsigned invalidating) + unsigned long ino, unsigned invalidating, + struct audit_watch_ctx *ctx) { struct audit_watch *owatch, *nwatch, *nextw; struct audit_krule *r, *nextr; @@ -280,7 +281,7 @@ static void audit_update_watch(struct audit_parent *par= ent, list_del(&oentry->rule.rlist); list_del_rcu(&oentry->list); =20 - nentry =3D audit_dupe_rule(&oentry->rule); + nentry =3D audit_dupe_rule(&oentry->rule, ctx); if (IS_ERR(nentry)) { list_del(&oentry->rule.list); audit_panic("error updating watch, removing"); @@ -479,10 +480,17 @@ static int audit_watch_handle_event(struct fsnotify_m= ark *inode_mark, u32 mask, if (WARN_ON_ONCE(inode_mark->group !=3D audit_watch_group)) return 0; =20 - if (mask & (FS_CREATE|FS_MOVED_TO) && inode) - audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0); - else if (mask & (FS_DELETE|FS_MOVED_FROM)) - audit_update_watch(parent, dname, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1); + if (mask & (FS_CREATE|FS_MOVED_TO) && inode) { + struct audit_watch_ctx ctx =3D { .dir =3D dir, .child =3D inode }; + + audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0, + &ctx); + } else if (mask & (FS_DELETE|FS_MOVED_FROM)) { + struct audit_watch_ctx ctx =3D { .dir =3D dir, .child =3D NULL }; + + audit_update_watch(parent, dname, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1, + &ctx); + } else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF)) audit_remove_parent_watches(parent); =20 @@ -505,7 +513,8 @@ static int __init audit_watch_init(void) } device_initcall(audit_watch_init); =20 -int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old) +int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old, + struct audit_watch_ctx *ctx) { struct audit_fsnotify_mark *audit_mark; char *pathname; @@ -514,7 +523,7 @@ int audit_dupe_exe(struct audit_krule *new, struct audi= t_krule *old) if (!pathname) return -ENOMEM; =20 - audit_mark =3D audit_alloc_mark(new, pathname, strlen(pathname)); + audit_mark =3D audit_alloc_mark(new, pathname, strlen(pathname), ctx); if (IS_ERR(audit_mark)) { kfree(pathname); return PTR_ERR(audit_mark); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 093425123f6c..587b46771fb9 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -589,7 +589,7 @@ static struct audit_entry *audit_data_to_entry(struct a= udit_rule_data *data, err =3D PTR_ERR(str); goto exit_free; } - audit_mark =3D audit_alloc_mark(&entry->rule, str, f_val); + audit_mark =3D audit_alloc_mark(&entry->rule, str, f_val, NULL); if (IS_ERR(audit_mark)) { kfree(str); err =3D PTR_ERR(audit_mark); @@ -816,7 +816,8 @@ static inline int audit_dupe_lsm_field(struct audit_fie= ld *df, * rule with the new rule in the filterlist, then free the old rule. * The rlist element is undefined; list manipulations are handled apart fr= om * the initial copy. */ -struct audit_entry *audit_dupe_rule(struct audit_krule *old) +struct audit_entry *audit_dupe_rule(struct audit_krule *old, + struct audit_watch_ctx *ctx) { u32 fcount =3D old->field_count; struct audit_entry *entry; @@ -875,7 +876,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule = *old) new->filterkey =3D fk; break; case AUDIT_EXE: - err =3D audit_dupe_exe(new, old); + err =3D audit_dupe_exe(new, old, ctx); break; } if (err) { @@ -1414,7 +1415,7 @@ static int update_lsm_rule(struct audit_krule *r) if (!security_audit_rule_known(r)) return 0; =20 - nentry =3D audit_dupe_rule(r); + nentry =3D audit_dupe_rule(r, NULL); if (entry->rule.exe) audit_remove_mark(entry->rule.exe); if (IS_ERR(nentry)) { --=20 2.53.0