@@ -71,7 +71,7 @@ pub mod uprobe;
71
71
pub mod xdp;
72
72
73
73
use std:: {
74
- ffi:: CString ,
74
+ ffi:: { CStr , CString } ,
75
75
io,
76
76
os:: fd:: { AsFd , BorrowedFd } ,
77
77
path:: { Path , PathBuf } ,
@@ -81,7 +81,7 @@ use std::{
81
81
use aya_obj:: {
82
82
VerifierLog ,
83
83
btf:: BtfError ,
84
- generated:: { bpf_attach_type, bpf_link_info, bpf_prog_info, bpf_prog_type} ,
84
+ generated:: { bpf_attach_type, bpf_link_info, bpf_prog_info, bpf_prog_type, bpf_task_fd_type } ,
85
85
} ;
86
86
use info:: impl_info;
87
87
pub use info:: { ProgramInfo , ProgramType , loaded_programs} ;
@@ -127,7 +127,7 @@ use crate::{
127
127
sys:: {
128
128
EbpfLoadProgramAttrs , NetlinkError , ProgQueryTarget , SyscallError , bpf_btf_get_fd_by_id,
129
129
bpf_get_object, bpf_link_get_fd_by_id, bpf_link_get_info_by_fd, bpf_load_program,
130
- bpf_pin_object, bpf_prog_get_fd_by_id, bpf_prog_query, iter_link_ids,
130
+ bpf_pin_object, bpf_prog_get_fd_by_id, bpf_prog_query, bpf_task_fd_query , iter_link_ids,
131
131
retry_with_verifier_logs,
132
132
} ,
133
133
util:: KernelVersion ,
@@ -1089,3 +1089,114 @@ pub fn loaded_links() -> impl Iterator<Item = Result<bpf_link_info, ProgramError
1089
1089
} )
1090
1090
. map ( |result| result. map_err ( Into :: into) )
1091
1091
}
1092
+
1093
+ /// Kind of a probe program from a process FD.
1094
+ #[ repr( u32 ) ]
1095
+ #[ non_exhaustive]
1096
+ #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
1097
+ pub enum TaskFdKind {
1098
+ /// Raw tracepoint.
1099
+ RawTracePoint = bpf_task_fd_type:: BPF_FD_TYPE_RAW_TRACEPOINT as u32 ,
1100
+ /// Tracepoint.
1101
+ TracePoint = bpf_task_fd_type:: BPF_FD_TYPE_TRACEPOINT as u32 ,
1102
+ /// Kernel probe.
1103
+ KProbe = bpf_task_fd_type:: BPF_FD_TYPE_KPROBE as u32 ,
1104
+ /// Kernel return probe.
1105
+ KRetProbe = bpf_task_fd_type:: BPF_FD_TYPE_KRETPROBE as u32 ,
1106
+ /// User space probe.
1107
+ UProbe = bpf_task_fd_type:: BPF_FD_TYPE_UPROBE as u32 ,
1108
+ /// User space return probe.
1109
+ URetProbe = bpf_task_fd_type:: BPF_FD_TYPE_URETPROBE as u32 ,
1110
+ }
1111
+
1112
+ impl TryFrom < u32 > for TaskFdKind {
1113
+ type Error = ProgramError ;
1114
+
1115
+ fn try_from ( v : u32 ) -> Result < Self , Self :: Error > {
1116
+ use TaskFdKind :: * ;
1117
+ use bpf_task_fd_type:: * ;
1118
+ Ok ( match v {
1119
+ x if x == BPF_FD_TYPE_RAW_TRACEPOINT as u32 => RawTracePoint ,
1120
+ x if x == BPF_FD_TYPE_TRACEPOINT as u32 => TracePoint ,
1121
+ x if x == BPF_FD_TYPE_KPROBE as u32 => KProbe ,
1122
+ x if x == BPF_FD_TYPE_KRETPROBE as u32 => KRetProbe ,
1123
+ x if x == BPF_FD_TYPE_UPROBE as u32 => UProbe ,
1124
+ x if x == BPF_FD_TYPE_URETPROBE as u32 => URetProbe ,
1125
+ _ => return Err ( ProgramError :: UnexpectedProgramType ) ,
1126
+ } )
1127
+ }
1128
+ }
1129
+
1130
+ /// Details of a probe program from a process FD.
1131
+ #[ derive( Debug ) ]
1132
+ pub struct TaskFdDetails < ' a > {
1133
+ /// Program ID.
1134
+ id : u32 ,
1135
+ /// Program kind.
1136
+ kind : TaskFdKind ,
1137
+ /// Program name.
1138
+ name : Option < & ' a CStr > ,
1139
+ /// Optional program probe address.
1140
+ probe_addr : Option < u64 > ,
1141
+ /// Optional program probe offset.
1142
+ probe_offset : Option < u64 > ,
1143
+ }
1144
+
1145
+ impl TaskFdDetails < ' _ > {
1146
+ /// Query the details of an FD in a process (task), looking for probe programs.
1147
+ ///
1148
+ /// `Ok(None)` is returned if the target FD does not exist or is not a probe program.
1149
+ pub fn query_task_fd (
1150
+ pid : u32 ,
1151
+ target_fd : BorrowedFd < ' _ > ,
1152
+ out_name_buf : Option < & mut [ u8 ] > ,
1153
+ ) -> Result < Option < Self > , ProgramError > {
1154
+ let out = match bpf_task_fd_query ( pid, target_fd, out_name_buf) {
1155
+ Ok ( v) => v,
1156
+ Err ( io_error) => {
1157
+ return match io_error. raw_os_error ( ) {
1158
+ // ENOTSUPP (errno 95) means that the target FD is not a perf program.
1159
+ Some ( 95 ) => Ok ( None ) ,
1160
+ // ENOENT (errno 2) means that the target FD or PID does not exist.
1161
+ Some ( 2 ) => Ok ( None ) ,
1162
+ _ => Err ( SyscallError {
1163
+ call : "bpf_task_fd_query" ,
1164
+ io_error,
1165
+ }
1166
+ . into ( ) ) ,
1167
+ } ;
1168
+ }
1169
+ } ;
1170
+ let kind = TaskFdKind :: try_from ( out. fd_type as u32 ) ?;
1171
+ Ok ( Some ( TaskFdDetails {
1172
+ id : out. prog_id ,
1173
+ kind,
1174
+ name : out. name ,
1175
+ probe_addr : out. probe_addr ,
1176
+ probe_offset : out. probe_offset ,
1177
+ } ) )
1178
+ }
1179
+
1180
+ /// Return the program ID.
1181
+ pub fn id ( & self ) -> u32 {
1182
+ self . id
1183
+ }
1184
+
1185
+ /// Return the program kind.
1186
+ pub fn kind ( & self ) -> TaskFdKind {
1187
+ self . kind
1188
+ }
1189
+
1190
+ /// Return the program name.
1191
+ pub fn name ( & self ) -> Option < & CStr > {
1192
+ self . name
1193
+ }
1194
+
1195
+ /// Return the program probe address and offset.
1196
+ pub fn address_and_offset ( & self ) -> Option < ( u64 , u64 ) > {
1197
+ match ( self . probe_addr , self . probe_offset ) {
1198
+ ( Some ( a) , Some ( o) ) => Some ( ( a, o) ) ,
1199
+ _ => None ,
1200
+ }
1201
+ }
1202
+ }
0 commit comments