From fe475ca0b565afa1e71040fa39366276624b0a3e Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Wed, 26 Jul 2023 15:03:41 -0700 Subject: [PATCH] ANDROID: fuse-bpf: Check inode not null fuse_iget_backing returns an inode or null, not a ERR_PTR. So check it's not NULL Also make sure we put the inode if d_splice_alias fails Bug: 293349757 Test: fuse_test runs Signed_off_by: Paul Lawrence Change-Id: I1eadad32f80bab6730e461412b4b7ab4d6c56bf2 --- fs/fuse/backing.c | 17 ++++++++++------- fs/fuse/dir.c | 26 ++++++++++++-------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/fs/fuse/backing.c b/fs/fuse/backing.c index f6c5bf60ed5b..4465d001e637 100644 --- a/fs/fuse/backing.c +++ b/fs/fuse/backing.c @@ -252,8 +252,8 @@ int fuse_create_open_backing( inode = fuse_iget_backing(dir->i_sb, target_nodeid, get_fuse_dentry(entry)->backing_path.dentry->d_inode); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); + if (!inode) { + err = -EIO; goto out; } @@ -269,10 +269,12 @@ int fuse_create_open_backing( goto out; } + inode = NULL; entry = newent ? newent : entry; err = finish_open(file, entry, fuse_open_file_backing); out: + iput(inode); dput(backing_dentry); return err; } @@ -1239,7 +1241,7 @@ struct dentry *fuse_lookup_finalize(struct fuse_bpf_args *fa, struct inode *dir, { struct fuse_dentry *fd; struct dentry *bd; - struct inode *inode, *backing_inode; + struct inode *inode = NULL, *backing_inode; struct inode *d_inode = entry->d_inode; struct fuse_entry_out *feo = fa->out_args[0].value; struct fuse_entry_bpf_out *febo = fa->out_args[1].value; @@ -1270,9 +1272,8 @@ struct dentry *fuse_lookup_finalize(struct fuse_bpf_args *fa, struct inode *dir, target_nodeid = get_fuse_inode(d_inode)->nodeid; inode = fuse_iget_backing(dir->i_sb, target_nodeid, backing_inode); - - if (IS_ERR(inode)) { - ret = ERR_PTR(PTR_ERR(inode)); + if (!inode) { + ret = ERR_PTR(-EIO); goto out; } @@ -1289,9 +1290,11 @@ struct dentry *fuse_lookup_finalize(struct fuse_bpf_args *fa, struct inode *dir, } get_fuse_inode(inode)->nodeid = feo->nodeid; - ret = d_splice_alias(inode, entry); + if (!IS_ERR(ret)) + inode = NULL; out: + iput(inode); if (feb->backing_file) fput(feb->backing_file); return ret; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 9863c3ce533b..2efc82ca98e8 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -495,7 +495,6 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name if (name->len > FUSE_NAME_MAX) goto out; - forget = fuse_alloc_forget(); err = -ENOMEM; if (!forget) @@ -514,32 +513,34 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name err = -ENOENT; if (!entry) - goto out_queue_forget; + goto out_put_forget; err = -EINVAL; backing_file = bpf_arg.backing_file; if (!backing_file) - goto out_queue_forget; + goto out_put_forget; if (IS_ERR(backing_file)) { err = PTR_ERR(backing_file); - goto out_queue_forget; + goto out_put_forget; } backing_inode = backing_file->f_inode; *inode = fuse_iget_backing(sb, outarg->nodeid, backing_inode); if (!*inode) - goto out; + goto out_put_forget; err = fuse_handle_backing(&bpf_arg, &get_fuse_inode(*inode)->backing_inode, &get_fuse_dentry(entry)->backing_path); - if (err) - goto out; - - err = fuse_handle_bpf_prog(&bpf_arg, NULL, &get_fuse_inode(*inode)->bpf); - if (err) - goto out; + if (!err) + err = fuse_handle_bpf_prog(&bpf_arg, NULL, + &get_fuse_inode(*inode)->bpf); + if (err) { + iput(*inode); + *inode = NULL; + goto out_put_forget; + } } else #endif { @@ -559,9 +560,6 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name } err = -ENOMEM; -#ifdef CONFIG_FUSE_BPF -out_queue_forget: -#endif if (!*inode && outarg->nodeid) { fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1); goto out;