Exemple #1
0
static int
invoke_cap_fault(register_t op)
{
	char buffer[N], ch;
	__capability char *cap;

	cap = cheri_ptrperm(buffer, sizeof(buffer), CHERI_PERM_LOAD);
	switch (op) {
	case CHERITEST_HELPER_OP_CP2_BOUND:
		ch = cap[N];
		return (ch);

	case CHERITEST_HELPER_OP_CP2_PERM:
		cap[0] = 0;
		break;

	case CHERITEST_HELPER_OP_CP2_TAG:
		cap = cheri_zerocap();
		ch = cap[0];
		return (ch);

	case CHERITEST_HELPER_OP_CP2_SEAL:
		cap = cheri_sealcode(cap);
		ch = cap[0];
		return (ch);
	}
	return (0);
}
Exemple #2
0
int
call_cheri_system_puts(void)
{
	__capability char *hello_world_str_c;

	hello_world_str_c = cheri_ptrperm(&hello_world_str,
	    sizeof(hello_world_str), CHERI_PERM_LOAD); /* Nul-terminated. */

	return (cheri_system_puts(hello_world_str_c));
}
Exemple #3
0
int
call_cheri_fd_write_c(struct cheri_object fd_object)
{
	__capability char *hello_world_buf_c;
	size_t len_buf_c;

	len_buf_c = strlen(hello_world_str_nl);
	hello_world_buf_c = cheri_ptrperm(&hello_world_str_nl, len_buf_c,
	    CHERI_PERM_LOAD); /* Just the text. */
	return (cheri_fd_write_c(fd_object,
	    hello_world_buf_c, len_buf_c).cfr_retval0);
}
Exemple #4
0
/*
 * Allocate a new cheri_fd object for an already-open file descriptor.
 */
int
cheri_fd_new(int fd, struct cheri_object *cop)
{
	__capability void *codecap, *datacap;
	struct cheri_fd *cfp;

	cfp = calloc(1, sizeof(*cfp));
	if (cfp == NULL) {
		errno = ENOMEM;
		return (-1);
	}
	CHERI_SYSTEM_OBJECT_INIT(cfp, cheri_fd_vtable);
	cfp->cf_fd = fd;

	/*
	 * Construct a sealed code capability for the class.  This is just the
	 * ambient $pcc with the offset set to the entry address.
	 *
	 * XXXRW: For now, when invoked, we install $pcc into $c0, so this
	 * needs a full set of permissions rather than just LOAD/EXECUTE. In
	 * the future, we will want to preserve a copy of cheri_getdefault()
	 * in the struct cheri_fd to be reinstalled by the entry code.
	 *
	 * XXXRW: In the future, use cheri_codeptr() here?
	 */
	codecap = cheri_setoffset(cheri_getpcc(),
	    (register_t)CHERI_CLASS_ENTRY(cheri_fd));
	cop->co_codecap = cheri_seal(codecap, cheri_fd_type);

	/*
	 * Construct a sealed data capability for the class.  This describes
	 * the 'struct cheri_fd' for the specific file descriptor.  The $c0
	 * to reinstall later is the first field in the structure.
	 *
	 * XXXRW: Should we also do an explicit cheri_setoffset()?
	 */
	datacap = cheri_ptrperm(cfp, sizeof(*cfp), CHERI_PERM_GLOBAL |
	    CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | CHERI_PERM_STORE |
	    CHERI_PERM_STORE_CAP);
	cop->co_datacap = cheri_seal(datacap, cheri_fd_type);
	return (0);
}
Exemple #5
0
/*
 * XXXRW: I'm not really happy with this approach of limiting access to system
 * resources via flags passed here.  We should use a more general security
 * model based on capability permissions.  However, this does allow us to more
 * generally get up and running.
 * XXXBD: I broke the flags when switching system functions to cheri_ccallee.
 */
int
sandbox_object_new_flags(struct sandbox_class *sbcp, size_t heaplen,
    uint flags, struct sandbox_object **sbopp)
{
	struct sandbox_object *sbop;
	int error;

	if (sandbox_program_sanity_check() < 0)
		errx(1, "%s: sandbox_program_sanity_check", __func__);

	sbop = calloc(1, sizeof(*sbop));
	if (sbop == NULL)
		return (-1);
	CHERI_SYSTEM_OBJECT_INIT(sbop, cheri_system_vtable);
	sbop->sbo_sandbox_classp = sbcp;
	sbop->sbo_flags = flags;
	sbop->sbo_heaplen = heaplen;

	/*
	 * XXXRW: In due course, stack size should be a parameter rather than
	 * a constant.
	 */
	sbop->sbo_stacklen = SANDBOX_STACK_SIZE;
	sbop->sbo_stackmem = mmap(0, sbop->sbo_stacklen,
	    PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
	if (sbop->sbo_stackmem == NULL) {
		free(sbop);
		return (-1);
	}

	/*
	 * Configure the object's stack before loading so that the stack
	 * capability can be installed into sandbox metadata.  Note that the
	 * capability is local (can't be shared) and can store local pointers
	 * (i.e., further stack-derived capabilities such as return
	 * addresses).
	 */
	sbop->sbo_stackcap = cheri_local(cheri_ptrperm(sbop->sbo_stackmem,
	    sbop->sbo_stacklen, CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP |
	    CHERI_PERM_STORE | CHERI_PERM_STORE_CAP |
	    CHERI_PERM_STORE_LOCAL_CAP));

	/*
	 * Set up the sandbox's code/data segments, sealed capabilities.
	 */
	error = sandbox_object_load(sbcp, sbop);
	if (error) {
		(void)munmap(sbop->sbo_stackmem, sbop->sbo_stacklen);
		free(sbop);
		return (-1);
	}

	/*
	 * Invoke object instance's constructors.  Note that, given the tight
	 * binding of class and object in the sandbox library currently, this
	 * will need to change in the future.  We also need to think more
	 * carefully about the mechanism here.
	 */
	if (cheri_invoke(sbop->sbo_cheri_object_rtld,
	    SANDBOX_RUNTIME_CONSTRUCTORS,
	    0, 0, 0, 0, 0, 0, 0, 0,
	    cheri_zerocap(), cheri_zerocap(), cheri_zerocap(),
	    cheri_zerocap(), cheri_zerocap(), cheri_zerocap(),
	    cheri_zerocap(), cheri_zerocap()) != 0) {
		sandbox_object_unload(sbop);
		(void)munmap(sbop->sbo_stackmem, sbop->sbo_stacklen);
		return (-1);
	}

	/*
	 * Now that constructors have completed, return object.
	 */
	*sbopp = sbop;
	return (0);
}
Exemple #6
0
int
test_sb(struct tf_test *thiz)
{
	struct sb sb;
	struct sb_param sp;
	__capability struct sb_param *spc;
	int rc;
	__capability void *cap;

	thiz->t_pf("create sandbox\n");
	rc = sb_init(thiz, &sb, SB_BIN, SB_HPSZ);
	if (rc != 0)
		return (rc);

	spc = cheri_ptr(&sp, sizeof(sp));
	memset(&sp, 0, sizeof(sp));

	rc = cheri_gc_new(CHERI_GC_METHOD_ALLOC_C |
	    CHERI_GC_METHOD_STATUS_C, &sp.sp_gc);
	if (rc != 0) {
		thiz->t_pf("error: cheri_gc_new\n");
		return (rc);
	}
	
	thiz->t_pf("sandbox codecap: %s\n", gc_cap_str(sb.sb_op->sbo_cheri_object_invoke.co_codecap));
	thiz->t_pf("sandbox datacap: %s\n", gc_cap_str(sb.sb_op->sbo_cheri_object_invoke.co_datacap));

	spc->sp_cap1 = cheri_ptrperm(&cap, sizeof(cap), CHERI_PERM_STORE_CAP);

	/* XXX: assume GC initialized. */
	
	thiz->t_pf("invoke sandbox\n");
	spc->sp_op = OP_INIT;
	rc = sb_invoke(thiz, &sb, spc);
	thiz->t_pf("return value from sandbox: %d\n", rc);
	
	/* In the sandbox, force p to the stack. */	
	thiz->t_pf("invoke sandbox\n");
	spc->sp_op = OP_TRY_USE;
	printf("note: spc is %s\n", gc_cap_str(spc));
	rc = sb_invoke(thiz, &sb, spc);
	thiz->t_pf("return value from sandbox: %d\n", rc);
	thiz->t_pf("cap: %s\n", gc_cap_str(cap));
	/* Check stack. */
	//struct gc_tags tg1 = gc_get_page_tags(gc_cheri_ptr(0x160c0c000ULL, 0x1000));
	//printf("lo: 0x%llx hi: 0x%llx\n", tg1.tg_lo, tg1.tg_hi);

	/* Do a collection. */
	//gc_extern_collect();
	
	// Revoke a cap.
	rc = gc_revoke(cap);
	thiz->t_pf("revoke rc: %d\n", rc);
	gc_extern_collect();
	
	thiz->t_pf("invoke sandbox\n");
	spc->sp_op = OP_TRY_USE;
	printf("note: spc is %s\n", gc_cap_str(spc));
	rc = sb_invoke(thiz, &sb, spc);
	thiz->t_pf("return value from sandbox: %d\n", rc);
	thiz->t_pf("cap: %s\n", gc_cap_str(cap));

	return (0);
}