Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vmm: Avoid making guest capabilities visible in the bhyve process context #2274

Merged
merged 7 commits into from
Jan 5, 2025
5 changes: 5 additions & 0 deletions lib/libvmmapi/aarch64/vmmapi_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ const char *vm_capstrmap[] = {
const cap_ioctl_t vm_ioctl_cmds[] = {
VM_COMMON_IOCTLS,
VM_MD_IOCTLS,
#if __has_feature(capabilities)
VM_GET_CHERI_CAPABILITY_TAG,
VM_GET_REGISTER_CHERI_CAPABILITY_TAG,
VM_GET_REGISTER_CHERI_CAPABILITY_TAG_SET,
#endif
};
size_t vm_ioctl_ncmds = nitems(vm_ioctl_cmds);

Expand Down
53 changes: 53 additions & 0 deletions lib/libvmmapi/vmmapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,23 @@ vm_get_register(struct vcpu *vcpu, int reg, uintcap_t *ret_val)
return (error);
}

#if __has_feature(capabilities)
int
vm_get_register_cheri_capability_tag(struct vcpu *vcpu, int reg, uint8_t *tagp)
{
struct vm_register_cheri_capability_tag vmreg;
int error;

bzero(&vmreg, sizeof(vmreg));
vmreg.regnum = reg;

error = vcpu_ioctl(vcpu, VM_GET_REGISTER_CHERI_CAPABILITY_TAG, &vmreg);
if (error == 0)
*tagp = vmreg.tag;
return (error);
}
#endif

int
vm_set_register_set(struct vcpu *vcpu, unsigned int count,
const int *regnums, uintcap_t *regvals)
Expand Down Expand Up @@ -682,6 +699,25 @@ vm_get_register_set(struct vcpu *vcpu, unsigned int count,
return (error);
}

#if __has_feature(capabilities)
int
vm_get_register_cheri_capability_tag_set(struct vcpu *vcpu, unsigned int count,
const int *regnums, uint8_t *tags)
{
struct vm_register_cheri_capability_tag_set vmtagset;
int error;

bzero(&vmtagset, sizeof(vmtagset));
vmtagset.count = count;
vmtagset.regnums = regnums;
vmtagset.tags = tags;

error = vcpu_ioctl(vcpu, VM_GET_REGISTER_CHERI_CAPABILITY_TAG_SET,
&vmtagset);
return (error);
}
#endif

int
vm_run(struct vcpu *vcpu, struct vm_run *vmrun)
{
Expand Down Expand Up @@ -1122,6 +1158,23 @@ vm_restore_time(struct vmctx *ctx)
}
#endif

#if __has_feature(capabilities)
int
vm_get_cheri_capability_tag(struct vmctx *ctx, vm_paddr_t gpa, uint8_t *tag)
{
struct vm_cheri_capability_tag vt;
int error;

bzero(&vt, sizeof(vt));
vt.gpa = gpa;

error = ioctl(ctx->fd, VM_GET_CHERI_CAPABILITY_TAG, &vt);
if (error == 0)
*tag = vt.tag;
return (error);
}
#endif

int
vm_set_topology(struct vmctx *ctx,
uint16_t sockets, uint16_t cores, uint16_t threads, uint16_t maxcpus)
Expand Down
16 changes: 16 additions & 0 deletions lib/libvmmapi/vmmapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,18 @@ int vm_get_seg_desc(struct vcpu *vcpu, int reg, struct seg_desc *seg_desc);
#endif
int vm_set_register(struct vcpu *vcpu, int reg, uintcap_t val);
int vm_get_register(struct vcpu *vcpu, int reg, uintcap_t *retval);
#if __has_feature(capabilities)
int vm_get_register_cheri_capability_tag(struct vcpu *vcpu, int reg,
uint8_t *tagp);
#endif
int vm_set_register_set(struct vcpu *vcpu, unsigned int count,
const int *regnums, uintcap_t *regvals);
int vm_get_register_set(struct vcpu *vcpu, unsigned int count,
const int *regnums, uintcap_t *regvals);
#if __has_feature(capabilities)
int vm_get_register_cheri_capability_tag_set(struct vcpu *vcpu,
unsigned int count, const int *regnums, uint8_t *tags);
#endif
int vm_run(struct vcpu *vcpu, struct vm_run *vmrun);
int vm_suspend(struct vmctx *ctx, enum vm_suspend_how how);
int vm_reinit(struct vmctx *ctx);
Expand Down Expand Up @@ -284,6 +292,14 @@ void vm_setup_freebsd_gdt(uint64_t *gdtr);
int vm_snapshot_req(struct vmctx *ctx, struct vm_snapshot_meta *meta);
int vm_restore_time(struct vmctx *ctx);

#if __has_feature(capabilities)
/*
* CHERI interfaces
*/
int vm_get_cheri_capability_tag(struct vmctx *ctx, vm_paddr_t gpa,
uint8_t *tag);
#endif

/*
* Deprecated interfaces, do not use them in new code.
*/
Expand Down
11 changes: 11 additions & 0 deletions sys/arm64/include/vmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ struct vm_object;
struct vm_guest_paging;
struct vm_vgic_descr;
struct pmap;
#if __has_feature(capabilities)
struct vm_cheri_capability_tag;
#endif

struct vm_eventinfo {
void *rptr; /* rendezvous cookie */
Expand Down Expand Up @@ -222,6 +225,10 @@ void *vm_gpa_hold_global(struct vm *vm, vm_paddr_t gpa, size_t len,
int prot, void **cookie);
void vm_gpa_release(void *cookie);
bool vm_mem_allocated(struct vcpu *vcpu, vm_paddr_t gpa);
#if __has_feature(capabilities)
int vm_get_cheri_capability_tag(struct vm *vm,
struct vm_cheri_capability_tag *vt);
#endif

int vm_gla2gpa_nofault(struct vcpu *vcpu, struct vm_guest_paging *paging,
uint64_t gla, int prot, uint64_t *gpa, int *is_fault);
Expand All @@ -232,6 +239,10 @@ void vm_get_topology(struct vm *vm, uint16_t *sockets, uint16_t *cores,
int vm_set_topology(struct vm *vm, uint16_t sockets, uint16_t cores,
uint16_t threads, uint16_t maxcpus);
int vm_get_register(struct vcpu *vcpu, int reg, uintcap_t *retval);
#if __has_feature(capabilities)
int vm_get_register_cheri_capability_tag(struct vcpu *vcpu, int reg,
uint8_t *tagp);
#endif
int vm_set_register(struct vcpu *vcpu, int reg, uintcap_t val);
int vm_run(struct vcpu *vcpu);
int vm_suspend(struct vm *vm, enum vm_suspend_how how);
Expand Down
41 changes: 41 additions & 0 deletions sys/arm64/include/vmm_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,30 @@
kuintcap_t regval;
};

#if __has_feature(capabilities)
struct vm_register_cheri_capability_tag {
int cpuid;
int regnum; /* enum vm_reg_name */
uint8_t tag;
};
#endif

struct vm_register_set {
int cpuid;
unsigned int count;
const int * __kerncap regnums; /* enum vm_reg_name */
uintcap_t * __kerncap regvals;
};

#if __has_feature(capabilities)
struct vm_register_cheri_capability_tag_set {
int cpuid;
unsigned int count;
const int * __kerncap regnums; /* enum vm_reg_name */

Check failure on line 79 in sys/arm64/include/vmm_dev.h

View workflow job for this annotation

GitHub Actions / Style Checker

"foo * bar" should be "foo *bar"
uint8_t * __kerncap tags;

Check failure on line 80 in sys/arm64/include/vmm_dev.h

View workflow job for this annotation

GitHub Actions / Style Checker

"foo * bar" should be "foo *bar"
};
#endif

struct vm_run {
int cpuid;
cpuset_t * __kerncap cpuset; /* CPU set storage */
Expand Down Expand Up @@ -159,6 +176,13 @@
uint16_t maxcpus;
};

#if __has_feature(capabilities)
struct vm_cheri_capability_tag {
vm_paddr_t gpa; /* input, must be aligned */
uint8_t tag; /* output */
};
#endif

enum {
/* general routines */
IOCNUM_ABIVERS = 0,
Expand Down Expand Up @@ -206,6 +230,12 @@
/* vm_attach_vgic */
IOCNUM_GET_VGIC_VERSION = 110,
IOCNUM_ATTACH_VGIC = 111,

#if __has_feature(capabilities)
IOCNUM_GET_CHERI_CAPABILITY_TAG = 200,
IOCNUM_GET_REGISTER_CHERI_CAPABILITY_TAG = 201,
IOCNUM_GET_REGISTER_CHERI_CAPABILITY_TAG_SET = 202,
#endif
};

#define VM_RUN \
Expand Down Expand Up @@ -266,4 +296,15 @@
_IOR('v', IOCNUM_GET_VGIC_VERSION, struct vm_vgic_version)
#define VM_ATTACH_VGIC \
_IOW('v', IOCNUM_ATTACH_VGIC, struct vm_vgic_descr)
#if __has_feature(capabilities)
#define VM_GET_CHERI_CAPABILITY_TAG \
_IOWR('v', IOCNUM_GET_CHERI_CAPABILITY_TAG, \
struct vm_cheri_capability_tag)
#define VM_GET_REGISTER_CHERI_CAPABILITY_TAG \
_IOWR('v', IOCNUM_GET_REGISTER_CHERI_CAPABILITY_TAG, \
struct vm_register_cheri_capability_tag)
#define VM_GET_REGISTER_CHERI_CAPABILITY_TAG_SET \
_IOW('v', IOCNUM_GET_REGISTER_CHERI_CAPABILITY_TAG_SET, \
struct vm_register_cheri_capability_tag_set)
#endif
#endif
44 changes: 41 additions & 3 deletions sys/arm64/vmm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1570,8 +1570,9 @@ _vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot,
void * __capability gpap;

#if __has_feature(capabilities)
gpap = cheri_setaddress(vmm_gpa_root_cap,
trunc_page(gpa));
gpap = cheri_setboundsexact(
cheri_setaddress(vmm_gpa_root_cap, trunc_page(gpa)),
PAGE_SIZE);
#else
gpap = (void *)trunc_page(gpa);
#endif
Expand All @@ -1583,7 +1584,7 @@ _vm_gpa_hold(struct vm *vm, vm_paddr_t gpa, size_t len, int reqprot,

if (count == 1) {
*cookie = m;
return (cheri_kern_setbounds(
return (cheri_kern_setboundsexact(
(void *)(PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)) + pageoff), len));
} else {
*cookie = NULL;
Expand Down Expand Up @@ -1633,6 +1634,23 @@ vm_get_register(struct vcpu *vcpu, int reg, uintcap_t *retval)
return (vmmops_getreg(vcpu->cookie, reg, retval));
}

#if __has_feature(capabilities)
int
vm_get_register_cheri_capability_tag(struct vcpu *vcpu, int reg, uint8_t *tagp)
{
uintcap_t val;
int error;

if (reg >= VM_REG_LAST)
return (EINVAL);

error = vmmops_getreg(vcpu->cookie, reg, &val);
if (error == 0)
*tagp = cheri_gettag(val);
return (error);
}
#endif

int
vm_set_register(struct vcpu *vcpu, int reg, uintcap_t val)
{
Expand Down Expand Up @@ -1689,6 +1707,26 @@ vm_deassert_irq(struct vm *vm, uint32_t irq)
return (vgic_inject_irq(vm->cookie, -1, irq, false));
}

#if __has_feature(capabilities)
int
vm_get_cheri_capability_tag(struct vm *vm, struct vm_cheri_capability_tag *vt)
{
uintcap_t *cap;
void *cookie;

if (!__is_aligned(vt->gpa, sizeof(*cap)))
return (EINVAL);

cap = vm_gpa_hold_global(vm, vt->gpa, sizeof(*cap), VM_PROT_READ,
&cookie);
if (cap == NULL)
return (EFAULT);
vt->tag = cheri_gettag(*cap);
vm_gpa_release(cookie);
return (0);
}
#endif

int
vm_raise_msi(struct vm *vm, uint64_t msg, uint64_t addr, int bus, int slot,
int func)
Expand Down
Loading
Loading