1 /* 2 * fuseMedia eBPF program 3 * 4 * Copyright (C) 2021 Google 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 */ 16 17 #include <android_bpf_defs.h> 18 #include <stdint.h> 19 #define __KERNEL__ 20 #include <fuse_kernel.h> 21 22 DEFINE_BPF_PROG("fuse/media", AID_ROOT, AID_MEDIA_RW, fuse_media) 23 (struct fuse_bpf_args* fa) { 24 switch (fa->opcode) { 25 case FUSE_LOOKUP | FUSE_PREFILTER: { 26 const char* name = fa->in_args[0].value; 27 28 bpf_printk("LOOKUP_PREFILTER: %lx %s", fa->nodeid, name); 29 return FUSE_BPF_BACKING | FUSE_BPF_POST_FILTER; 30 } 31 32 case FUSE_LOOKUP | FUSE_POSTFILTER: { 33 struct fuse_entry_out* feo = fa->out_args[0].value; 34 struct fuse_entry_bpf_out* febo = fa->out_args[1].value; 35 uint64_t uid_gid = bpf_get_current_uid_gid(); 36 uint32_t uid = uid_gid; 37 uint32_t gid = uid_gid >> 32; 38 39 febo->bpf_action = FUSE_ACTION_REMOVE; 40 41 /* If the decision is easy, make it here for performance */ 42 if (fa->error_in || (feo->attr.mode & 0001) || 43 ((feo->attr.mode & 0010) && gid == feo->attr.gid) || 44 ((feo->attr.mode & 0100) && uid == feo->attr.uid)) 45 return 0; 46 47 /* Delegate to the daemon */ 48 return FUSE_BPF_USER_FILTER; 49 } 50 51 case FUSE_READDIR | FUSE_PREFILTER: { 52 return FUSE_BPF_BACKING | FUSE_BPF_POST_FILTER; 53 } 54 55 case FUSE_READDIR | FUSE_POSTFILTER: { 56 return FUSE_BPF_USER_FILTER; 57 } 58 59 default: 60 return FUSE_BPF_BACKING; 61 } 62 } 63 64 LICENSE("GPL"); 65