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 <paullawrence@google.com>

Change-Id: I1eadad32f80bab6730e461412b4b7ab4d6c56bf2
This commit is contained in:
Paul Lawrence
2023-07-26 15:03:41 -07:00
parent feb5ea6684
commit fe475ca0b5
2 changed files with 22 additions and 21 deletions

View File

@@ -252,8 +252,8 @@ int fuse_create_open_backing(
inode = fuse_iget_backing(dir->i_sb, target_nodeid, inode = fuse_iget_backing(dir->i_sb, target_nodeid,
get_fuse_dentry(entry)->backing_path.dentry->d_inode); get_fuse_dentry(entry)->backing_path.dentry->d_inode);
if (IS_ERR(inode)) { if (!inode) {
err = PTR_ERR(inode); err = -EIO;
goto out; goto out;
} }
@@ -269,10 +269,12 @@ int fuse_create_open_backing(
goto out; goto out;
} }
inode = NULL;
entry = newent ? newent : entry; entry = newent ? newent : entry;
err = finish_open(file, entry, fuse_open_file_backing); err = finish_open(file, entry, fuse_open_file_backing);
out: out:
iput(inode);
dput(backing_dentry); dput(backing_dentry);
return err; return err;
} }
@@ -1239,7 +1241,7 @@ struct dentry *fuse_lookup_finalize(struct fuse_bpf_args *fa, struct inode *dir,
{ {
struct fuse_dentry *fd; struct fuse_dentry *fd;
struct dentry *bd; struct dentry *bd;
struct inode *inode, *backing_inode; struct inode *inode = NULL, *backing_inode;
struct inode *d_inode = entry->d_inode; struct inode *d_inode = entry->d_inode;
struct fuse_entry_out *feo = fa->out_args[0].value; struct fuse_entry_out *feo = fa->out_args[0].value;
struct fuse_entry_bpf_out *febo = fa->out_args[1].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; target_nodeid = get_fuse_inode(d_inode)->nodeid;
inode = fuse_iget_backing(dir->i_sb, target_nodeid, backing_inode); inode = fuse_iget_backing(dir->i_sb, target_nodeid, backing_inode);
if (!inode) {
if (IS_ERR(inode)) { ret = ERR_PTR(-EIO);
ret = ERR_PTR(PTR_ERR(inode));
goto out; 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; get_fuse_inode(inode)->nodeid = feo->nodeid;
ret = d_splice_alias(inode, entry); ret = d_splice_alias(inode, entry);
if (!IS_ERR(ret))
inode = NULL;
out: out:
iput(inode);
if (feb->backing_file) if (feb->backing_file)
fput(feb->backing_file); fput(feb->backing_file);
return ret; return ret;

View File

@@ -495,7 +495,6 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
if (name->len > FUSE_NAME_MAX) if (name->len > FUSE_NAME_MAX)
goto out; goto out;
forget = fuse_alloc_forget(); forget = fuse_alloc_forget();
err = -ENOMEM; err = -ENOMEM;
if (!forget) if (!forget)
@@ -514,32 +513,34 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
err = -ENOENT; err = -ENOENT;
if (!entry) if (!entry)
goto out_queue_forget; goto out_put_forget;
err = -EINVAL; err = -EINVAL;
backing_file = bpf_arg.backing_file; backing_file = bpf_arg.backing_file;
if (!backing_file) if (!backing_file)
goto out_queue_forget; goto out_put_forget;
if (IS_ERR(backing_file)) { if (IS_ERR(backing_file)) {
err = PTR_ERR(backing_file); err = PTR_ERR(backing_file);
goto out_queue_forget; goto out_put_forget;
} }
backing_inode = backing_file->f_inode; backing_inode = backing_file->f_inode;
*inode = fuse_iget_backing(sb, outarg->nodeid, backing_inode); *inode = fuse_iget_backing(sb, outarg->nodeid, backing_inode);
if (!*inode) if (!*inode)
goto out; goto out_put_forget;
err = fuse_handle_backing(&bpf_arg, err = fuse_handle_backing(&bpf_arg,
&get_fuse_inode(*inode)->backing_inode, &get_fuse_inode(*inode)->backing_inode,
&get_fuse_dentry(entry)->backing_path); &get_fuse_dentry(entry)->backing_path);
if (err) if (!err)
goto out; err = fuse_handle_bpf_prog(&bpf_arg, NULL,
&get_fuse_inode(*inode)->bpf);
err = fuse_handle_bpf_prog(&bpf_arg, NULL, &get_fuse_inode(*inode)->bpf); if (err) {
if (err) iput(*inode);
goto out; *inode = NULL;
goto out_put_forget;
}
} else } else
#endif #endif
{ {
@@ -559,9 +560,6 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
} }
err = -ENOMEM; err = -ENOMEM;
#ifdef CONFIG_FUSE_BPF
out_queue_forget:
#endif
if (!*inode && outarg->nodeid) { if (!*inode && outarg->nodeid) {
fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1); fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1);
goto out; goto out;