(root)/
strace-6.5/
tests-mx32/
ioctl_perf.c
       1  /*
       2   * Check decoding of PERF_EVENT_IOC_* commands of ioctl syscall.
       3   *
       4   * Copyright (c) 2018-2022 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include "scno.h"
      12  #include <inttypes.h>
      13  #include <stdio.h>
      14  #include <string.h>
      15  #include <unistd.h>
      16  #include <sys/ioctl.h>
      17  #include <linux/perf_event.h>
      18  
      19  #define STR16 "0123456789abcdef"
      20  
      21  static long
      22  sys_ioctl(kernel_long_t fd, kernel_ulong_t cmd, kernel_ulong_t arg)
      23  {
      24  	return syscall(__NR_ioctl, fd, cmd, arg);
      25  }
      26  
      27  int
      28  main(void)
      29  {
      30  	static const kernel_ulong_t unknown_perf_cmd =
      31  		(kernel_ulong_t) 0xbadc0dedfeed24edULL;
      32  	static const kernel_ulong_t magic =
      33  		(kernel_ulong_t) 0xdeadbeefbadc0dedULL;
      34  	static const uint64_t magic64 = 0xfacefeeddeadc0deULL;
      35  	static const char str[] = STR16 STR16 STR16 STR16;
      36  
      37  	static struct {
      38  		unsigned int cmd;
      39  		const char *str;
      40  	} flag_iocs[] = {
      41  		{ ARG_STR(PERF_EVENT_IOC_ENABLE) },
      42  		{ ARG_STR(PERF_EVENT_IOC_DISABLE) },
      43  		{ ARG_STR(PERF_EVENT_IOC_RESET) },
      44  	};
      45  
      46  	TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, u64_ptr);
      47  	uint64_t *const u64_efault = u64_ptr + 1;
      48  	uint32_t *const u32_arr = tail_alloc(sizeof(uint32_t) * 4);
      49  	uint32_t *const u32_efault = u32_arr + 4;
      50  	char *const str_ptr = tail_memdup(str, sizeof(str));
      51  	char *const str_efault = str_ptr + sizeof(str);
      52  	TAIL_ALLOC_OBJECT_CONST_PTR(struct perf_event_attr, pea_ptr);
      53  
      54  	*u64_ptr = magic64;
      55  	fill_memory_ex(pea_ptr, sizeof(*pea_ptr), 0xaa, 0x55);
      56  
      57  	/* Unknown perf commands */
      58  	sys_ioctl(-1, unknown_perf_cmd, magic);
      59  	printf("ioctl(-1, _IOC(%s_IOC_READ|_IOC_WRITE, 0x24, %#x, %#x), "
      60  	       "%#lx) = -1 EBADF (%m)\n",
      61  	       _IOC_DIR((unsigned int) unknown_perf_cmd) & _IOC_NONE ?
      62  	       "_IOC_NONE|" : "",
      63  	       _IOC_NR((unsigned int) unknown_perf_cmd),
      64  	       _IOC_SIZE((unsigned int) unknown_perf_cmd),
      65  	       (unsigned long) magic);
      66  
      67  	sys_ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1, magic);
      68  	printf("ioctl(-1, _IOC(_IOC_WRITE, 0x24, %#x, %#x), %#lx)"
      69  	       " = -1 EBADF (%m)\n",
      70  	       (unsigned int) _IOC_NR(PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1),
      71  	       (unsigned int) _IOC_SIZE(PERF_EVENT_IOC_MODIFY_ATTRIBUTES + 1),
      72  	       (unsigned long) magic);
      73  
      74  	/* PERF_EVENT_IOC_{ENABLE,DISABLE,RESET} */
      75  	for (unsigned i = 0; i < ARRAY_SIZE(flag_iocs); i++) {
      76  		ioctl(-1, flag_iocs[i].cmd, 0);
      77  		printf("ioctl(-1, %s, 0) = -1 EBADF (%m)\n", flag_iocs[i].str);
      78  
      79  		ioctl(-1, flag_iocs[i].cmd, 1);
      80  		printf("ioctl(-1, %s, PERF_IOC_FLAG_GROUP) = -1 EBADF (%m)\n",
      81  		       flag_iocs[i].str);
      82  
      83  		ioctl(-1, flag_iocs[i].cmd, 2);
      84  		printf("ioctl(-1, %s, 0x2 /* PERF_IOC_FLAG_??? */) "
      85  		       "= -1 EBADF (%m)\n",
      86  		       flag_iocs[i].str);
      87  
      88  		sys_ioctl(-1, flag_iocs[i].cmd, magic);
      89  		printf("ioctl(-1, %s, PERF_IOC_FLAG_GROUP|%#x) "
      90  		       "= -1 EBADF (%m)\n",
      91  		       flag_iocs[i].str, (unsigned int) magic & ~1U);
      92  	}
      93  
      94  	/* PERF_EVENT_IOC_REFRESH */
      95  	sys_ioctl(-1, PERF_EVENT_IOC_REFRESH, magic);
      96  	printf("ioctl(-1, PERF_EVENT_IOC_REFRESH, %d) = -1 EBADF (%m)\n",
      97  	       (int) magic);
      98  
      99  	/* PERF_EVENT_IOC_PERIOD */
     100  	ioctl(-1, PERF_EVENT_IOC_PERIOD, NULL);
     101  	printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, NULL) = -1 EBADF (%m)\n");
     102  
     103  	ioctl(-1, PERF_EVENT_IOC_PERIOD, u64_efault);
     104  	printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, %p) = -1 EBADF (%m)\n",
     105  	      u64_efault);
     106  
     107  	ioctl(-1, PERF_EVENT_IOC_PERIOD, u64_ptr);
     108  	printf("ioctl(-1, PERF_EVENT_IOC_PERIOD, [%" PRIu64 "])"
     109  	       " = -1 EBADF (%m)\n",
     110  	       magic64);
     111  
     112  	/* PERF_EVENT_IOC_SET_OUTPUT */
     113  	sys_ioctl(-1, PERF_EVENT_IOC_SET_OUTPUT, magic);
     114  	printf("ioctl(-1, PERF_EVENT_IOC_SET_OUTPUT, %d) = -1 EBADF (%m)\n",
     115  	       (int) magic);
     116  
     117  	/* PERF_EVENT_IOC_SET_FILTER */
     118  	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, NULL);
     119  	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, NULL) = -1 EBADF (%m)\n");
     120  
     121  	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_efault);
     122  	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, %p) = -1 EBADF (%m)\n",
     123  	       str_efault);
     124  
     125  	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr);
     126  	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, \"%.32s\"...)"
     127  	       " = -1 EBADF (%m)\n",
     128  	       str_ptr);
     129  
     130  	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr + 40);
     131  	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, \"%.32s\")"
     132  	       " = -1 EBADF (%m)\n",
     133  	       str_ptr + 40);
     134  
     135  	str_ptr[sizeof(str) - 1] = '0';
     136  	ioctl(-1, PERF_EVENT_IOC_SET_FILTER, str_ptr + 40);
     137  	printf("ioctl(-1, PERF_EVENT_IOC_SET_FILTER, %p)"
     138  	       " = -1 EBADF (%m)\n",
     139  	       str_ptr + 40);
     140  
     141  	/* PERF_EVENT_IOC_ID */
     142  	ioctl(-1, PERF_EVENT_IOC_ID, NULL);
     143  	printf("ioctl(-1, PERF_EVENT_IOC_ID, NULL) = -1 EBADF (%m)\n");
     144  
     145  	ioctl(-1, PERF_EVENT_IOC_ID, u64_efault);
     146  	printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = -1 EBADF (%m)\n",
     147  	      u64_efault);
     148  
     149  	ioctl(-1, PERF_EVENT_IOC_ID, u64_ptr);
     150  	printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = -1 EBADF (%m)\n",
     151  	       u64_ptr);
     152  
     153  	/* PERF_EVENT_IOC_SET_BPF */
     154  	sys_ioctl(-1, PERF_EVENT_IOC_SET_BPF, magic);
     155  	printf("ioctl(-1, PERF_EVENT_IOC_SET_BPF, %d) = -1 EBADF (%m)\n",
     156  	       (int) magic);
     157  
     158  	/* PERF_EVENT_IOC_PAUSE_OUTPUT */
     159  	sys_ioctl(-1, PERF_EVENT_IOC_PAUSE_OUTPUT, magic);
     160  	printf("ioctl(-1, PERF_EVENT_IOC_PAUSE_OUTPUT, %lu) = -1 EBADF (%m)\n",
     161  	       (unsigned long) magic);
     162  
     163  	/* PERF_EVENT_IOC_QUERY_BPF */
     164  	ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL);
     165  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL) = -1 EBADF (%m)\n");
     166  
     167  	ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_efault);
     168  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, %p) = -1 EBADF (%m)\n",
     169  	       u32_efault);
     170  
     171  	u32_arr[0] = 0xbadc0ded;
     172  	ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr);
     173  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3134983661, ...})"
     174  	       " = -1 EBADF (%m)\n");
     175  
     176  	/* PERF_EVENT_IOC_MODIFY_ATTRIBUTES */
     177  	ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, NULL);
     178  	printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, NULL)"
     179  	       " = -1 EBADF (%m)\n");
     180  
     181  	ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, pea_ptr + 1);
     182  	printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, %p)"
     183  	       " = -1 EBADF (%m)\n",
     184  	       pea_ptr + 1);
     185  
     186  	printf("ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES"
     187  	       ", {type=%#x /* PERF_TYPE_??? */"
     188  	       ", size=%#x /* PERF_ATTR_SIZE_??? */"
     189  	       ", config=%#llx, sample_period=%llu%s, ...}) = -1 EBADF (%m)\n",
     190  	       (unsigned int) pea_ptr->type,
     191  	       (unsigned int) pea_ptr->size,
     192  	       (unsigned long long) pea_ptr->config,
     193  	       (unsigned long long) pea_ptr->sample_period,
     194  #ifdef WORDS_BIGENDIAN
     195  	       ", sample_type=PERF_SAMPLE_IP|PERF_SAMPLE_ADDR|PERF_SAMPLE_ID|"
     196  	       "PERF_SAMPLE_CPU|PERF_SAMPLE_BRANCH_STACK|PERF_SAMPLE_WEIGHT|"
     197  	       "PERF_SAMPLE_DATA_SRC|PERF_SAMPLE_IDENTIFIER|"
     198  	       "PERF_SAMPLE_TRANSACTION|PERF_SAMPLE_REGS_INTR|"
     199  	       "PERF_SAMPLE_DATA_PAGE_SIZE|PERF_SAMPLE_CODE_PAGE_SIZE|"
     200  	       "0xc2c3c4c5c6000000"
     201  	       ", read_format=PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_LOST|"
     202  	       "0xcacbcccdcecfd0c0"
     203  	       ", disabled=1, inherit=1, exclusive=1, exclude_hv=1, mmap=1"
     204  	       ", comm=1, inherit_stat=1, watermark=1"
     205  	       ", precise_ip=3 /* must have 0 skid */, mmap_data=1"
     206  	       ", exclude_host=1, exclude_callchain_kernel=1, comm_exec=1"
     207  	       ", use_clockid=1, write_backward=1, ksymbol=1, aux_output=1"
     208  	       ", cgroup=1, text_poke=1, inherit_thread=1, sigtrap=1"
     209  	       ", __reserved_1=0x2d7d8d9 /* Bits 63..38 */"
     210  #else
     211  	       ", sample_type=PERF_SAMPLE_TID|PERF_SAMPLE_ID|PERF_SAMPLE_CPU|"
     212  	       "PERF_SAMPLE_PERIOD|PERF_SAMPLE_STREAM_ID|PERF_SAMPLE_WEIGHT|"
     213  	       "PERF_SAMPLE_DATA_SRC|PERF_SAMPLE_REGS_INTR|"
     214  	       "PERF_SAMPLE_DATA_PAGE_SIZE|PERF_SAMPLE_CODE_PAGE_SIZE|"
     215  	       "PERF_SAMPLE_WEIGHT_STRUCT|0xc9c8c7c6c4000000"
     216  	       ", read_format=PERF_FORMAT_TOTAL_TIME_RUNNING|PERF_FORMAT_GROUP|"
     217  	       "0xd1d0cfcecdcccbc0"
     218  	       ", inherit=1, exclude_user=1, exclude_hv=1, exclude_idle=1"
     219  	       ", mmap=1, comm=1, enable_on_exec=1, watermark=1"
     220  	       ", precise_ip=1 /* constant skid */, sample_id_all=1"
     221  	       ", exclude_guest=1, exclude_callchain_user=1, mmap2=1"
     222  	       ", comm_exec=1, context_switch=1, namespaces=1, bpf_event=1"
     223  	       ", aux_output=1, text_poke=1, build_id=1, remove_on_exec=1"
     224  	       ", __reserved_1=0x367635f /* Bits 63..38 */"
     225  #endif
     226  	       );
     227  	ioctl(-1, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, pea_ptr);
     228  
     229  	puts("+++ exited with 0 +++");
     230  	return 0;
     231  }