From b64fedcf913456f1039c3026c143d8491d59fcaf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 28 Jun 2015 16:55:45 +0000 Subject: [PATCH] xen: Implement the xsm_op hypercall More recent Xen toolstacks use this for the SID_TO_CONTEXT operation only, even when XSM is not in use. XSM is actually an abstraction layer, of which the only current implementation is FLASK. So this blindly assumes that the backend is FLASK. Should another XSM backend be invented then we will have to sort of detecting the correct one. Signed-off-by: Ian Campbell git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15384 --- coregrind/m_syswrap/syswrap-xen.c | 73 ++++++++++++++++++++++++++++++- include/vki/vki-xen-xsm.h | 68 ++++++++++++++++++++++++++++ include/vki/vki-xen.h | 1 + 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 include/vki/vki-xen-xsm.h diff --git a/coregrind/m_syswrap/syswrap-xen.c b/coregrind/m_syswrap/syswrap-xen.c index ffbb7d183c..d897ed87e6 100644 --- a/coregrind/m_syswrap/syswrap-xen.c +++ b/coregrind/m_syswrap/syswrap-xen.c @@ -339,6 +339,53 @@ PRE(mmuext_op) } } +PRE(xsm_op) +{ + /* XXX assuming flask, only actual XSM right now */ + struct vki_xen_flask_op *op = (struct vki_xen_flask_op *)ARG1; + + PRINT("__HYPERVISOR_xsm_op ( %d )", op->cmd); + + /* + * Common part of xen_flask_op: + * vki_uint32_t cmd; + * vki_uint32_t interface_version; + */ + PRE_MEM_READ("__HYPERVISOR_xsm_op", ARG1, + sizeof(vki_uint32_t) + sizeof(vki_uint32_t)); + + if (!op) + return; + + switch (op->interface_version) { + case 0x00000001: + break; + default: + bad_intf_version(tid, layout, arrghs, status, flags, + "__HYPERVISOR_xsm_op", op->interface_version); + return; + } + +#define PRE_XEN_XSM_OP_READ(_xsm_op, _union, _field) \ + PRE_MEM_READ("FLASK_" #_xsm_op " u." #_union "." #_field, \ + (Addr)&op->u._union._field, \ + sizeof(op->u._union._field)) + + switch (op->cmd) { + case VKI_FLASK_SID_TO_CONTEXT: + PRE_XEN_XSM_OP_READ(SID_TO_CONTEXT, sid_context, sid); + PRE_XEN_XSM_OP_READ(SID_TO_CONTEXT, sid_context, size); + PRE_XEN_XSM_OP_READ(SID_TO_CONTEXT, sid_context, context.p); + break; + default: + bad_subop(tid, layout, arrghs, status, flags, + "__HYPERVISOR_xsm_op", op->cmd); + break; + } +#undef __PRE_XEN_XSM_OP_READ +#undef PRE_XEN_XSM_OP_READ +} + PRE(sched_op) { PRINT("__HYPERVISOR_sched_op ( %ld, %lx )", ARG1, ARG2); @@ -1286,6 +1333,30 @@ POST(mmuext_op) POST_MEM_WRITE((Addr)pdone, sizeof(*pdone)); } +POST(xsm_op) +{ + /* XXX assuming flask, only actual XSM right now */ + struct vki_xen_flask_op *op = (struct vki_xen_flask_op *)ARG1; + + switch (op->interface_version) { + case 0x00000001: + break; + default: + return; + } + +#define POST_XEN_XSM_OP_WRITE(_xsm_op, _union, _field) \ + POST_MEM_WRITE((Addr)&op->u._union._field, \ + sizeof(op->u._union._field)) + + switch (op->cmd) { + case VKI_FLASK_SID_TO_CONTEXT: + POST_XEN_XSM_OP_WRITE(SID_TO_CONTEXT, sid_context, size); + POST_MEM_WRITE((Addr)op->u.sid_context.context.p, + op->u.sid_context.size); + } +} + static void post_evtchn_op(ThreadId tid, __vki_u32 cmd, void *arg, int compat) { switch (cmd) { @@ -1911,7 +1982,7 @@ static XenHypercallTableEntry hypercall_table[] = { // __VKI_XEN_set_segment_base // 25 HYPXY(__VKI_XEN_mmuext_op, mmuext_op, 2), // 26 - // __VKI_XEN_xsm_op // 27 + HYPXY(__VKI_XEN_xsm_op, xsm_op, 1), // 27 // __VKI_XEN_nmi_op // 28 HYPXY(__VKI_XEN_sched_op, sched_op, 2), // 29 diff --git a/include/vki/vki-xen-xsm.h b/include/vki/vki-xen-xsm.h new file mode 100644 index 0000000000..8c798178b0 --- /dev/null +++ b/include/vki/vki-xen-xsm.h @@ -0,0 +1,68 @@ +#ifndef __VKI_XEN_XSM_H +#define __VKI_XEN_XSM_H + +#define VKI_XEN_FLASK_INTERFACE_VERSION 1 + +struct vki_xen_flask_sid_context { + /* IN/OUT: sid to convert to/from string */ + vki_uint32_t sid; + /* IN: size of the context buffer + * OUT: actual size of the output context string + */ + vki_uint32_t size; + VKI_XEN_GUEST_HANDLE(char) context; +}; + +struct vki_xen_flask_op { + vki_uint32_t cmd; +#define VKI_FLASK_LOAD 1 +#define VKI_FLASK_GETENFORCE 2 +#define VKI_FLASK_SETENFORCE 3 +#define VKI_FLASK_CONTEXT_TO_SID 4 +#define VKI_FLASK_SID_TO_CONTEXT 5 +#define VKI_FLASK_ACCESS 6 +#define VKI_FLASK_CREATE 7 +#define VKI_FLASK_RELABEL 8 +#define VKI_FLASK_USER 9 +#define VKI_FLASK_POLICYVERS 10 +#define VKI_FLASK_GETBOOL 11 +#define VKI_FLASK_SETBOOL 12 +#define VKI_FLASK_COMMITBOOLS 13 +#define VKI_FLASK_MLS 14 +#define VKI_FLASK_DISABLE 15 +#define VKI_FLASK_GETAVC_THRESHOLD 16 +#define VKI_FLASK_SETAVC_THRESHOLD 17 +#define VKI_FLASK_AVC_HASHSTATS 18 +#define VKI_FLASK_AVC_CACHESTATS 19 +#define VKI_FLASK_MEMBER 20 +#define VKI_FLASK_ADD_OCONTEXT 21 +#define VKI_FLASK_DEL_OCONTEXT 22 +#define VKI_FLASK_GET_PEER_SID 23 +#define VKI_FLASK_RELABEL_DOMAIN 24 + vki_uint32_t interface_version; /* VKI_XEN_FLASK_INTERFACE_VERSION */ + union { + //struct vki_xen_flask_load load; + //struct vki_xen_flask_setenforce enforce; + /* FLASK_CONTEXT_TO_SID and FLASK_SID_TO_CONTEXT */ + struct vki_xen_flask_sid_context sid_context; + //struct vki_xen_flask_access access; + /* FLASK_CREATE, FLASK_RELABEL, FLASK_MEMBER */ + //struct vki_xen_flask_transition transition; + //struct vki_xen_flask_userlist userlist; + /* FLASK_GETBOOL, FLASK_SETBOOL */ + //struct vki_xen_flask_boolean boolean; + //struct vki_xen_flask_setavc_threshold setavc_threshold; + //struct vki_xen_flask_hash_stats hash_stats; + //struct vki_xen_flask_cache_stats cache_stats; + /* FLASK_ADD_OCONTEXT, FLASK_DEL_OCONTEXT */ + //struct vki_xen_flask_ocontext ocontext; + //struct vki_xen_flask_peersid peersid; + //struct vki_xen_flask_relabel relabel; + } u; +}; + +#endif // __VKI_XEN_XSM_H + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-xen.h b/include/vki/vki-xen.h index cf24ed6664..8812b3e076 100644 --- a/include/vki/vki-xen.h +++ b/include/vki/vki-xen.h @@ -87,6 +87,7 @@ struct vki_xenctl_bitmap { #include #include #include +#include #endif // __VKI_XEN_H -- 2.47.3