mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
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:
@@ -208,6 +208,7 @@ int fuse_create_open_backing(
|
|||||||
struct file *file, unsigned int flags, umode_t mode)
|
struct file *file, unsigned int flags, umode_t mode)
|
||||||
{
|
{
|
||||||
struct fuse_inode *dir_fuse_inode = get_fuse_inode(dir);
|
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 fuse_dentry *dir_fuse_dentry = get_fuse_dentry(entry->d_parent);
|
||||||
struct dentry *backing_dentry = NULL;
|
struct dentry *backing_dentry = NULL;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
@@ -239,19 +240,19 @@ int fuse_create_open_backing(
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (get_fuse_dentry(entry)->backing_path.dentry)
|
if (fuse_entry->backing_path.dentry)
|
||||||
path_put(&get_fuse_dentry(entry)->backing_path);
|
path_put(&fuse_entry->backing_path);
|
||||||
get_fuse_dentry(entry)->backing_path = (struct path) {
|
fuse_entry->backing_path = (struct path) {
|
||||||
.mnt = dir_fuse_dentry->backing_path.mnt,
|
.mnt = dir_fuse_dentry->backing_path.mnt,
|
||||||
.dentry = backing_dentry,
|
.dentry = backing_dentry,
|
||||||
};
|
};
|
||||||
path_get(&get_fuse_dentry(entry)->backing_path);
|
path_get(&fuse_entry->backing_path);
|
||||||
|
|
||||||
if (d_inode)
|
if (d_inode)
|
||||||
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,
|
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) {
|
if (!inode) {
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -259,9 +260,8 @@ int fuse_create_open_backing(
|
|||||||
|
|
||||||
if (get_fuse_inode(inode)->bpf)
|
if (get_fuse_inode(inode)->bpf)
|
||||||
bpf_prog_put(get_fuse_inode(inode)->bpf);
|
bpf_prog_put(get_fuse_inode(inode)->bpf);
|
||||||
get_fuse_inode(inode)->bpf = dir_fuse_inode->bpf;
|
get_fuse_inode(inode)->bpf = fuse_entry->bpf;
|
||||||
if (get_fuse_inode(inode)->bpf)
|
fuse_entry->bpf = NULL;
|
||||||
bpf_prog_inc(dir_fuse_inode->bpf);
|
|
||||||
|
|
||||||
newent = d_splice_alias(inode, entry);
|
newent = d_splice_alias(inode, entry);
|
||||||
if (IS_ERR(newent)) {
|
if (IS_ERR(newent)) {
|
||||||
|
|||||||
@@ -2009,6 +2009,44 @@ static int bpf_test_lookup_postfilter(const char *mount_dir)
|
|||||||
return result;
|
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)
|
static void parse_range(const char *ranges, bool *run_test, size_t tests)
|
||||||
{
|
{
|
||||||
size_t i;
|
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_revalidate_handle_backing_fd),
|
||||||
MAKE_TEST(bpf_test_lookup_postfilter),
|
MAKE_TEST(bpf_test_lookup_postfilter),
|
||||||
MAKE_TEST(flock_test),
|
MAKE_TEST(flock_test),
|
||||||
|
MAKE_TEST(bpf_test_create_and_remove_bpf),
|
||||||
};
|
};
|
||||||
#undef MAKE_TEST
|
#undef MAKE_TEST
|
||||||
|
|
||||||
|
|||||||
@@ -505,3 +505,29 @@ int lookuppostfilter_test(struct fuse_bpf_args *fa)
|
|||||||
return FUSE_BPF_BACKING;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user