18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Augment syscalls with the contents of the pointer arguments. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Test it with: 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * It'll catch some openat syscalls related to the dynamic linked and 108c2ecf20Sopenharmony_ci * the last one should be the one for '/etc/passwd'. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * This matches what is marshalled into the raw_syscall:sys_enter payload 138c2ecf20Sopenharmony_ci * expected by the 'perf trace' beautifiers, and can be used by them, that will 148c2ecf20Sopenharmony_ci * check if perf_sample->raw_data is more than what is expected for each 158c2ecf20Sopenharmony_ci * syscalls:sys_{enter,exit}_SYSCALL tracepoint, uing the extra data as the 168c2ecf20Sopenharmony_ci * contents of pointer arguments. 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include <stdio.h> 208c2ecf20Sopenharmony_ci#include <linux/socket.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* bpf-output associated map */ 238c2ecf20Sopenharmony_cibpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistruct syscall_exit_args { 268c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 278c2ecf20Sopenharmony_ci long syscall_nr; 288c2ecf20Sopenharmony_ci long ret; 298c2ecf20Sopenharmony_ci}; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct augmented_filename { 328c2ecf20Sopenharmony_ci unsigned int size; 338c2ecf20Sopenharmony_ci int reserved; 348c2ecf20Sopenharmony_ci char value[256]; 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define augmented_filename_syscall(syscall) \ 388c2ecf20Sopenharmony_cistruct augmented_enter_##syscall##_args { \ 398c2ecf20Sopenharmony_ci struct syscall_enter_##syscall##_args args; \ 408c2ecf20Sopenharmony_ci struct augmented_filename filename; \ 418c2ecf20Sopenharmony_ci}; \ 428c2ecf20Sopenharmony_ciint syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \ 438c2ecf20Sopenharmony_ci{ \ 448c2ecf20Sopenharmony_ci struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; \ 458c2ecf20Sopenharmony_ci unsigned int len = sizeof(augmented_args); \ 468c2ecf20Sopenharmony_ci probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \ 478c2ecf20Sopenharmony_ci augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, \ 488c2ecf20Sopenharmony_ci sizeof(augmented_args.filename.value), \ 498c2ecf20Sopenharmony_ci args->filename_ptr); \ 508c2ecf20Sopenharmony_ci if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) { \ 518c2ecf20Sopenharmony_ci len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size; \ 528c2ecf20Sopenharmony_ci len &= sizeof(augmented_args.filename.value) - 1; \ 538c2ecf20Sopenharmony_ci } \ 548c2ecf20Sopenharmony_ci /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \ 558c2ecf20Sopenharmony_ci return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \ 568c2ecf20Sopenharmony_ci &augmented_args, len); \ 578c2ecf20Sopenharmony_ci} \ 588c2ecf20Sopenharmony_ciint syscall_exit(syscall)(struct syscall_exit_args *args) \ 598c2ecf20Sopenharmony_ci{ \ 608c2ecf20Sopenharmony_ci return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ \ 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct syscall_enter_openat_args { 648c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 658c2ecf20Sopenharmony_ci long syscall_nr; 668c2ecf20Sopenharmony_ci long dfd; 678c2ecf20Sopenharmony_ci char *filename_ptr; 688c2ecf20Sopenharmony_ci long flags; 698c2ecf20Sopenharmony_ci long mode; 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciaugmented_filename_syscall(openat); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistruct syscall_enter_open_args { 758c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 768c2ecf20Sopenharmony_ci long syscall_nr; 778c2ecf20Sopenharmony_ci char *filename_ptr; 788c2ecf20Sopenharmony_ci long flags; 798c2ecf20Sopenharmony_ci long mode; 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ciaugmented_filename_syscall(open); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct syscall_enter_inotify_add_watch_args { 858c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 868c2ecf20Sopenharmony_ci long syscall_nr; 878c2ecf20Sopenharmony_ci long fd; 888c2ecf20Sopenharmony_ci char *filename_ptr; 898c2ecf20Sopenharmony_ci long mask; 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciaugmented_filename_syscall(inotify_add_watch); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistruct statbuf; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistruct syscall_enter_newstat_args { 978c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 988c2ecf20Sopenharmony_ci long syscall_nr; 998c2ecf20Sopenharmony_ci char *filename_ptr; 1008c2ecf20Sopenharmony_ci struct stat *statbuf; 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ciaugmented_filename_syscall(newstat); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci#ifndef _K_SS_MAXSIZE 1068c2ecf20Sopenharmony_ci#define _K_SS_MAXSIZE 128 1078c2ecf20Sopenharmony_ci#endif 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci#define augmented_sockaddr_syscall(syscall) \ 1108c2ecf20Sopenharmony_cistruct augmented_enter_##syscall##_args { \ 1118c2ecf20Sopenharmony_ci struct syscall_enter_##syscall##_args args; \ 1128c2ecf20Sopenharmony_ci struct sockaddr_storage addr; \ 1138c2ecf20Sopenharmony_ci}; \ 1148c2ecf20Sopenharmony_ciint syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \ 1158c2ecf20Sopenharmony_ci{ \ 1168c2ecf20Sopenharmony_ci struct augmented_enter_##syscall##_args augmented_args; \ 1178c2ecf20Sopenharmony_ci unsigned long addrlen = sizeof(augmented_args.addr); \ 1188c2ecf20Sopenharmony_ci probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \ 1198c2ecf20Sopenharmony_ci/* FIXME_CLANG_OPTIMIZATION_THAT_ACCESSES_USER_CONTROLLED_ADDRLEN_DESPITE_THIS_CHECK */ \ 1208c2ecf20Sopenharmony_ci/* if (addrlen > augmented_args.args.addrlen) */ \ 1218c2ecf20Sopenharmony_ci/* addrlen = augmented_args.args.addrlen; */ \ 1228c2ecf20Sopenharmony_ci/* */ \ 1238c2ecf20Sopenharmony_ci probe_read(&augmented_args.addr, addrlen, args->addr_ptr); \ 1248c2ecf20Sopenharmony_ci /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \ 1258c2ecf20Sopenharmony_ci return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \ 1268c2ecf20Sopenharmony_ci &augmented_args, \ 1278c2ecf20Sopenharmony_ci sizeof(augmented_args) - sizeof(augmented_args.addr) + addrlen);\ 1288c2ecf20Sopenharmony_ci} \ 1298c2ecf20Sopenharmony_ciint syscall_exit(syscall)(struct syscall_exit_args *args) \ 1308c2ecf20Sopenharmony_ci{ \ 1318c2ecf20Sopenharmony_ci return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ \ 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistruct sockaddr; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistruct syscall_enter_bind_args { 1378c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 1388c2ecf20Sopenharmony_ci long syscall_nr; 1398c2ecf20Sopenharmony_ci long fd; 1408c2ecf20Sopenharmony_ci struct sockaddr *addr_ptr; 1418c2ecf20Sopenharmony_ci unsigned long addrlen; 1428c2ecf20Sopenharmony_ci}; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ciaugmented_sockaddr_syscall(bind); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistruct syscall_enter_connect_args { 1478c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 1488c2ecf20Sopenharmony_ci long syscall_nr; 1498c2ecf20Sopenharmony_ci long fd; 1508c2ecf20Sopenharmony_ci struct sockaddr *addr_ptr; 1518c2ecf20Sopenharmony_ci unsigned long addrlen; 1528c2ecf20Sopenharmony_ci}; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ciaugmented_sockaddr_syscall(connect); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistruct syscall_enter_sendto_args { 1578c2ecf20Sopenharmony_ci unsigned long long common_tp_fields; 1588c2ecf20Sopenharmony_ci long syscall_nr; 1598c2ecf20Sopenharmony_ci long fd; 1608c2ecf20Sopenharmony_ci void *buff; 1618c2ecf20Sopenharmony_ci long len; 1628c2ecf20Sopenharmony_ci unsigned long flags; 1638c2ecf20Sopenharmony_ci struct sockaddr *addr_ptr; 1648c2ecf20Sopenharmony_ci long addr_len; 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ciaugmented_sockaddr_syscall(sendto); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cilicense(GPL); 170