ANDROID: fuse-bpf: Use stored bpf for create_open
create_open would always take its parent directory's bpf for the created object. Modify to use the bpf stored in fuse_dentry which is set by lookup. Bug: 291705489 Test: fuse_test passes, adb push file /sdcard/Android/data works Signed-off-by: Paul Lawrence <paullawrence@google.com> Change-Id: I0a1ea2a291a8fdf67923f1827176b2ea96bd4c2d
This commit is contained in:
parent
74d9daa59a
commit
295e779e8f
@ -208,6 +208,7 @@ int fuse_create_open_backing(
|
||||
struct file *file, unsigned int flags, umode_t mode)
|
||||
{
|
||||
struct fuse_inode *dir_fuse_inode = get_fuse_inode(dir);
|
||||
struct fuse_dentry *fuse_entry = get_fuse_dentry(entry);
|
||||
struct fuse_dentry *dir_fuse_dentry = get_fuse_dentry(entry->d_parent);
|
||||
struct dentry *backing_dentry = NULL;
|
||||
struct inode *inode = NULL;
|
||||
@ -239,19 +240,19 @@ int fuse_create_open_backing(
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
if (get_fuse_dentry(entry)->backing_path.dentry)
|
||||
path_put(&get_fuse_dentry(entry)->backing_path);
|
||||
get_fuse_dentry(entry)->backing_path = (struct path) {
|
||||
if (fuse_entry->backing_path.dentry)
|
||||
path_put(&fuse_entry->backing_path);
|
||||
fuse_entry->backing_path = (struct path) {
|
||||
.mnt = dir_fuse_dentry->backing_path.mnt,
|
||||
.dentry = backing_dentry,
|
||||
};
|
||||
path_get(&get_fuse_dentry(entry)->backing_path);
|
||||
path_get(&fuse_entry->backing_path);
|
||||
|
||||
if (d_inode)
|
||||
target_nodeid = get_fuse_inode(d_inode)->nodeid;
|
||||
|
||||
inode = fuse_iget_backing(dir->i_sb, target_nodeid,
|
||||
get_fuse_dentry(entry)->backing_path.dentry->d_inode);
|
||||
fuse_entry->backing_path.dentry->d_inode);
|
||||
if (!inode) {
|
||||
err = -EIO;
|
||||
goto out;
|
||||
@ -259,9 +260,8 @@ int fuse_create_open_backing(
|
||||
|
||||
if (get_fuse_inode(inode)->bpf)
|
||||
bpf_prog_put(get_fuse_inode(inode)->bpf);
|
||||
get_fuse_inode(inode)->bpf = dir_fuse_inode->bpf;
|
||||
if (get_fuse_inode(inode)->bpf)
|
||||
bpf_prog_inc(dir_fuse_inode->bpf);
|
||||
get_fuse_inode(inode)->bpf = fuse_entry->bpf;
|
||||
fuse_entry->bpf = NULL;
|
||||
|
||||
newent = d_splice_alias(inode, entry);
|
||||
if (IS_ERR(newent)) {
|
||||
|
@ -2009,6 +2009,44 @@ static int bpf_test_lookup_postfilter(const char *mount_dir)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a file made via create_and_open correctly gets the bpf assigned
|
||||
* from the negative lookup
|
||||
* bpf blocks file open, but also removes itself from children
|
||||
* This test will fail if the 'remove' is unsuccessful
|
||||
*/
|
||||
static int bpf_test_create_and_remove_bpf(const char *mount_dir)
|
||||
{
|
||||
const char *file = "file";
|
||||
|
||||
int result = TEST_FAILURE;
|
||||
int src_fd = -1;
|
||||
int bpf_fd = -1;
|
||||
int fuse_dev = -1;
|
||||
int fd = -1;
|
||||
int fd2 = -1;
|
||||
|
||||
TEST(src_fd = open(ft_src, O_DIRECTORY | O_RDONLY | O_CLOEXEC),
|
||||
src_fd != -1);
|
||||
TESTEQUAL(install_elf_bpf("test_bpf.bpf", "test_create_remove", &bpf_fd,
|
||||
NULL, NULL), 0);
|
||||
TESTEQUAL(mount_fuse_no_init(mount_dir, bpf_fd, src_fd, &fuse_dev), 0);
|
||||
TEST(fd = s_creat(s_path(s(mount_dir), s(file)), 0777),
|
||||
fd != -1);
|
||||
TEST(fd2 = s_open(s_path(s(mount_dir), s(file)), O_RDONLY),
|
||||
fd2 != -1);
|
||||
|
||||
result = TEST_SUCCESS;
|
||||
out:
|
||||
close(fd2);
|
||||
close(fd);
|
||||
close(fuse_dev);
|
||||
close(bpf_fd);
|
||||
close(src_fd);
|
||||
umount(mount_dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void parse_range(const char *ranges, bool *run_test, size_t tests)
|
||||
{
|
||||
size_t i;
|
||||
@ -2136,6 +2174,7 @@ int main(int argc, char *argv[])
|
||||
MAKE_TEST(bpf_test_revalidate_handle_backing_fd),
|
||||
MAKE_TEST(bpf_test_lookup_postfilter),
|
||||
MAKE_TEST(flock_test),
|
||||
MAKE_TEST(bpf_test_create_and_remove_bpf),
|
||||
};
|
||||
#undef MAKE_TEST
|
||||
|
||||
|
@ -505,3 +505,29 @@ int lookuppostfilter_test(struct fuse_bpf_args *fa)
|
||||
return FUSE_BPF_BACKING;
|
||||
}
|
||||
}
|
||||
|
||||
SEC("test_create_remove")
|
||||
int createremovebpf_test(struct fuse_bpf_args *fa)
|
||||
{
|
||||
switch (fa->opcode) {
|
||||
case FUSE_LOOKUP | FUSE_PREFILTER: {
|
||||
return FUSE_BPF_BACKING | FUSE_BPF_POST_FILTER;
|
||||
}
|
||||
|
||||
case FUSE_LOOKUP | FUSE_POSTFILTER: {
|
||||
struct fuse_entry_bpf_out *febo = fa->out_args[1].value;
|
||||
|
||||
febo->bpf_action = FUSE_ACTION_REMOVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case FUSE_OPEN | FUSE_PREFILTER: {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
default:
|
||||
return FUSE_BPF_BACKING;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user