1 /* audit_fsnotify.c -- tracking inodes
3 * Copyright 2003-2009,2014-2015 Red Hat, Inc.
4 * Copyright 2005 Hewlett-Packard Development Company, L.P.
5 * Copyright 2005 IBM Corporation
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/kernel.h>
19 #include <linux/audit.h>
20 #include <linux/kthread.h>
21 #include <linux/mutex.h>
23 #include <linux/fsnotify_backend.h>
24 #include <linux/namei.h>
25 #include <linux/netlink.h>
26 #include <linux/sched.h>
27 #include <linux/slab.h>
28 #include <linux/security.h>
32 * this mark lives on the parent directory of the inode in question.
33 * but dev, ino, and path are about the child
35 struct audit_fsnotify_mark
{
36 dev_t dev
; /* associated superblock device */
37 unsigned long ino
; /* associated inode number */
38 char *path
; /* insertion path */
39 struct fsnotify_mark mark
; /* fsnotify mark on the inode */
40 struct audit_krule
*rule
;
43 /* fsnotify handle. */
44 static struct fsnotify_group
*audit_fsnotify_group
;
46 /* fsnotify events we care about. */
47 #define AUDIT_FS_EVENTS (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
48 FS_MOVE_SELF | FS_EVENT_ON_CHILD)
50 static void audit_fsnotify_mark_free(struct audit_fsnotify_mark
*audit_mark
)
52 kfree(audit_mark
->path
);
56 static void audit_fsnotify_free_mark(struct fsnotify_mark
*mark
)
58 struct audit_fsnotify_mark
*audit_mark
;
60 audit_mark
= container_of(mark
, struct audit_fsnotify_mark
, mark
);
61 audit_fsnotify_mark_free(audit_mark
);
64 char *audit_mark_path(struct audit_fsnotify_mark
*mark
)
69 int audit_mark_compare(struct audit_fsnotify_mark
*mark
, unsigned long ino
, dev_t dev
)
71 if (mark
->ino
== AUDIT_INO_UNSET
)
73 return (mark
->ino
== ino
) && (mark
->dev
== dev
);
76 static void audit_update_mark(struct audit_fsnotify_mark
*audit_mark
,
77 const struct inode
*inode
)
79 audit_mark
->dev
= inode
? inode
->i_sb
->s_dev
: AUDIT_DEV_UNSET
;
80 audit_mark
->ino
= inode
? inode
->i_ino
: AUDIT_INO_UNSET
;
83 struct audit_fsnotify_mark
*audit_alloc_mark(struct audit_krule
*krule
, char *pathname
, int len
)
85 struct audit_fsnotify_mark
*audit_mark
;
87 struct dentry
*dentry
;
91 if (pathname
[0] != '/' || pathname
[len
-1] == '/')
92 return ERR_PTR(-EINVAL
);
94 dentry
= kern_path_locked(pathname
, &path
);
96 return (void *)dentry
; /* returning an error */
97 inode
= path
.dentry
->d_inode
;
100 audit_mark
= kzalloc(sizeof(*audit_mark
), GFP_KERNEL
);
101 if (unlikely(!audit_mark
)) {
102 audit_mark
= ERR_PTR(-ENOMEM
);
106 fsnotify_init_mark(&audit_mark
->mark
, audit_fsnotify_group
);
107 audit_mark
->mark
.mask
= AUDIT_FS_EVENTS
;
108 audit_mark
->path
= pathname
;
109 audit_update_mark(audit_mark
, dentry
->d_inode
);
110 audit_mark
->rule
= krule
;
112 ret
= fsnotify_add_mark(&audit_mark
->mark
, inode
, NULL
, true);
114 fsnotify_put_mark(&audit_mark
->mark
);
115 audit_mark
= ERR_PTR(ret
);
123 static void audit_mark_log_rule_change(struct audit_fsnotify_mark
*audit_mark
, char *op
)
125 struct audit_buffer
*ab
;
126 struct audit_krule
*rule
= audit_mark
->rule
;
130 ab
= audit_log_start(NULL
, GFP_NOFS
, AUDIT_CONFIG_CHANGE
);
133 audit_log_format(ab
, "auid=%u ses=%u op=%s",
134 from_kuid(&init_user_ns
, audit_get_loginuid(current
)),
135 audit_get_sessionid(current
), op
);
136 audit_log_format(ab
, " path=");
137 audit_log_untrustedstring(ab
, audit_mark
->path
);
138 audit_log_key(ab
, rule
->filterkey
);
139 audit_log_format(ab
, " list=%d res=1", rule
->listnr
);
143 void audit_remove_mark(struct audit_fsnotify_mark
*audit_mark
)
145 fsnotify_destroy_mark(&audit_mark
->mark
, audit_fsnotify_group
);
146 fsnotify_put_mark(&audit_mark
->mark
);
149 void audit_remove_mark_rule(struct audit_krule
*krule
)
151 struct audit_fsnotify_mark
*mark
= krule
->exe
;
153 audit_remove_mark(mark
);
156 static void audit_autoremove_mark_rule(struct audit_fsnotify_mark
*audit_mark
)
158 struct audit_krule
*rule
= audit_mark
->rule
;
159 struct audit_entry
*entry
= container_of(rule
, struct audit_entry
, rule
);
161 audit_mark_log_rule_change(audit_mark
, "autoremove_rule");
162 audit_del_rule(entry
);
165 /* Update mark data in audit rules based on fsnotify events. */
166 static int audit_mark_handle_event(struct fsnotify_group
*group
,
167 struct inode
*to_tell
,
168 struct fsnotify_mark
*inode_mark
,
169 struct fsnotify_mark
*vfsmount_mark
,
170 u32 mask
, const void *data
, int data_type
,
171 const unsigned char *dname
, u32 cookie
,
172 struct fsnotify_iter_info
*iter_info
)
174 struct audit_fsnotify_mark
*audit_mark
;
175 const struct inode
*inode
= NULL
;
177 audit_mark
= container_of(inode_mark
, struct audit_fsnotify_mark
, mark
);
179 BUG_ON(group
!= audit_fsnotify_group
);
182 case (FSNOTIFY_EVENT_PATH
):
183 inode
= ((const struct path
*)data
)->dentry
->d_inode
;
185 case (FSNOTIFY_EVENT_INODE
):
186 inode
= (const struct inode
*)data
;
193 if (mask
& (FS_CREATE
|FS_MOVED_TO
|FS_DELETE
|FS_MOVED_FROM
)) {
194 if (audit_compare_dname_path(dname
, audit_mark
->path
, AUDIT_NAME_FULL
))
196 audit_update_mark(audit_mark
, inode
);
197 } else if (mask
& (FS_DELETE_SELF
|FS_UNMOUNT
|FS_MOVE_SELF
))
198 audit_autoremove_mark_rule(audit_mark
);
203 static const struct fsnotify_ops audit_mark_fsnotify_ops
= {
204 .handle_event
= audit_mark_handle_event
,
205 .free_mark
= audit_fsnotify_free_mark
,
208 static int __init
audit_fsnotify_init(void)
210 audit_fsnotify_group
= fsnotify_alloc_group(&audit_mark_fsnotify_ops
);
211 if (IS_ERR(audit_fsnotify_group
)) {
212 audit_fsnotify_group
= NULL
;
213 audit_panic("cannot create audit fsnotify group");
217 device_initcall(audit_fsnotify_init
);