Skip to content

Commit 1456c75

Browse files
committed
Merge branch 'audit-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull audit-tree fixes from Miklos Szeredi: "The audit subsystem maintainers (Al and Eric) are not responding to repeated resends. Eric did ack them a while ago, but no response since then. So I'm sending these directly to you." * 'audit-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: audit: clean up refcounting in audit-tree audit: fix refcounting in audit-tree audit: don't free_chunk() after fsnotify_add_mark()
2 parents a6b881a + b3e8692 commit 1456c75

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

kernel/audit_tree.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ static void untag_chunk(struct node *p)
250250
spin_unlock(&hash_lock);
251251
spin_unlock(&entry->lock);
252252
fsnotify_destroy_mark(entry);
253-
fsnotify_put_mark(entry);
254253
goto out;
255254
}
256255

@@ -259,7 +258,7 @@ static void untag_chunk(struct node *p)
259258

260259
fsnotify_duplicate_mark(&new->mark, entry);
261260
if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) {
262-
free_chunk(new);
261+
fsnotify_put_mark(&new->mark);
263262
goto Fallback;
264263
}
265264

@@ -293,7 +292,7 @@ static void untag_chunk(struct node *p)
293292
spin_unlock(&hash_lock);
294293
spin_unlock(&entry->lock);
295294
fsnotify_destroy_mark(entry);
296-
fsnotify_put_mark(entry);
295+
fsnotify_put_mark(&new->mark); /* drop initial reference */
297296
goto out;
298297

299298
Fallback:
@@ -322,7 +321,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
322321

323322
entry = &chunk->mark;
324323
if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) {
325-
free_chunk(chunk);
324+
fsnotify_put_mark(entry);
326325
return -ENOSPC;
327326
}
328327

@@ -347,6 +346,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
347346
insert_hash(chunk);
348347
spin_unlock(&hash_lock);
349348
spin_unlock(&entry->lock);
349+
fsnotify_put_mark(entry); /* drop initial reference */
350350
return 0;
351351
}
352352

@@ -396,7 +396,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
396396
fsnotify_duplicate_mark(chunk_entry, old_entry);
397397
if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) {
398398
spin_unlock(&old_entry->lock);
399-
free_chunk(chunk);
399+
fsnotify_put_mark(chunk_entry);
400400
fsnotify_put_mark(old_entry);
401401
return -ENOSPC;
402402
}
@@ -444,8 +444,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
444444
spin_unlock(&chunk_entry->lock);
445445
spin_unlock(&old_entry->lock);
446446
fsnotify_destroy_mark(old_entry);
447+
fsnotify_put_mark(chunk_entry); /* drop initial reference */
447448
fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
448-
fsnotify_put_mark(old_entry); /* and kill it */
449449
return 0;
450450
}
451451

@@ -916,7 +916,12 @@ static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify
916916
struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark);
917917

918918
evict_chunk(chunk);
919-
fsnotify_put_mark(entry);
919+
920+
/*
921+
* We are guaranteed to have at least one reference to the mark from
922+
* either the inode or the caller of fsnotify_destroy_mark().
923+
*/
924+
BUG_ON(atomic_read(&entry->refcnt) < 1);
920925
}
921926

922927
static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode,

0 commit comments

Comments
 (0)