mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
ANDROID: fuse-bpf: Fix RCU/reference issue
094905c877("ANDROID: fuse-bpf: Always call revalidate for backing") called dget_parent/dput improperly within an RCU context. Additionally, it failed to free/put some references. Fixes:094905c877("ANDROID: fuse-bpf: Always call revalidate for backing") Signed-off-by: Daniel Rosenberg <drosen@google.com> Change-Id: Iedeee7550ff88366bc5310eedece285019336814
This commit is contained in:
@@ -243,14 +243,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TODO: Respect timeouts for lookups with backing inodes */
|
|
||||||
parent = dget_parent(entry);
|
|
||||||
if (get_fuse_inode(d_inode_rcu(parent))->backing_inode) {
|
|
||||||
dput(parent);
|
|
||||||
ret = 1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
dput(parent);
|
|
||||||
#endif
|
#endif
|
||||||
if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
|
if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
|
||||||
(flags & LOOKUP_REVAL)) {
|
(flags & LOOKUP_REVAL)) {
|
||||||
@@ -269,23 +261,26 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
|
|||||||
goto out;
|
goto out;
|
||||||
fm = get_fuse_mount(inode);
|
fm = get_fuse_mount(inode);
|
||||||
|
|
||||||
forget = fuse_alloc_forget();
|
|
||||||
ret = -ENOMEM;
|
|
||||||
if (!forget)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
attr_version = fuse_get_attr_version(fm->fc);
|
|
||||||
|
|
||||||
parent = dget_parent(entry);
|
parent = dget_parent(entry);
|
||||||
|
|
||||||
/* TODO: Once we're handling timeouts for backing inodes, do a
|
/* TODO: Once we're handling timeouts for backing inodes, do a
|
||||||
* bpf based lookup_revalidate here.
|
* bpf based lookup_revalidate here.
|
||||||
*/
|
*/
|
||||||
if (get_fuse_inode(parent->d_inode)->backing_inode) {
|
if (get_fuse_inode(parent->d_inode)->backing_inode) {
|
||||||
|
dput(parent);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forget = fuse_alloc_forget();
|
||||||
|
ret = -ENOMEM;
|
||||||
|
if (!forget) {
|
||||||
|
dput(parent);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_version = fuse_get_attr_version(fm->fc);
|
||||||
|
|
||||||
fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)),
|
fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)),
|
||||||
&entry->d_name, &outarg, &bpf_arg.out);
|
&entry->d_name, &outarg, &bpf_arg.out);
|
||||||
ret = fuse_simple_request(fm, &args);
|
ret = fuse_simple_request(fm, &args);
|
||||||
|
|||||||
Reference in New Issue
Block a user