1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* audit_fsnotify.c -- tracking inodes
4 * Copyright 2003-2009,2014-2015 Red Hat, Inc.
5 * Copyright 2005 Hewlett-Packard Development Company, L.P.
6 * Copyright 2005 IBM Corporation
9 #include <linux/kernel.h>
10 #include <linux/audit.h>
11 #include <linux/kthread.h>
12 #include <linux/mutex.h>
14 #include <linux/fsnotify_backend.h>
15 #include <linux/namei.h>
16 #include <linux/netlink.h>
17 #include <linux/sched.h>
18 #include <linux/slab.h>
19 #include <linux/security.h>
23 * this mark lives on the parent directory of the inode in question.
24 * but dev, ino, and path are about the child
26 struct audit_fsnotify_mark
{
27 dev_t dev
; /* associated superblock device */
28 unsigned long ino
; /* associated inode number */
29 char *path
; /* insertion path */
30 struct fsnotify_mark mark
; /* fsnotify mark on the inode */
31 struct audit_krule
*rule
;
34 /* fsnotify handle. */
35 static struct fsnotify_group
*audit_fsnotify_group
;
37 /* fsnotify events we care about. */
38 #define AUDIT_FS_EVENTS (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
41 static void audit_fsnotify_mark_free(struct audit_fsnotify_mark
*audit_mark
)
43 kfree(audit_mark
->path
);
47 static void audit_fsnotify_free_mark(struct fsnotify_mark
*mark
)
49 struct audit_fsnotify_mark
*audit_mark
;
51 audit_mark
= container_of(mark
, struct audit_fsnotify_mark
, mark
);
52 audit_fsnotify_mark_free(audit_mark
);
55 char *audit_mark_path(struct audit_fsnotify_mark
*mark
)
60 int audit_mark_compare(struct audit_fsnotify_mark
*mark
, unsigned long ino
, dev_t dev
)
62 if (mark
->ino
== AUDIT_INO_UNSET
)
64 return (mark
->ino
== ino
) && (mark
->dev
== dev
);
67 static void audit_update_mark(struct audit_fsnotify_mark
*audit_mark
,
68 const struct inode
*inode
)
70 audit_mark
->dev
= inode
? inode
->i_sb
->s_dev
: AUDIT_DEV_UNSET
;
71 audit_mark
->ino
= inode
? inode
->i_ino
: AUDIT_INO_UNSET
;
74 struct audit_fsnotify_mark
*audit_alloc_mark(struct audit_krule
*krule
, char *pathname
, int len
)
76 struct audit_fsnotify_mark
*audit_mark
;
78 struct dentry
*dentry
;
82 if (pathname
[0] != '/' || pathname
[len
-1] == '/')
83 return ERR_PTR(-EINVAL
);
85 dentry
= kern_path_locked(pathname
, &path
);
87 return (void *)dentry
; /* returning an error */
88 inode
= path
.dentry
->d_inode
;
91 audit_mark
= kzalloc(sizeof(*audit_mark
), GFP_KERNEL
);
92 if (unlikely(!audit_mark
)) {
93 audit_mark
= ERR_PTR(-ENOMEM
);
97 fsnotify_init_mark(&audit_mark
->mark
, audit_fsnotify_group
);
98 audit_mark
->mark
.mask
= AUDIT_FS_EVENTS
;
99 audit_mark
->path
= pathname
;
100 audit_update_mark(audit_mark
, dentry
->d_inode
);
101 audit_mark
->rule
= krule
;
103 ret
= fsnotify_add_inode_mark(&audit_mark
->mark
, inode
, true);
105 fsnotify_put_mark(&audit_mark
->mark
);
106 audit_mark
= ERR_PTR(ret
);
114 static void audit_mark_log_rule_change(struct audit_fsnotify_mark
*audit_mark
, char *op
)
116 struct audit_buffer
*ab
;
117 struct audit_krule
*rule
= audit_mark
->rule
;
121 ab
= audit_log_start(audit_context(), GFP_NOFS
, AUDIT_CONFIG_CHANGE
);
124 audit_log_session_info(ab
);
125 audit_log_format(ab
, " op=%s path=", op
);
126 audit_log_untrustedstring(ab
, audit_mark
->path
);
127 audit_log_key(ab
, rule
->filterkey
);
128 audit_log_format(ab
, " list=%d res=1", rule
->listnr
);
132 void audit_remove_mark(struct audit_fsnotify_mark
*audit_mark
)
134 fsnotify_destroy_mark(&audit_mark
->mark
, audit_fsnotify_group
);
135 fsnotify_put_mark(&audit_mark
->mark
);
138 void audit_remove_mark_rule(struct audit_krule
*krule
)
140 struct audit_fsnotify_mark
*mark
= krule
->exe
;
142 audit_remove_mark(mark
);
145 static void audit_autoremove_mark_rule(struct audit_fsnotify_mark
*audit_mark
)
147 struct audit_krule
*rule
= audit_mark
->rule
;
148 struct audit_entry
*entry
= container_of(rule
, struct audit_entry
, rule
);
150 audit_mark_log_rule_change(audit_mark
, "autoremove_rule");
151 audit_del_rule(entry
);
154 /* Update mark data in audit rules based on fsnotify events. */
155 static int audit_mark_handle_event(struct fsnotify_mark
*inode_mark
, u32 mask
,
156 struct inode
*inode
, struct inode
*dir
,
157 const struct qstr
*dname
, u32 cookie
)
159 struct audit_fsnotify_mark
*audit_mark
;
161 audit_mark
= container_of(inode_mark
, struct audit_fsnotify_mark
, mark
);
163 if (WARN_ON_ONCE(inode_mark
->group
!= audit_fsnotify_group
) ||
164 WARN_ON_ONCE(!inode
))
167 if (mask
& (FS_CREATE
|FS_MOVED_TO
|FS_DELETE
|FS_MOVED_FROM
)) {
168 if (audit_compare_dname_path(dname
, audit_mark
->path
, AUDIT_NAME_FULL
))
170 audit_update_mark(audit_mark
, inode
);
171 } else if (mask
& (FS_DELETE_SELF
|FS_UNMOUNT
|FS_MOVE_SELF
)) {
172 audit_autoremove_mark_rule(audit_mark
);
178 static const struct fsnotify_ops audit_mark_fsnotify_ops
= {
179 .handle_inode_event
= audit_mark_handle_event
,
180 .free_mark
= audit_fsnotify_free_mark
,
183 static int __init
audit_fsnotify_init(void)
185 audit_fsnotify_group
= fsnotify_alloc_group(&audit_mark_fsnotify_ops
);
186 if (IS_ERR(audit_fsnotify_group
)) {
187 audit_fsnotify_group
= NULL
;
188 audit_panic("cannot create audit fsnotify group");
192 device_initcall(audit_fsnotify_init
);