cheri-security / MorelloLinux / exampleCode / src / hybrid / hellohybrid.c
hellohybrid.c
Raw
/*
 * Copyright (c) 2023 Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <alloca.h>

#include "morello.h"

// Capability-aware strcpy:
static char * __capability strcpy_cap(char * __capability dst, const char *src);

// Capability-unaware strcpy:
static char *strcpy(char *dst, const char *src);

// Capability-aware alloca:
// Todo: bounds unrepresentability may cause bounds to overlap other objects.
static inline void * __capability alloca_cap(size_t n)
{
    return cheri_perms_and(cheri_bounds_set((void * __capability)alloca(n), n), PERM_GLOBAL | READ_CAP_PERMS | WRITE_CAP_PERMS);
}

int main(int argc, char *argv[])
{

    printf("hello morello in hybrid mode\n");
    printf("DDC: %s\n", cap_to_str(NULL, cheri_ddc_get()));
    printf("PCC: %s\n", cap_to_str(NULL, cheri_pcc_get()));

    printf("sizeof(ptr) = %zu\n", sizeof(char *));
    printf("sizeof(cap) = %zu\n", sizeof(char * __capability));

    char *ptr = "hybrid";
    char * __capability cap = "hybrid";

    printf("ptr: %016lx\n", (size_t)ptr);
    printf("cap: %s\n", cap_to_str(NULL, cap));

    // Make some capability:
    char * __capability dst_cap = alloca_cap(20);

    // Use capability-aware strcpy:
    char * __capability res_cap = strcpy_cap(dst_cap, "hello hybrid");
    printf("dst: %s\n", cap_to_str(NULL, dst_cap));
    printf("res: %s\n", cap_to_str(NULL, res_cap));

    // Use non-capability-aware strcpy:
    char * res_addr = strcpy((char *)cheri_address_get(dst_cap), "hello hybrid");
    printf("res: %016lx\n", (size_t)res_addr);

    return 0;
}

static char * __capability strcpy_cap(char * __capability dst, const char *src)
{
    for(; cheri_is_deref(dst) && *src; src++, dst++) {
        *dst = *src;
    }
    if (cheri_is_deref(dst)) {
        *dst = '\0';
    }
    return dst;
}

static char *strcpy(char *dst, const char *src)
{
    for(; *src; src++, dst++) {
        *dst = *src;
    }
    *dst = '\0';
    return dst;
}