cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

augmented_syscalls.c (5202B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Augment syscalls with the contents of the pointer arguments.
      4 *
      5 * Test it with:
      6 *
      7 * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null
      8 *
      9 * It'll catch some openat syscalls related to the dynamic linked and
     10 * the last one should be the one for '/etc/passwd'.
     11 *
     12 * This matches what is marshalled into the raw_syscall:sys_enter payload
     13 * expected by the 'perf trace' beautifiers, and can be used by them, that will
     14 * check if perf_sample->raw_data is more than what is expected for each
     15 * syscalls:sys_{enter,exit}_SYSCALL tracepoint, uing the extra data as the
     16 * contents of pointer arguments.
     17 */
     18
     19#include <stdio.h>
     20#include <linux/socket.h>
     21
     22/* bpf-output associated map */
     23bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);
     24
     25struct syscall_exit_args {
     26	unsigned long long common_tp_fields;
     27	long		   syscall_nr;
     28	long		   ret;
     29};
     30
     31struct augmented_filename {
     32	unsigned int	size;
     33	int		reserved;
     34	char		value[256];
     35};
     36
     37#define augmented_filename_syscall(syscall)							\
     38struct augmented_enter_##syscall##_args {			 				\
     39	struct syscall_enter_##syscall##_args	args;				 		\
     40	struct augmented_filename		filename;				 	\
     41};												\
     42int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
     43{												\
     44	struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; 	\
     45	unsigned int len = sizeof(augmented_args);						\
     46	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
     47	augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, 		\
     48						      sizeof(augmented_args.filename.value), 	\
     49						      args->filename_ptr); 			\
     50	if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) {		\
     51		len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size;	\
     52		len &= sizeof(augmented_args.filename.value) - 1;				\
     53	}											\
     54	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
     55	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
     56				 &augmented_args, len);						\
     57}												\
     58int syscall_exit(syscall)(struct syscall_exit_args *args)					\
     59{												\
     60       return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */	\
     61}
     62
     63struct syscall_enter_openat_args {
     64	unsigned long long common_tp_fields;
     65	long		   syscall_nr;
     66	long		   dfd;
     67	char		   *filename_ptr;
     68	long		   flags;
     69	long		   mode;
     70};
     71
     72augmented_filename_syscall(openat);
     73
     74struct syscall_enter_open_args {
     75	unsigned long long common_tp_fields;
     76	long		   syscall_nr;
     77	char		   *filename_ptr;
     78	long		   flags;
     79	long		   mode;
     80};
     81
     82augmented_filename_syscall(open);
     83
     84struct syscall_enter_inotify_add_watch_args {
     85	unsigned long long common_tp_fields;
     86	long		   syscall_nr;
     87	long		   fd;
     88	char		   *filename_ptr;
     89	long		   mask;
     90};
     91
     92augmented_filename_syscall(inotify_add_watch);
     93
     94struct statbuf;
     95
     96struct syscall_enter_newstat_args {
     97	unsigned long long common_tp_fields;
     98	long		   syscall_nr;
     99	char		   *filename_ptr;
    100	struct stat	   *statbuf;
    101};
    102
    103augmented_filename_syscall(newstat);
    104
    105#ifndef _K_SS_MAXSIZE
    106#define _K_SS_MAXSIZE 128
    107#endif
    108
    109#define augmented_sockaddr_syscall(syscall)						\
    110struct augmented_enter_##syscall##_args {			 				\
    111	struct syscall_enter_##syscall##_args	args;				 		\
    112	struct sockaddr_storage			addr;						\
    113};												\
    114int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
    115{												\
    116	struct augmented_enter_##syscall##_args augmented_args;				 	\
    117	unsigned long addrlen = sizeof(augmented_args.addr);					\
    118	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
    119/* FIXME_CLANG_OPTIMIZATION_THAT_ACCESSES_USER_CONTROLLED_ADDRLEN_DESPITE_THIS_CHECK */		\
    120/*	if (addrlen > augmented_args.args.addrlen)				     */		\
    121/*		addrlen = augmented_args.args.addrlen;				     */		\
    122/*										     */		\
    123	probe_read(&augmented_args.addr, addrlen, args->addr_ptr); 				\
    124	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
    125	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
    126				 &augmented_args, 						\
    127				sizeof(augmented_args) - sizeof(augmented_args.addr) + addrlen);\
    128}												\
    129int syscall_exit(syscall)(struct syscall_exit_args *args)					\
    130{												\
    131       return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */	\
    132}
    133
    134struct sockaddr;
    135
    136struct syscall_enter_bind_args {
    137	unsigned long long common_tp_fields;
    138	long		   syscall_nr;
    139	long		   fd;
    140	struct sockaddr	   *addr_ptr;
    141	unsigned long	   addrlen;
    142};
    143
    144augmented_sockaddr_syscall(bind);
    145
    146struct syscall_enter_connect_args {
    147	unsigned long long common_tp_fields;
    148	long		   syscall_nr;
    149	long		   fd;
    150	struct sockaddr	   *addr_ptr;
    151	unsigned long	   addrlen;
    152};
    153
    154augmented_sockaddr_syscall(connect);
    155
    156struct syscall_enter_sendto_args {
    157	unsigned long long common_tp_fields;
    158	long		   syscall_nr;
    159	long		   fd;
    160	void		   *buff;
    161	long		   len;
    162	unsigned long	   flags;
    163	struct sockaddr	   *addr_ptr;
    164	long		   addr_len;
    165};
    166
    167augmented_sockaddr_syscall(sendto);
    168
    169license(GPL);