Messages in this thread Patch in this message | | | Date | Fri, 22 Sep 2017 16:36:44 +0200 | From | Oleg Nesterov <> | Subject | [PATCH 2/5] exec: binfmt_misc: shift filp_close(interp_file) from kill_node() to bm_evict_inode() |
| |
to ensure that load_misc_binary() can't use the partially destroyed Node, see also the next patch.
The current logic looks wrong in any case, once we close interp_file it doesn't make any sense to delay kfree(inode->i_private), this Node is no longer valid. Even if the MISC_FMT_OPEN_FILE/interp_file checks were not racy (they are), load_misc_binary() should not try to reopen ->interpreter if MISC_FMT_OPEN_FILE is set but ->interp_file is NULL.
And I can't understand why do we use filp_close(), not fput().
Signed-off-by: Oleg Nesterov <oleg@redhat.com> --- fs/binfmt_misc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index f4de5ae..040ed26 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -591,8 +591,13 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode) static void bm_evict_inode(struct inode *inode) { + Node *e = inode->i_private; + + if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) + filp_close(e->interp_file, NULL); + clear_inode(inode); - kfree(inode->i_private); + kfree(e); } static void kill_node(Node *e) @@ -603,11 +608,6 @@ static void kill_node(Node *e) list_del_init(&e->list); write_unlock(&entries_lock); - if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) { - filp_close(e->interp_file, NULL); - e->interp_file = NULL; - } - dentry = e->dentry; drop_nlink(d_inode(dentry)); d_drop(dentry); -- 2.5.0
| |