/* * Copyright (c) 2023 Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #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; }