- 27 Jul, 2020 2 commits
-
-
Amir Goldstein authored
The method handle_event() grew a lot of complexity due to the design of fanotify and merging of ignore masks. Most backends do not care about this complex functionality, so we can hide this complexity from them. Introduce a method handle_inode_event() that serves those backends and passes a single inode mark and less arguments. This change converts all backends except fanotify and inotify to use the simplified handle_inode_event() method. In pricipal, inotify could have also used the new method, but that would require passing more arguments on the simple helper (data, data_type, cookie), so we leave it with the handle_event() method. Link: https://lore.kernel.org/r/20200722125849.17418-9-amir73il@gmail.com Suggested-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Amir Goldstein authored
The 'inode' argument to handle_event(), sometimes referred to as 'to_tell' is somewhat obsolete. It is a remnant from the times when a group could only have an inode mark associated with an event. We now pass an iter_info array to the callback, with all marks associated with an event. Most backends ignore this argument, with two exceptions: 1. dnotify uses it for sanity check that event is on directory 2. fanotify uses it to report fid of directory on directory entry modification events Remove the 'inode' argument and add a 'dir' argument. The callback function signature is deliberately changed, because the meaning of the argument has changed and the arguments have been documented. The 'dir' argument is set to when 'file_name' is specified and it is referring to the directory that the 'file_name' entry belongs to. Signed-off-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
- 17 Jun, 2020 1 commit
-
-
Gustavo A. R. Silva authored
One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct audit_chunk { ... struct node { struct list_head list; struct audit_tree *owner; unsigned index; /* index; upper bit indicates 'will prune' */ } owners[]; }; Make use of the struct_size() helper instead of an open-coded version in order to avoid any potential type mistakes. So, replace the following form: offsetof(struct audit_chunk, owners) + count * sizeof(struct node); with: struct_size(chunk, owners, count) This code was detected with the help of Coccinelle. Signed-off-by:
Gustavo A. R. Silva <gustavoars@kernel.org> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 26 Apr, 2019 1 commit
-
-
Al Viro authored
note that conditions surrounding accesses to dname in audit_watch_handle_event() and audit_mark_handle_event() guarantee that dname won't have been NULL. Signed-off-by:
Al Viro <viro@zeniv.linux.org.uk>
-
- 14 Jan, 2019 1 commit
-
-
Richard Guy Briggs authored
Since the context is derived from the task parameter handed to __audit_free(), hand the context to audit_kill_trees() so it can be used to associate with a syscall record. This requires adding the context parameter to kill_rules() rather than using the current audit_context. The callers of trim_marked() and evict_chunk() still have their context. The EOE record was being issued prior to the pruning of the killed_tree list. Move the kill_trees call before the audit_log_exit call in __audit_free() and __audit_syscall_exit() so that any pruned trees CONFIG_CHANGE records are included with the associated syscall event by the user library due to the EOE record flagging the end of the event. See: https://github.com/linux-audit/audit-kernel/issues/50 See: https://github.com/linux-audit/audit-kernel/issues/59 Signed-off-by:
Richard Guy Briggs <rgb@redhat.com> [PM: fixed merge fuzz in kernel/audit_tree.c] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 26 Nov, 2018 1 commit
-
-
Paul Moore authored
There are some cases where we are making multiple audit_log_format() calls in a row, for no apparent reason. Squash these down to a single audit_log_format() call whenever possible. Acked-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 12 Nov, 2018 14 commits
-
-
Jan Kara authored
Variables pointing to fsnotify_mark are sometimes called 'entry' and sometimes 'mark'. Use 'mark' in all places. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> [PM: minor merge fuzz due to updated patches previously in the series] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Audit tree code currently associates new fsnotify mark with each new chunk. As chunk attached to an inode is replaced when new tag is added / removed, we also need to remove old fsnotify mark and add a new one on such occasion. This is cumbersome and makes locking rules somewhat difficult to follow. Fix these problems by allocating fsnotify mark independently of chunk and keeping it all the time while there is some chunk attached to an inode. Also add documentation about the locking rules so that things are easier to follow. Signed-off-by:
Jan Kara <jack@suse.cz> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> [PM: minor merge fuzz due to updated patches previously in the series] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
untag_chunk() has to be called with hash_lock, it drops it and reacquires it when returning. The unlocking of hash_lock is thus hidden from the callers of untag_chunk() with is rather error prone. Reorganize the code so that untag_chunk() is called without hash_lock, only with mark reference preventing the chunk from going away. Since this requires some more code in the caller of untag_chunk() to assure forward progress, factor out loop pruning tree from all chunks into a common helper function. Signed-off-by:
Jan Kara <jack@suse.cz> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
When deleting chunk from a tree, drop all unused nodes in a chunk instead of just the one used by the tree. This gets rid of possibly lingering unused nodes (created due to fallback path in untag_chunk()) and also removes some special cases and will allow us to simplify locking in untag_chunk(). Signed-off-by:
Jan Kara <jack@suse.cz> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
When removing chunk from a tree, we do shrink the chunk. This can fail for various reasons (due to races, ENOMEM, etc.) and in some cases we just bail from untag_chunk() relying on someone else to cleanup. Although this currently works, later we will need to add new failure situation which would break. Also this simplifies the code and will allow us to make locking around untag_chunk() less awkward. Signed-off-by:
Jan Kara <jack@suse.cz> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Allocate fsnotify mark independently instead of embedding it inside chunk. This will allow us to just replace chunk attached to mark when growing / shrinking chunk instead of replacing mark attached to inode which is a more complex operation. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Provide a helper function audit_mark_put_chunk() for dropping mark's reference (which has to happen only after RCU grace period expires). Currently that happens only from a single place but in later patches we introduce more callers. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
The audit_tree_group->mark_mutex is held all the time while we create the fsnotify mark, add it to the inode, and insert chunk into the hash. Hence mark cannot get detached during this time and so the check whether the mark is attached in insert_hash() is pointless. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Chunk replacement code is very similar for the cases where we grow or shrink chunk. Factor the code out into a common helper function. Signed-off-by:
Jan Kara <jack@suse.cz> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Currently, the audit tree code does not make sure that when a chunk is inserted into the hash table, it is fully initialized. So in theory a user of RCU lookup could see uninitialized structure in the hash table and crash. Add appropriate barriers between initialization of the structure and its insertion into hash table. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Currently chunk hash key (which is in fact pointer to the inode) is derived as chunk->mark.conn->obj. It is tricky to make this dereference reliable for hash table lookups only under RCU as mark can get detached from the connector and connector gets freed independently of the running lookup. Thus there is a possible use after free / NULL ptr dereference issue: CPU1 CPU2 untag_chunk() ... audit_tree_lookup() list_for_each_entry_rcu(p, list, hash) { list_del_rcu(&chunk->hash); fsnotify_destroy_mark(entry); fsnotify_put_mark(entry) chunk_to_key(p) if (!chunk->mark.connector) ... hlist_del_init_rcu(&mark->obj_list); if (hlist_empty(&conn->list)) { inode = fsnotify_detach_connector_from_object(conn); mark->connector = NULL; ... frees connector from workqueue chunk->mark.connector->obj This race is probably impossible to hit in practice as the race window on CPU1 is very narrow and CPU2 has a lot of code to execute. Still it's better to have this fixed. Since the inode the chunk is attached to is constant during chunk's lifetime it is easy to cache the key in the chunk itself and thus avoid these issues. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Audit tree code is replacing marks attached to inodes in non-atomic way. Thus fsnotify_find_mark() in tag_chunk() may find a mark that belongs to a chunk that is no longer valid one and will soon be destroyed. Tags added to such chunk will be simply lost. Fix the problem by making sure old mark is marked as going away (through fsnotify_detach_mark()) before dropping mark_mutex and thus in an atomic way wrt tag_chunk(). Note that this does not fix the problem completely as if tag_chunk() finds a mark that is going away, it fails with -ENOENT. But at least the failure is not silent and currently there's no way to search for another fsnotify mark attached to the inode. We'll fix this problem in later patch. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
When an inode is tagged with a tree, tag_chunk() checks whether there is audit_tree_group mark attached to the inode and adds one if not. However nothing protects another tag_chunk() to add the mark between we've checked and try to add the fsnotify mark thus resulting in an error from fsnotify_add_mark() and consequently an ENOSPC error from tag_chunk(). Fix the problem by holding mark_mutex over the whole check-insert code sequence. Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
Jan Kara authored
Currently, audit_tree code uses mark->lock to protect against detaching of mark from an inode. In most places it however also uses mark->group->mark_mutex (as we need to atomically replace attached marks) and this provides protection against mark detaching as well. So just remove protection with mark->lock from audit tree code and replace it with mark->group->mark_mutex protection in all the places. It simplifies the code and gets rid of some ugly catches like calling fsnotify_add_mark_locked() with mark->lock held (which cannot sleep only because we hold a reference to another mark attached to the same inode). Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 28 Jun, 2018 1 commit
-
-
Richard Guy Briggs authored
Respect the audit_enabled flag when printing tree rule config change records. See: https://github.com/linux-audit/audit-kernel/issues/50 Signed-off-by:
Richard Guy Briggs <rgb@redhat.com> [PM: tweak the subject line] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 27 Jun, 2018 1 commit
-
-
Amir Goldstein authored
Make the code to attach/detach a connector to object more generic by letting the fsnotify connector point to an abstract fsnotify_connp_t. Code that needs to dereference an inode or mount object now uses the helpers fsnotify_conn_{inode,mount}. Signed-off-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
- 18 May, 2018 2 commits
-
-
Amir Goldstein authored
Before changing the arguments of the functions fsnotify_add_mark() and fsnotify_add_mark_locked(), convert most callers to use a wrapper. Signed-off-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Amir Goldstein authored
inode_mark and vfsmount_mark arguments are passed to handle_event() operation as function arguments as well as on iter_info struct. The difference is that iter_info struct may contain marks that should not be handled and are represented as NULL arguments to inode_mark or vfsmount_mark. Instead of passing the inode_mark and vfsmount_mark arguments, add a report_mask member to iter_info struct to indicate which marks should be handled, versus marks that should only be kept alive during user wait. This change is going to be used for passing more mark types with handle_event() (i.e. super block marks). Signed-off-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
- 23 Feb, 2018 1 commit
-
-
Paul Moore authored
Evidently the __mutex_owner() function was never intended for use outside the core mutex code, so build a thing locking wrapper around the mutex code which allows us to track the mutex owner. One, arguably positive, side effect is that this allows us to hide the audit_cmd_mutex inside of kernel/audit.c behind the lock/unlock functions. Reported-by:
Peter Zijlstra <peterz@infradead.org> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 02 Nov, 2017 1 commit
-
-
Greg Kroah-Hartman authored
Many source files in the tree are missing licensing information, which makes it harder for compliance tools to determine the correct license. By default all files without license information are under the default license of the kernel, which is GPL version 2. Update the files which contain no license information with the 'GPL-2.0' SPDX license identifier. The SPDX identifier is a legally binding shorthand, which can be used instead of the full boiler plate text. This patch is based on work done by Thomas Gleixner and Kate Stewart and Philippe Ombredanne. How this work was done: Patches were generated and checked against linux-4.14-rc6 for a subset of the use cases: - file had no licensing information it it. - file was a */uapi/* one with no licensing information in it, - file was a */uapi/* one with existing licensing information, Further patches will be generated in subsequent months to fix up cases where non-standard...
-
- 31 Oct, 2017 1 commit
-
-
Elena Reshetova authored
atomic_t variables are currently used to implement reference counters with the following properties: - counter is initialized to 1 using atomic_set() - a resource is freed upon counter reaching zero - once counter reaches zero, its further increments aren't allowed - counter schema uses basic atomic operations (set, inc, inc_not_zero, dec_and_test, etc.) Such atomic variables should be converted to a newly provided refcount_t type and API that prevents accidental counter overflows and underflows. This is important since overflows and underflows can lead to use-after-free situation and be exploitable. The variable fsnotify_mark.refcnt is used as pure reference counter. Convert it to refcount_t and fix up the operations. Suggested-by:
Kees Cook <keescook@chromium.org> Reviewed-by:
David Windsor <dwindsor@gmail.com> Reviewed-by:
Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by:
Elena Reshetova <elena.reshetova@intel.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
- 02 May, 2017 1 commit
-
-
Elena Reshetova authored
refcount_t type and corresponding API should be used instead of atomic_t when the variable is used as a reference counter. This allows to avoid accidental refcounter overflows that might lead to use-after-free situations. Signed-off-by:
Elena Reshetova <elena.reshetova@intel.com> Signed-off-by:
Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by:
Kees Cook <keescook@chromium.org> Signed-off-by:
David Windsor <dwindsor@gmail.com> [PM: fix subject line, add #include] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 10 Apr, 2017 7 commits
-
-
Jan Kara authored
Pointer to ->free_mark callback unnecessarily occupies one long in each fsnotify_mark although they are the same for all marks from one notification group. Move the callback pointer to fsnotify_ops. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Reviewed-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Jan Kara authored
Currently we initialize mark->group only in fsnotify_add_mark_lock(). However we will need to access fsnotify_ops of corresponding group from fsnotify_put_mark() so we need mark->group initialized earlier. Do that in fsnotify_init_mark() which has a consequence that once fsnotify_init_mark() is called on a mark, the mark has to be destroyed by fsnotify_put_mark(). Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Reviewed-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Jan Kara authored
These are very thin wrappers, just remove them. Drop fs/notify/vfsmount_mark.c as it is empty now. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Reviewed-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Jan Kara authored
Pass fsnotify_iter_info into ->handle_event() handler so that it can release and reacquire SRCU lock via fsnotify_prepare_user_wait() and fsnotify_finish_user_wait() functions. These functions also make sure current marks are appropriately pinned so that iteration protected by srcu in fsnotify() stays safe. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Reviewed-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Jan Kara authored
Instead of removing mark from object list from fsnotify_detach_mark(), remove the mark when last reference to the mark is dropped. This will allow fanotify to wait for userspace response to event without having to hold onto fsnotify_mark_srcu. To avoid pinning inodes by elevated refcount (and thus e.g. delaying file deletion) while someone holds mark reference, we detach connector from the object also from fsnotify_destroy_marks() and not only after removing last mark from the list as it was now. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Reviewed-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Jan Kara authored
Move pointer to inode / vfsmount from mark itself to the fsnotify_mark_connector structure. This is another step on the path towards decoupling inode / vfsmount lifetime from notification mark lifetime. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Reviewed-by:
Amir Goldstein <amir73il@gmail.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
Jan Kara authored
Currently audit code uses checking of mark->inode to verify whether mark is still alive. Switch that to checking mark flags as that is more logical and current way will become unreliable in future. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
- 05 Apr, 2017 1 commit
-
-
Jan Kara authored
Audit tree currently uses inode pointer as a key into the hash table. Getting that from notification mark will be somewhat more difficult with coming fsnotify changes. So abstract getting of hash key from the audit chunk and inode so that we can change the method to obtain a key easily. Reviewed-by:
Miklos Szeredi <mszeredi@redhat.com> CC: Paul Moore <paul@paul-moore.com> Acked-by:
Paul Moore <paul@paul-moore.com> Signed-off-by:
Jan Kara <jack@suse.cz>
-
- 03 Jan, 2017 1 commit
-
-
Jan Kara authored
Audit tree code was happily adding new notification marks while holding spinlocks. Since fsnotify_add_mark() acquires group->mark_mutex this can lead to sleeping while holding a spinlock, deadlocks due to lock inversion, and probably other fun. Fix the problem by acquiring group->mark_mutex earlier. CC: Paul Moore <paul@paul-moore.com> Signed-off-by:
Jan Kara <jack@suse.cz> Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 23 Dec, 2016 1 commit
-
-
Jan Kara authored
There are only two calls sites of fsnotify_duplicate_mark(). Those are in kernel/audit_tree.c and both are bogus. Vfsmount pointer is unused for audit tree, inode pointer and group gets set in fsnotify_add_mark_locked() later anyway, mask and free_mark are already set in alloc_chunk(). In fact, calling fsnotify_duplicate_mark() is actively harmful because following fsnotify_add_mark_locked() will leak group reference by overwriting the group pointer. So just remove the two calls to fsnotify_duplicate_mark() and the function. Signed-off-by:
Jan Kara <jack@suse.cz> [PM: line wrapping to fit in 80 chars] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-
- 05 Dec, 2016 1 commit
-
-
Al Viro authored
Signed-off-by:
Al Viro <viro@zeniv.linux.org.uk>
-
- 20 Nov, 2016 1 commit
-
-
Steve Grubb authored
The AUDIT_CONFIG_CHANGE events sometimes use a op= field. The current code logs the value of the field with quotes. This field is documented to not be encoded, so it should not have quotes. Signed-off-by:
Steve Grubb <sgrubb@redhat.com> Reviewed-by:
Richard Guy Briggs <rgb@redhat.com> [PM: reformatted commit description to make checkpatch.pl happy] Signed-off-by:
Paul Moore <paul@paul-moore.com>
-