/* * Forward write_c() on a cheri_fd to the underlying file descriptor. */ struct cheri_fd_ret cheri_fd_write(__capability const void *buf_c, size_t nbytes) { struct cheri_fd_ret ret; __capability struct cheri_fd *cfp; void *buf; /* XXXRW: Object-capability user permission check on idc. */ /* XXXRW: Change to check permissions directly and throw exception. */ if (!(cheri_getperm(buf_c) & CHERI_PERM_LOAD)) { ret.cfr_retval0 = -1; ret.cfr_retval1 = EPROT; return (ret); } buf = (void *)buf_c; /* Check that cheri_fd hasn't been revoked. */ cfp = cheri_getidc(); if (cfp->cf_fd == -1) { ret.cfr_retval0 = -1; ret.cfr_retval1 = EBADF; return (ret); } /* Forward to operating system. */ ret.cfr_retval0 = write(cfp->cf_fd, buf, min(nbytes, cheri_getlen(buf_c) - cheri_getoffset(buf_c))); ret.cfr_retval1 = (ret.cfr_retval0 < 0 ? errno : 0); return (ret); }
/* * Forward fstat() on a cheri_fd to the underlying file descriptor. */ struct cheri_fd_ret cheri_fd_fstat(__capability struct stat *sb_c) { struct cheri_fd_ret ret; __capability struct cheri_fd *cfp; struct stat *sb; /* XXXRW: Object-capability user permission check on idc. */ /* XXXRW: Change to check permissions directly and throw exception. */ if (!(cheri_getperm(sb_c) & CHERI_PERM_STORE) || !(cheri_getlen(sb_c) >= sizeof(*sb))) { ret.cfr_retval0 = -1; ret.cfr_retval1 = EPROT; return (ret); } sb = (void *)sb_c; /* Check that the cheri_fd hasn't been revoked. */ cfp = cheri_getidc(); if (cfp->cf_fd == -1) { ret.cfr_retval0 = -1; ret.cfr_retval1 = EBADF; return (ret); } /* Forward to operating system. */ ret.cfr_retval0 = fstat(cfp->cf_fd, sb); ret.cfr_retval1 = (ret.cfr_retval0 < 0 ? errno : 0); return (ret); }
/* * Forward lseek() on a cheri_fd to the underlying file descriptor. */ struct cheri_fd_ret cheri_fd_lseek(off_t offset, int whence) { struct cheri_fd_ret ret; __capability struct cheri_fd *cfp; /* XXXRW: Object-capability user permission check on idc. */ /* Check that the cheri_fd hasn't been revoked. */ cfp = cheri_getidc(); if (cfp->cf_fd == -1) { ret.cfr_retval0 = -1; ret.cfr_retval1 = EBADF; return (ret); } /* Forward to operating system. */ ret.cfr_retval0 = lseek(cfp->cf_fd, offset, whence); ret.cfr_retval1 = (ret.cfr_retval0 < 0 ? errno : 0); return (ret); }
__capability struct sandbox * cheri_getsandbox(void) { return (cheri_getidc()); }