Commit a2140fc0cb0325bb6384e788edd27b9a568714e2
1 parent
0fe33aae0e
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
audit: fix refcounting in audit-tree
Refcounting of fsnotify_mark in audit tree is broken. E.g: refcount create_chunk alloc_chunk 1 fsnotify_add_mark 2 untag_chunk fsnotify_get_mark 3 fsnotify_destroy_mark audit_tree_freeing_mark 2 fsnotify_put_mark 1 fsnotify_put_mark 0 via destroy_list fsnotify_mark_destroy -1 This was reported by various people as triggering Oops when stopping auditd. We could just remove the put_mark from audit_tree_freeing_mark() but that would break freeing via inode destruction. So this patch simply omits a put_mark after calling destroy_mark or adds a get_mark before. The additional get_mark is necessary where there's no other put_mark after fsnotify_destroy_mark() since it assumes that the caller is holding a reference (or the inode is keeping the mark pinned, not the case here AFAICS). Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Reported-by: Valentin Avram <aval13@gmail.com> Reported-by: Peter Moody <pmoody@google.com> Acked-by: Eric Paris <eparis@redhat.com> CC: stable@vger.kernel.org
Showing 1 changed file with 2 additions and 3 deletions Side-by-side Diff
kernel/audit_tree.c
... | ... | @@ -250,7 +250,6 @@ |
250 | 250 | spin_unlock(&hash_lock); |
251 | 251 | spin_unlock(&entry->lock); |
252 | 252 | fsnotify_destroy_mark(entry); |
253 | - fsnotify_put_mark(entry); | |
254 | 253 | goto out; |
255 | 254 | } |
256 | 255 | |
... | ... | @@ -293,7 +292,6 @@ |
293 | 292 | spin_unlock(&hash_lock); |
294 | 293 | spin_unlock(&entry->lock); |
295 | 294 | fsnotify_destroy_mark(entry); |
296 | - fsnotify_put_mark(entry); | |
297 | 295 | goto out; |
298 | 296 | |
299 | 297 | Fallback: |
... | ... | @@ -332,6 +330,7 @@ |
332 | 330 | spin_unlock(&hash_lock); |
333 | 331 | chunk->dead = 1; |
334 | 332 | spin_unlock(&entry->lock); |
333 | + fsnotify_get_mark(entry); | |
335 | 334 | fsnotify_destroy_mark(entry); |
336 | 335 | fsnotify_put_mark(entry); |
337 | 336 | return 0; |
... | ... | @@ -412,6 +411,7 @@ |
412 | 411 | spin_unlock(&chunk_entry->lock); |
413 | 412 | spin_unlock(&old_entry->lock); |
414 | 413 | |
414 | + fsnotify_get_mark(chunk_entry); | |
415 | 415 | fsnotify_destroy_mark(chunk_entry); |
416 | 416 | |
417 | 417 | fsnotify_put_mark(chunk_entry); |
... | ... | @@ -445,7 +445,6 @@ |
445 | 445 | spin_unlock(&old_entry->lock); |
446 | 446 | fsnotify_destroy_mark(old_entry); |
447 | 447 | fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ |
448 | - fsnotify_put_mark(old_entry); /* and kill it */ | |
449 | 448 | return 0; |
450 | 449 | } |
451 | 450 |