cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

semihosting.c (2390B)


      1/*
      2 * linux-user semihosting checks
      3 *
      4 * Copyright (c) 2019
      5 * Written by Alex Bennée <alex.bennee@linaro.org>
      6 *
      7 * SPDX-License-Identifier: GPL-3.0-or-later
      8 */
      9
     10#define SYS_WRITE0      0x04
     11#define SYS_HEAPINFO    0x16
     12#define SYS_REPORTEXC   0x18
     13
     14#include <stdint.h>
     15#include <stdlib.h>
     16#include <stdio.h>
     17#include <string.h>
     18#include "semicall.h"
     19
     20int main(int argc, char *argv[argc])
     21{
     22#if UINTPTR_MAX == UINT32_MAX
     23    uintptr_t exit_code = 0x20026;
     24#else
     25    uintptr_t exit_block[2] = {0x20026, 0};
     26    uintptr_t exit_code = (uintptr_t) &exit_block;
     27#endif
     28    struct {
     29        void *heap_base;
     30        void *heap_limit;
     31        void *stack_base;
     32        void *stack_limit;
     33    } info;
     34    void *ptr_to_info = (void *) &info;
     35
     36    __semi_call(SYS_WRITE0, (uintptr_t) "Checking HeapInfo\n");
     37
     38    memset(&info, 0, sizeof(info));
     39    __semi_call(SYS_HEAPINFO, (uintptr_t) &ptr_to_info);
     40
     41    if (info.heap_base == NULL || info.heap_limit == NULL) {
     42        printf("null heap: %p -> %p\n", info.heap_base, info.heap_limit);
     43        exit(1);
     44    }
     45
     46    /* Error if heap base is above limit */
     47    if ((uintptr_t) info.heap_base >= (uintptr_t) info.heap_limit) {
     48        printf("heap base %p >= heap_limit %p\n",
     49               info.heap_base, info.heap_limit);
     50        exit(2);
     51    }
     52
     53    if (info.stack_base == NULL || info.stack_limit) {
     54        printf("null stack: %p -> %p\n", info.stack_base, info.stack_limit);
     55        exit(3);
     56    }
     57
     58    /* check our local variables are indeed inside the reported stack */
     59    if (ptr_to_info > info.stack_base) {
     60        printf("info appears to be above stack: %p > %p\n", ptr_to_info,
     61               info.stack_base);
     62        exit(4);
     63    } else if (ptr_to_info < info.stack_limit) {
     64        printf("info appears to be outside stack: %p < %p\n", ptr_to_info,
     65               info.stack_limit);
     66        exit(5);
     67    }
     68
     69    if (ptr_to_info > info.heap_base && ptr_to_info < info.heap_limit) {
     70        printf("info appears to be inside the heap: %p in %p:%p\n",
     71               ptr_to_info, info.heap_base, info.heap_limit);
     72        exit(6);
     73    }
     74
     75    printf("heap: %p -> %p\n", info.heap_base, info.heap_limit);
     76    printf("stack: %p -> %p\n", info.stack_base, info.stack_limit);
     77
     78    __semi_call(SYS_WRITE0, (uintptr_t) "Passed HeapInfo checks");
     79    __semi_call(SYS_REPORTEXC, exit_code);
     80    /* if we get here we failed */
     81    return -1;
     82}