1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Copyright 2020 Google LLC. 5 */ 6 7 #include <errno.h> 8 #include <linux/bpf.h> 9 #include <stdbool.h> 10 #include <bpf/bpf_helpers.h> 11 #include <bpf/bpf_tracing.h> 12 13 char _license[] SEC("license") = "GPL"; 14 15 #define DUMMY_STORAGE_VALUE 0xdeadbeef 16 17 int monitored_pid = 0; 18 int inode_storage_result = -1; 19 int sk_storage_result = -1; 20 21 struct dummy_storage { 22 __u32 value; 23 }; 24 25 struct { 26 __uint(type, BPF_MAP_TYPE_INODE_STORAGE); 27 __uint(map_flags, BPF_F_NO_PREALLOC); 28 __type(key, int); 29 __type(value, struct dummy_storage); 30 } inode_storage_map SEC(".maps"); 31 32 struct { 33 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 34 __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE); 35 __type(key, int); 36 __type(value, struct dummy_storage); 37 } sk_storage_map SEC(".maps"); 38 39 /* TODO Use vmlinux.h once BTF pruning for embedded types is fixed. 40 */ 41 struct sock {} __attribute__((preserve_access_index)); 42 struct sockaddr {} __attribute__((preserve_access_index)); 43 struct socket { 44 struct sock *sk; 45 } __attribute__((preserve_access_index)); 46 47 struct inode {} __attribute__((preserve_access_index)); 48 struct dentry { 49 struct inode *d_inode; 50 } __attribute__((preserve_access_index)); 51 struct file { 52 struct inode *f_inode; 53 } __attribute__((preserve_access_index)); 54 55 56 SEC("lsm/inode_unlink") 57 int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) 58 { 59 __u32 pid = bpf_get_current_pid_tgid() >> 32; 60 struct dummy_storage *storage; 61 62 if (pid != monitored_pid) 63 return 0; 64 65 storage = bpf_inode_storage_get(&inode_storage_map, victim->d_inode, 0, 66 BPF_SK_STORAGE_GET_F_CREATE); 67 if (!storage) 68 return 0; 69 70 if (storage->value == DUMMY_STORAGE_VALUE) 71 inode_storage_result = -1; 72 73 inode_storage_result = 74 bpf_inode_storage_delete(&inode_storage_map, victim->d_inode); 75 76 return 0; 77 } 78 79 SEC("lsm/socket_bind") 80 int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, 81 int addrlen) 82 { 83 __u32 pid = bpf_get_current_pid_tgid() >> 32; 84 struct dummy_storage *storage; 85 86 if (pid != monitored_pid) 87 return 0; 88 89 storage = bpf_sk_storage_get(&sk_storage_map, sock->sk, 0, 90 BPF_SK_STORAGE_GET_F_CREATE); 91 if (!storage) 92 return 0; 93 94 if (storage->value == DUMMY_STORAGE_VALUE) 95 sk_storage_result = -1; 96 97 sk_storage_result = bpf_sk_storage_delete(&sk_storage_map, sock->sk); 98 return 0; 99 } 100 101 SEC("lsm/socket_post_create") 102 int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, 103 int protocol, int kern) 104 { 105 __u32 pid = bpf_get_current_pid_tgid() >> 32; 106 struct dummy_storage *storage; 107 108 if (pid != monitored_pid) 109 return 0; 110 111 storage = bpf_sk_storage_get(&sk_storage_map, sock->sk, 0, 112 BPF_SK_STORAGE_GET_F_CREATE); 113 if (!storage) 114 return 0; 115 116 storage->value = DUMMY_STORAGE_VALUE; 117 118 return 0; 119 } 120 121 SEC("lsm/file_open") 122 int BPF_PROG(file_open, struct file *file) 123 { 124 __u32 pid = bpf_get_current_pid_tgid() >> 32; 125 struct dummy_storage *storage; 126 127 if (pid != monitored_pid) 128 return 0; 129 130 if (!file->f_inode) 131 return 0; 132 133 storage = bpf_inode_storage_get(&inode_storage_map, file->f_inode, 0, 134 BPF_LOCAL_STORAGE_GET_F_CREATE); 135 if (!storage) 136 return 0; 137 138 storage->value = DUMMY_STORAGE_VALUE; 139 return 0; 140 } 141