xref: /openbmc/linux/kernel/audit_watch.c (revision b97d6790d03b763eca08847a9a5869a4291b9f9a)
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /* audit_watch.c -- watching inodes
3   *
4   * Copyright 2003-2009 Red Hat, Inc.
5   * Copyright 2005 Hewlett-Packard Development Company, L.P.
6   * Copyright 2005 IBM Corporation
7   */
8  
9  #include <linux/file.h>
10  #include <linux/kernel.h>
11  #include <linux/audit.h>
12  #include <linux/kthread.h>
13  #include <linux/mutex.h>
14  #include <linux/fs.h>
15  #include <linux/fsnotify_backend.h>
16  #include <linux/namei.h>
17  #include <linux/netlink.h>
18  #include <linux/refcount.h>
19  #include <linux/sched.h>
20  #include <linux/slab.h>
21  #include <linux/security.h>
22  #include "audit.h"
23  
24  /*
25   * Reference counting:
26   *
27   * audit_parent: lifetime is from audit_init_parent() to receipt of an FS_IGNORED
28   * 	event.  Each audit_watch holds a reference to its associated parent.
29   *
30   * audit_watch: if added to lists, lifetime is from audit_init_watch() to
31   * 	audit_remove_watch().  Additionally, an audit_watch may exist
32   * 	temporarily to assist in searching existing filter data.  Each
33   * 	audit_krule holds a reference to its associated watch.
34   */
35  
36  struct audit_watch {
37  	refcount_t		count;	/* reference count */
38  	dev_t			dev;	/* associated superblock device */
39  	char			*path;	/* insertion path */
40  	unsigned long		ino;	/* associated inode number */
41  	struct audit_parent	*parent; /* associated parent */
42  	struct list_head	wlist;	/* entry in parent->watches list */
43  	struct list_head	rules;	/* anchor for krule->rlist */
44  };
45  
46  struct audit_parent {
47  	struct list_head	watches; /* anchor for audit_watch->wlist */
48  	struct fsnotify_mark mark; /* fsnotify mark on the inode */
49  };
50  
51  /* fsnotify handle. */
52  static struct fsnotify_group *audit_watch_group;
53  
54  /* fsnotify events we care about. */
55  #define AUDIT_FS_WATCH (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
56  			FS_MOVE_SELF | FS_UNMOUNT)
57  
audit_free_parent(struct audit_parent * parent)58  static void audit_free_parent(struct audit_parent *parent)
59  {
60  	WARN_ON(!list_empty(&parent->watches));
61  	kfree(parent);
62  }
63  
audit_watch_free_mark(struct fsnotify_mark * entry)64  static void audit_watch_free_mark(struct fsnotify_mark *entry)
65  {
66  	struct audit_parent *parent;
67  
68  	parent = container_of(entry, struct audit_parent, mark);
69  	audit_free_parent(parent);
70  }
71  
audit_get_parent(struct audit_parent * parent)72  static void audit_get_parent(struct audit_parent *parent)
73  {
74  	if (likely(parent))
75  		fsnotify_get_mark(&parent->mark);
76  }
77  
audit_put_parent(struct audit_parent * parent)78  static void audit_put_parent(struct audit_parent *parent)
79  {
80  	if (likely(parent))
81  		fsnotify_put_mark(&parent->mark);
82  }
83  
84  /*
85   * Find and return the audit_parent on the given inode.  If found a reference
86   * is taken on this parent.
87   */
audit_find_parent(struct inode * inode)88  static inline struct audit_parent *audit_find_parent(struct inode *inode)
89  {
90  	struct audit_parent *parent = NULL;
91  	struct fsnotify_mark *entry;
92  
93  	entry = fsnotify_find_mark(&inode->i_fsnotify_marks, audit_watch_group);
94  	if (entry)
95  		parent = container_of(entry, struct audit_parent, mark);
96  
97  	return parent;
98  }
99  
audit_get_watch(struct audit_watch * watch)100  void audit_get_watch(struct audit_watch *watch)
101  {
102  	refcount_inc(&watch->count);
103  }
104  
audit_put_watch(struct audit_watch * watch)105  void audit_put_watch(struct audit_watch *watch)
106  {
107  	if (refcount_dec_and_test(&watch->count)) {
108  		WARN_ON(watch->parent);
109  		WARN_ON(!list_empty(&watch->rules));
110  		kfree(watch->path);
111  		kfree(watch);
112  	}
113  }
114  
audit_remove_watch(struct audit_watch * watch)115  static void audit_remove_watch(struct audit_watch *watch)
116  {
117  	list_del(&watch->wlist);
118  	audit_put_parent(watch->parent);
119  	watch->parent = NULL;
120  	audit_put_watch(watch); /* match initial get */
121  }
122  
audit_watch_path(struct audit_watch * watch)123  char *audit_watch_path(struct audit_watch *watch)
124  {
125  	return watch->path;
126  }
127  
audit_watch_compare(struct audit_watch * watch,unsigned long ino,dev_t dev)128  int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev_t dev)
129  {
130  	return (watch->ino != AUDIT_INO_UNSET) &&
131  		(watch->ino == ino) &&
132  		(watch->dev == dev);
133  }
134  
135  /* Initialize a parent watch entry. */
audit_init_parent(const struct path * path)136  static struct audit_parent *audit_init_parent(const struct path *path)
137  {
138  	struct inode *inode = d_backing_inode(path->dentry);
139  	struct audit_parent *parent;
140  	int ret;
141  
142  	parent = kzalloc(sizeof(*parent), GFP_KERNEL);
143  	if (unlikely(!parent))
144  		return ERR_PTR(-ENOMEM);
145  
146  	INIT_LIST_HEAD(&parent->watches);
147  
148  	fsnotify_init_mark(&parent->mark, audit_watch_group);
149  	parent->mark.mask = AUDIT_FS_WATCH;
150  	ret = fsnotify_add_inode_mark(&parent->mark, inode, 0);
151  	if (ret < 0) {
152  		audit_free_parent(parent);
153  		return ERR_PTR(ret);
154  	}
155  
156  	return parent;
157  }
158  
159  /* Initialize a watch entry. */
audit_init_watch(char * path)160  static struct audit_watch *audit_init_watch(char *path)
161  {
162  	struct audit_watch *watch;
163  
164  	watch = kzalloc(sizeof(*watch), GFP_KERNEL);
165  	if (unlikely(!watch))
166  		return ERR_PTR(-ENOMEM);
167  
168  	INIT_LIST_HEAD(&watch->rules);
169  	refcount_set(&watch->count, 1);
170  	watch->path = path;
171  	watch->dev = AUDIT_DEV_UNSET;
172  	watch->ino = AUDIT_INO_UNSET;
173  
174  	return watch;
175  }
176  
177  /* Translate a watch string to kernel representation. */
audit_to_watch(struct audit_krule * krule,char * path,int len,u32 op)178  int audit_to_watch(struct audit_krule *krule, char *path, int len, u32 op)
179  {
180  	struct audit_watch *watch;
181  
182  	if (!audit_watch_group)
183  		return -EOPNOTSUPP;
184  
185  	if (path[0] != '/' || path[len-1] == '/' ||
186  	    (krule->listnr != AUDIT_FILTER_EXIT &&
187  	     krule->listnr != AUDIT_FILTER_URING_EXIT) ||
188  	    op != Audit_equal ||
189  	    krule->inode_f || krule->watch || krule->tree)
190  		return -EINVAL;
191  
192  	watch = audit_init_watch(path);
193  	if (IS_ERR(watch))
194  		return PTR_ERR(watch);
195  
196  	krule->watch = watch;
197  
198  	return 0;
199  }
200  
201  /* Duplicate the given audit watch.  The new watch's rules list is initialized
202   * to an empty list and wlist is undefined. */
audit_dupe_watch(struct audit_watch * old)203  static struct audit_watch *audit_dupe_watch(struct audit_watch *old)
204  {
205  	char *path;
206  	struct audit_watch *new;
207  
208  	path = kstrdup(old->path, GFP_KERNEL);
209  	if (unlikely(!path))
210  		return ERR_PTR(-ENOMEM);
211  
212  	new = audit_init_watch(path);
213  	if (IS_ERR(new)) {
214  		kfree(path);
215  		goto out;
216  	}
217  
218  	new->dev = old->dev;
219  	new->ino = old->ino;
220  	audit_get_parent(old->parent);
221  	new->parent = old->parent;
222  
223  out:
224  	return new;
225  }
226  
audit_watch_log_rule_change(struct audit_krule * r,struct audit_watch * w,char * op)227  static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watch *w, char *op)
228  {
229  	struct audit_buffer *ab;
230  
231  	if (!audit_enabled)
232  		return;
233  	ab = audit_log_start(audit_context(), GFP_NOFS, AUDIT_CONFIG_CHANGE);
234  	if (!ab)
235  		return;
236  	audit_log_session_info(ab);
237  	audit_log_format(ab, "op=%s path=", op);
238  	audit_log_untrustedstring(ab, w->path);
239  	audit_log_key(ab, r->filterkey);
240  	audit_log_format(ab, " list=%d res=1", r->listnr);
241  	audit_log_end(ab);
242  }
243  
244  /* Update inode info in audit rules based on filesystem event. */
audit_update_watch(struct audit_parent * parent,const struct qstr * dname,dev_t dev,unsigned long ino,unsigned invalidating)245  static void audit_update_watch(struct audit_parent *parent,
246  			       const struct qstr *dname, dev_t dev,
247  			       unsigned long ino, unsigned invalidating)
248  {
249  	struct audit_watch *owatch, *nwatch, *nextw;
250  	struct audit_krule *r, *nextr;
251  	struct audit_entry *oentry, *nentry;
252  
253  	mutex_lock(&audit_filter_mutex);
254  	/* Run all of the watches on this parent looking for the one that
255  	 * matches the given dname */
256  	list_for_each_entry_safe(owatch, nextw, &parent->watches, wlist) {
257  		if (audit_compare_dname_path(dname, owatch->path,
258  					     AUDIT_NAME_FULL))
259  			continue;
260  
261  		/* If the update involves invalidating rules, do the inode-based
262  		 * filtering now, so we don't omit records. */
263  		if (invalidating && !audit_dummy_context())
264  			audit_filter_inodes(current, audit_context());
265  
266  		/* updating ino will likely change which audit_hash_list we
267  		 * are on so we need a new watch for the new list */
268  		nwatch = audit_dupe_watch(owatch);
269  		if (IS_ERR(nwatch)) {
270  			mutex_unlock(&audit_filter_mutex);
271  			audit_panic("error updating watch, skipping");
272  			return;
273  		}
274  		nwatch->dev = dev;
275  		nwatch->ino = ino;
276  
277  		list_for_each_entry_safe(r, nextr, &owatch->rules, rlist) {
278  
279  			oentry = container_of(r, struct audit_entry, rule);
280  			list_del(&oentry->rule.rlist);
281  			list_del_rcu(&oentry->list);
282  
283  			nentry = audit_dupe_rule(&oentry->rule);
284  			if (IS_ERR(nentry)) {
285  				list_del(&oentry->rule.list);
286  				audit_panic("error updating watch, removing");
287  			} else {
288  				int h = audit_hash_ino((u32)ino);
289  
290  				/*
291  				 * nentry->rule.watch == oentry->rule.watch so
292  				 * we must drop that reference and set it to our
293  				 * new watch.
294  				 */
295  				audit_put_watch(nentry->rule.watch);
296  				audit_get_watch(nwatch);
297  				nentry->rule.watch = nwatch;
298  				list_add(&nentry->rule.rlist, &nwatch->rules);
299  				list_add_rcu(&nentry->list, &audit_inode_hash[h]);
300  				list_replace(&oentry->rule.list,
301  					     &nentry->rule.list);
302  			}
303  			if (oentry->rule.exe)
304  				audit_remove_mark(oentry->rule.exe);
305  
306  			call_rcu(&oentry->rcu, audit_free_rule_rcu);
307  		}
308  
309  		audit_remove_watch(owatch);
310  		goto add_watch_to_parent; /* event applies to a single watch */
311  	}
312  	mutex_unlock(&audit_filter_mutex);
313  	return;
314  
315  add_watch_to_parent:
316  	list_add(&nwatch->wlist, &parent->watches);
317  	mutex_unlock(&audit_filter_mutex);
318  	return;
319  }
320  
321  /* Remove all watches & rules associated with a parent that is going away. */
audit_remove_parent_watches(struct audit_parent * parent)322  static void audit_remove_parent_watches(struct audit_parent *parent)
323  {
324  	struct audit_watch *w, *nextw;
325  	struct audit_krule *r, *nextr;
326  	struct audit_entry *e;
327  
328  	mutex_lock(&audit_filter_mutex);
329  	list_for_each_entry_safe(w, nextw, &parent->watches, wlist) {
330  		list_for_each_entry_safe(r, nextr, &w->rules, rlist) {
331  			e = container_of(r, struct audit_entry, rule);
332  			audit_watch_log_rule_change(r, w, "remove_rule");
333  			if (e->rule.exe)
334  				audit_remove_mark(e->rule.exe);
335  			list_del(&r->rlist);
336  			list_del(&r->list);
337  			list_del_rcu(&e->list);
338  			call_rcu(&e->rcu, audit_free_rule_rcu);
339  		}
340  		audit_remove_watch(w);
341  	}
342  	mutex_unlock(&audit_filter_mutex);
343  
344  	fsnotify_destroy_mark(&parent->mark, audit_watch_group);
345  }
346  
347  /* Get path information necessary for adding watches. */
audit_get_nd(struct audit_watch * watch,struct path * parent)348  static int audit_get_nd(struct audit_watch *watch, struct path *parent)
349  {
350  	struct dentry *d = kern_path_locked(watch->path, parent);
351  	if (IS_ERR(d))
352  		return PTR_ERR(d);
353  	if (d_is_positive(d)) {
354  		/* update watch filter fields */
355  		watch->dev = d->d_sb->s_dev;
356  		watch->ino = d_backing_inode(d)->i_ino;
357  	}
358  	inode_unlock(d_backing_inode(parent->dentry));
359  	dput(d);
360  	return 0;
361  }
362  
363  /* Associate the given rule with an existing parent.
364   * Caller must hold audit_filter_mutex. */
audit_add_to_parent(struct audit_krule * krule,struct audit_parent * parent)365  static void audit_add_to_parent(struct audit_krule *krule,
366  				struct audit_parent *parent)
367  {
368  	struct audit_watch *w, *watch = krule->watch;
369  	int watch_found = 0;
370  
371  	BUG_ON(!mutex_is_locked(&audit_filter_mutex));
372  
373  	list_for_each_entry(w, &parent->watches, wlist) {
374  		if (strcmp(watch->path, w->path))
375  			continue;
376  
377  		watch_found = 1;
378  
379  		/* put krule's ref to temporary watch */
380  		audit_put_watch(watch);
381  
382  		audit_get_watch(w);
383  		krule->watch = watch = w;
384  
385  		audit_put_parent(parent);
386  		break;
387  	}
388  
389  	if (!watch_found) {
390  		watch->parent = parent;
391  
392  		audit_get_watch(watch);
393  		list_add(&watch->wlist, &parent->watches);
394  	}
395  	list_add(&krule->rlist, &watch->rules);
396  }
397  
398  /* Find a matching watch entry, or add this one.
399   * Caller must hold audit_filter_mutex. */
audit_add_watch(struct audit_krule * krule,struct list_head ** list)400  int audit_add_watch(struct audit_krule *krule, struct list_head **list)
401  {
402  	struct audit_watch *watch = krule->watch;
403  	struct audit_parent *parent;
404  	struct path parent_path;
405  	int h, ret = 0;
406  
407  	/*
408  	 * When we will be calling audit_add_to_parent, krule->watch might have
409  	 * been updated and watch might have been freed.
410  	 * So we need to keep a reference of watch.
411  	 */
412  	audit_get_watch(watch);
413  
414  	mutex_unlock(&audit_filter_mutex);
415  
416  	/* Avoid calling path_lookup under audit_filter_mutex. */
417  	ret = audit_get_nd(watch, &parent_path);
418  
419  	/* caller expects mutex locked */
420  	mutex_lock(&audit_filter_mutex);
421  
422  	if (ret) {
423  		audit_put_watch(watch);
424  		return ret;
425  	}
426  
427  	/* either find an old parent or attach a new one */
428  	parent = audit_find_parent(d_backing_inode(parent_path.dentry));
429  	if (!parent) {
430  		parent = audit_init_parent(&parent_path);
431  		if (IS_ERR(parent)) {
432  			ret = PTR_ERR(parent);
433  			goto error;
434  		}
435  	}
436  
437  	audit_add_to_parent(krule, parent);
438  
439  	h = audit_hash_ino((u32)watch->ino);
440  	*list = &audit_inode_hash[h];
441  error:
442  	path_put(&parent_path);
443  	audit_put_watch(watch);
444  	return ret;
445  }
446  
audit_remove_watch_rule(struct audit_krule * krule)447  void audit_remove_watch_rule(struct audit_krule *krule)
448  {
449  	struct audit_watch *watch = krule->watch;
450  	struct audit_parent *parent = watch->parent;
451  
452  	list_del(&krule->rlist);
453  
454  	if (list_empty(&watch->rules)) {
455  		/*
456  		 * audit_remove_watch() drops our reference to 'parent' which
457  		 * can get freed. Grab our own reference to be safe.
458  		 */
459  		audit_get_parent(parent);
460  		audit_remove_watch(watch);
461  		if (list_empty(&parent->watches))
462  			fsnotify_destroy_mark(&parent->mark, audit_watch_group);
463  		audit_put_parent(parent);
464  	}
465  }
466  
467  /* Update watch data in audit rules based on fsnotify events. */
audit_watch_handle_event(struct fsnotify_mark * inode_mark,u32 mask,struct inode * inode,struct inode * dir,const struct qstr * dname,u32 cookie)468  static int audit_watch_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
469  				    struct inode *inode, struct inode *dir,
470  				    const struct qstr *dname, u32 cookie)
471  {
472  	struct audit_parent *parent;
473  
474  	parent = container_of(inode_mark, struct audit_parent, mark);
475  
476  	if (WARN_ON_ONCE(inode_mark->group != audit_watch_group))
477  		return 0;
478  
479  	if (mask & (FS_CREATE|FS_MOVED_TO) && inode)
480  		audit_update_watch(parent, dname, inode->i_sb->s_dev, inode->i_ino, 0);
481  	else if (mask & (FS_DELETE|FS_MOVED_FROM))
482  		audit_update_watch(parent, dname, AUDIT_DEV_UNSET, AUDIT_INO_UNSET, 1);
483  	else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF))
484  		audit_remove_parent_watches(parent);
485  
486  	return 0;
487  }
488  
489  static const struct fsnotify_ops audit_watch_fsnotify_ops = {
490  	.handle_inode_event =	audit_watch_handle_event,
491  	.free_mark =		audit_watch_free_mark,
492  };
493  
audit_watch_init(void)494  static int __init audit_watch_init(void)
495  {
496  	audit_watch_group = fsnotify_alloc_group(&audit_watch_fsnotify_ops, 0);
497  	if (IS_ERR(audit_watch_group)) {
498  		audit_watch_group = NULL;
499  		audit_panic("cannot create audit fsnotify group");
500  	}
501  	return 0;
502  }
503  device_initcall(audit_watch_init);
504  
audit_dupe_exe(struct audit_krule * new,struct audit_krule * old)505  int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old)
506  {
507  	struct audit_fsnotify_mark *audit_mark;
508  	char *pathname;
509  
510  	pathname = kstrdup(audit_mark_path(old->exe), GFP_KERNEL);
511  	if (!pathname)
512  		return -ENOMEM;
513  
514  	audit_mark = audit_alloc_mark(new, pathname, strlen(pathname));
515  	if (IS_ERR(audit_mark)) {
516  		kfree(pathname);
517  		return PTR_ERR(audit_mark);
518  	}
519  	new->exe = audit_mark;
520  
521  	return 0;
522  }
523  
audit_exe_compare(struct task_struct * tsk,struct audit_fsnotify_mark * mark)524  int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark)
525  {
526  	struct file *exe_file;
527  	unsigned long ino;
528  	dev_t dev;
529  
530  	/* only do exe filtering if we are recording @current events/records */
531  	if (tsk != current)
532  		return 0;
533  
534  	if (!current->mm)
535  		return 0;
536  	exe_file = get_mm_exe_file(current->mm);
537  	if (!exe_file)
538  		return 0;
539  	ino = file_inode(exe_file)->i_ino;
540  	dev = file_inode(exe_file)->i_sb->s_dev;
541  	fput(exe_file);
542  
543  	return audit_mark_compare(mark, ino, dev);
544  }
545