From 185fb56a5f7384e0a4a29b7cd76fcc786f26de51 Mon Sep 17 00:00:00 2001 From: Christopher Clark Date: Wed, 18 Sep 2019 10:35:53 -0700 Subject: [PATCH 1/3] xen: Add missing dummy XSM code to init quiet Argo XSM check The recent change to quiet the AVC issued when a domain does not have XSM argo enabled unfortunately omitted a change to add initialization logic to the dummy policy, so when running with the dummy policy active, it results in a crash in Xen on boot. This change adds the needed initialization. Fixes OXT-1692. Signed-off-by: Christopher Clark --- .../xen/files/argo-quiet-xsm-check-during-init.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/recipes-extended/xen/files/argo-quiet-xsm-check-during-init.patch b/recipes-extended/xen/files/argo-quiet-xsm-check-during-init.patch index 54b650657d..afc7d73440 100644 --- a/recipes-extended/xen/files/argo-quiet-xsm-check-during-init.patch +++ b/recipes-extended/xen/files/argo-quiet-xsm-check-during-init.patch @@ -92,3 +92,13 @@ Signed-off-by: Jason Andryuk .argo_register_single_source = flask_argo_register_single_source, .argo_register_any_source = flask_argo_register_any_source, .argo_send = flask_argo_send, +--- a/xen/xsm/dummy.c ++++ b/xen/xsm/dummy.c +@@ -155,6 +155,7 @@ void __init xsm_fixup_ops (struct xsm_operations *ops) + set_to_dummy_if_null(ops, domain_resource_map); + #ifdef CONFIG_ARGO + set_to_dummy_if_null(ops, argo_enable); ++ set_to_dummy_if_null(ops, argo_enable_noaudit); + set_to_dummy_if_null(ops, argo_register_single_source); + set_to_dummy_if_null(ops, argo_register_any_source); + set_to_dummy_if_null(ops, argo_send); From 6836b2f500c05c3d283a31da362efc2657b8939c Mon Sep 17 00:00:00 2001 From: Christopher Clark Date: Tue, 13 Aug 2019 18:41:35 -0700 Subject: [PATCH 2/3] OXT-1503: [xen] [argo] [xsm] transmit XSM sid in message header Convey the peer Flask label of a communicating domain by introducing the 32-bit Flask SID in the xen_argo_ring_message_header that is delivered with each Argo message. To retain the existing size of the message header while adding this 32-bit field the message_type field is resized from 32 to 8 bits and a 16-bit padding field is removed. 8-bits of padding remain. This is an ABI change and a corresponding update to the Linux Argo device driver is required. Signed-off-by: Christopher Clark --- .../xen/files/argo-xmit-xsm-context.patch | 220 ++++++++++++++++++ recipes-extended/xen/xen-common.inc | 1 + 2 files changed, 221 insertions(+) create mode 100644 recipes-extended/xen/files/argo-xmit-xsm-context.patch diff --git a/recipes-extended/xen/files/argo-xmit-xsm-context.patch b/recipes-extended/xen/files/argo-xmit-xsm-context.patch new file mode 100644 index 0000000000..ada9d2480b --- /dev/null +++ b/recipes-extended/xen/files/argo-xmit-xsm-context.patch @@ -0,0 +1,220 @@ +################################################################################ +SHORT DESCRIPTION: +################################################################################ +Enable transmission of a domain's XSM sid value in the message header of Argo +messages between domains. + +################################################################################ +LONG DESCRIPTION: +################################################################################ +argo, xsm: provide XSM sid as sender domain context in message header + +Adds a Flask hook to retrieve the value of the domain's sid to transmit. + +In order to fit the additional 32-bit sid value in the message header +without changing its size, the message_type field is reduced from 32 +to 8 bits, which is sufficient to handle existing use cases for the +field, and a 16 bit padding field is removed by switching from +use of a xen_argo_addr struct to individual source domain and port +fields. These changes leave 8 bits unused within the new header, now +marked as a pad field to be zeroed, reserved for later use. + +This change of ABI alters the sendv op arguments and the message +format in the ring. + +Signed-off-by: Christopher Clark + + xen/common/argo.c | 18 ++++++++++-------- + xen/include/public/argo.h | 11 +++++++---- + xen/include/xsm/dummy.h | 5 +++++ + xen/include/xsm/xsm.h | 6 ++++++ + xen/xsm/dummy.c | 1 + + xen/xsm/flask/hooks.c | 5 +++++ + 6 files changed, 34 insertions(+), 12 deletions(-) + +################################################################################ +CHANGELOG +################################################################################ + +################################################################################ +REMOVAL +################################################################################ +Remove when upstreamed. + +################################################################################ +UPSTREAM PLAN +################################################################################ +For development and validation in OpenXT with related components and then to be +upstreamed. + +################################################################################ +INTERNAL DEPENDENCIES +################################################################################ +This patch implements an ABI change, so the Linux Argo device driver has a +corresponding patch to match this one. + +################################################################################ +PATCHES +################################################################################ +--- a/xen/common/argo.c ++++ b/xen/common/argo.c +@@ -765,7 +765,7 @@ iov_count(const xen_argo_iov_t *piov, unsigned int niov, + static int + ringbuf_insert(const struct domain *d, struct argo_ring_info *ring_info, + const struct argo_ring_id *src_id, xen_argo_iov_t *iovs, +- unsigned int niov, uint32_t message_type, unsigned int len) ++ unsigned int niov, uint8_t message_type, unsigned int len) + { + xen_argo_ring_t ring; + struct xen_argo_ring_message_header mh = { }; +@@ -819,9 +819,11 @@ ringbuf_insert(const struct domain *d, struct argo_ring_info *ring_info, + } + + mh.len = len + sizeof(struct xen_argo_ring_message_header); +- mh.source.aport = src_id->aport; +- mh.source.domain_id = src_id->domain_id; ++ mh.src_aport = src_id->aport; ++ mh.src_domain_id = src_id->domain_id; + mh.message_type = message_type; ++ mh.src_sid = xsm_argo_domain_sid(d); ++ mh.pad = 0; + + /* + * For this copy to the guest ring, tx_ptr is always 16-byte aligned +@@ -1960,7 +1962,7 @@ notify(struct domain *currd, + static long + sendv(struct domain *src_d, xen_argo_addr_t *src_addr, + const xen_argo_addr_t *dst_addr, xen_argo_iov_t *iovs, unsigned int niov, +- uint32_t message_type) ++ uint8_t message_type) + { + struct domain *dst_d = NULL; + struct argo_ring_id src_id; +@@ -1968,7 +1970,7 @@ sendv(struct domain *src_d, xen_argo_addr_t *src_addr, + int ret = 0; + unsigned int len = 0; + +- argo_dprintk("sendv: (%u:%x)->(%u:%x) niov:%u type:%x\n", ++ argo_dprintk("sendv: (%u:%x)->(%u:%x) niov:%u type:%o\n", + src_addr->domain_id, src_addr->aport, dst_addr->domain_id, + dst_addr->aport, niov, message_type); + +@@ -2150,7 +2152,7 @@ do_argo_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) arg1, + XEN_GUEST_HANDLE_PARAM(xen_argo_iov_t) iovs_hnd = + guest_handle_cast(arg2, xen_argo_iov_t); + /* arg3 is niov */ +- /* arg4 is message_type. Must be a 32-bit value. */ ++ /* arg4 is message_type. Must be a 8-bit value. */ + + /* XEN_ARGO_MAXIOV value determines size of iov array on stack */ + BUILD_BUG_ON(XEN_ARGO_MAXIOV > 8); +@@ -2164,9 +2166,9 @@ do_argo_op(unsigned int cmd, XEN_GUEST_HANDLE_PARAM(void) arg1, + + /* + * Reject niov above maximum limit or message_types that are outside +- * 32 bit range. ++ * 8 bit range. + */ +- if ( unlikely((arg3 > XEN_ARGO_MAXIOV) || (arg4 != (uint32_t)arg4)) ) ++ if ( unlikely((arg3 > XEN_ARGO_MAXIOV) || (arg4 != (uint8_t)arg4)) ) + { + rc = -EINVAL; + break; +--- a/xen/include/public/argo.h ++++ b/xen/include/public/argo.h +@@ -146,8 +146,11 @@ typedef struct xen_argo_ring_data + struct xen_argo_ring_message_header + { + uint32_t len; +- struct xen_argo_addr source; +- uint32_t message_type; ++ uint8_t pad; ++ uint8_t message_type; ++ domid_t src_domain_id; ++ xen_argo_port_t src_aport; ++ uint32_t src_sid; + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + uint8_t data[]; + #elif defined(__GNUC__) +@@ -223,13 +226,13 @@ struct xen_argo_ring_message_header + * If insufficient space exists in the destination ring, it will return -EAGAIN + * and Xen will notify the caller when sufficient space becomes available. + * +- * The message type is a 32-bit data field available to communicate message ++ * The message type is a 8-bit data field available to communicate message + * context data (eg. kernel-to-kernel, rather than application layer). + * + * arg1: XEN_GUEST_HANDLE(xen_argo_send_addr_t) source and dest addresses + * arg2: XEN_GUEST_HANDLE(xen_argo_iov_t) iovs + * arg3: unsigned long niov +- * arg4: unsigned long message type (32-bit value) ++ * arg4: unsigned long message type (8-bit value) + */ + #define XEN_ARGO_OP_sendv 3 + +--- a/xen/include/xsm/dummy.h ++++ b/xen/include/xsm/dummy.h +@@ -737,6 +737,11 @@ static XSM_INLINE int xsm_argo_send(const struct domain *d, + return 0; + } + ++static XSM_INLINE uint32_t xsm_argo_domain_sid(const struct domain *d) ++{ ++ return 0; ++} ++ + #endif /* CONFIG_ARGO */ + + #include +--- a/xen/include/xsm/xsm.h ++++ b/xen/include/xsm/xsm.h +@@ -186,6 +186,7 @@ struct xsm_operations { + const struct domain *t); + int (*argo_register_any_source) (const struct domain *d); + int (*argo_send) (const struct domain *d, const struct domain *t); ++ uint32_t (*argo_domain_sid) (const struct domain *d); + #endif + }; + +@@ -721,6 +722,11 @@ static inline int xsm_argo_send(const struct domain *d, const struct domain *t) + return xsm_ops->argo_send(d, t); + } + ++static inline uint32_t xsm_argo_domain_sid(const struct domain *d) ++{ ++ return xsm_ops->argo_domain_sid(d); ++} ++ + #endif /* CONFIG_ARGO */ + + #endif /* XSM_NO_WRAPPERS */ +--- a/xen/xsm/dummy.c ++++ b/xen/xsm/dummy.c +@@ -156,5 +156,6 @@ void __init xsm_fixup_ops (struct xsm_operations *ops) + set_to_dummy_if_null(ops, argo_register_single_source); + set_to_dummy_if_null(ops, argo_register_any_source); + set_to_dummy_if_null(ops, argo_send); ++ set_to_dummy_if_null(ops, argo_domain_sid); + #endif + } +--- a/xen/xsm/flask/hooks.c ++++ b/xen/xsm/flask/hooks.c +@@ -1736,6 +1736,10 @@ static int flask_argo_send(const struct domain *d, const struct domain *t) + return domain_has_perm(d, t, SECCLASS_ARGO, ARGO__SEND); + } + ++static uint32_t flask_argo_domain_sid(const struct domain *d) ++{ ++ return domain_sid(d); ++} + #endif + + long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); +@@ -1876,6 +1880,7 @@ static struct xsm_operations flask_ops = { + .argo_register_single_source = flask_argo_register_single_source, + .argo_register_any_source = flask_argo_register_any_source, + .argo_send = flask_argo_send, ++ .argo_domain_sid = flask_argo_domain_sid, + #endif + }; + diff --git a/recipes-extended/xen/xen-common.inc b/recipes-extended/xen/xen-common.inc index a0eca3c555..462051b01e 100644 --- a/recipes-extended/xen/xen-common.inc +++ b/recipes-extended/xen/xen-common.inc @@ -99,6 +99,7 @@ SRC_URI_append = " \ file://argo-fix-full-ring-write-bug.patch \ file://argo-fix-requeue-msg-len-bug.patch \ file://argo-quiet-xsm-check-during-init.patch \ + file://argo-xmit-xsm-context.patch \ file://libxl-seabios-ipxe.patch \ file://memory-scrub-on-domain-shutdown.patch \ " From 479a941f0121baafea1149c100e38a42a6e3f3a5 Mon Sep 17 00:00:00 2001 From: Christopher Clark Date: Tue, 13 Aug 2019 19:33:21 -0700 Subject: [PATCH 3/3] OXT-1503: Linux Argo support for xmit of XSM/Flask SID in msg header Updates the Linux device driver to a revised Argo ABI where the XSM/Flask SID of the sender domain is conveyed with each message. The ring message header has been changed to accommodate the new data and the message_type field is reduced in size to 8-bits. Stream and datagram protocol indicator values are redefined to within the 8-bit range. Works in conjunction with the corresponding patch for Xen. Signed-off-by: Christopher Clark --- .../linux-argo-xmit-xsm-context.patch | 206 ++++++++++++++++++ recipes-openxt/argo-module/argo-module_git.bb | 3 +- 2 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 recipes-openxt/argo-module/argo-module/linux-argo-xmit-xsm-context.patch diff --git a/recipes-openxt/argo-module/argo-module/linux-argo-xmit-xsm-context.patch b/recipes-openxt/argo-module/argo-module/linux-argo-xmit-xsm-context.patch new file mode 100644 index 0000000000..017376dbef --- /dev/null +++ b/recipes-openxt/argo-module/argo-module/linux-argo-xmit-xsm-context.patch @@ -0,0 +1,206 @@ +From 9b019db98c2c52d9c34b1734e82b878417a3c89c Mon Sep 17 00:00:00 2001 +From: Christopher Clark +Date: Wed, 14 Aug 2019 14:56:35 -0700 +Subject: [PATCH] OXT-1503: Update the argo-linux driver to new Argo ABI with + XSM sid in message header + +Handles the changes to the Argo message header format and sendv operation +arguments for the ABI change to indicate XSM/Flask SID in Argo messages: +the message_type field has been reduced in size to 8 bits from 32 bits, +and the message source domain and port fields are now standalone rather +than within a xen_argo_addr struct. + +Since the message_type field, which is used to indicate the protocol that +is in use between driver endpoints -- ie. either datagram or stream -- has +decreased in size, the protocol indicator values for dgram and stream are +changed to new values within the 8-bit range. + +Signed-off-by: Christopher Clark + + argo-module.c | 43 ++++++++++++++++++++----------------------- + include/xen/argo.h | 11 +++++++---- + 2 files changed, 27 insertions(+), 27 deletions(-) + +--- a/argo-module.c ++++ b/argo-module.c +@@ -236,8 +236,8 @@ static struct list_head ring_list; + #define ARGO_SHF_PING (1 << 8) + #define ARGO_SHF_PONG (1 << 9) + +-#define ARGO_PROTO_DGRAM 0x6447724d +-#define ARGO_PROTO_STREAM 0x3574526d ++#define ARGO_PROTO_DGRAM 0x01 ++#define ARGO_PROTO_STREAM 0x02 + + struct argo_stream_header + { +@@ -263,7 +263,7 @@ argo_ring_bytes_to_read(volatile struct xen_argo_ring *r, uint32_t ring_size) + */ + static ssize_t + argo_copy_out(struct xen_argo_ring *r, uint32_t ring_size, +- struct xen_argo_addr *from, uint32_t * protocol, ++ struct xen_argo_addr *from, uint8_t *protocol, + void *_buf, size_t t, int consume) + { + volatile struct xen_argo_ring_message_header *mh; +@@ -288,15 +288,12 @@ argo_copy_out(struct xen_argo_ring *r, uint32_t ring_size, + if ( btr < len ) + return -1; + +-#if defined(__GNUC__) + if ( from ) +- *from = mh->source; +-#else +- /* MSVC can't do the above */ +- if ( from ) +- memcpy((void *) from, (void *) &(mh->source), +- sizeof(struct xen_argo_addr)); +-#endif ++ { ++ from->aport = mh->src_aport; ++ from->domain_id = mh->src_domain_id; ++ from->pad = 0; ++ } + + if ( protocol ) + *protocol = mh->message_type; +@@ -447,7 +444,7 @@ struct pending_xmit + struct argo_ring_id from; + xen_argo_addr_t to; + size_t len; +- uint32_t protocol; ++ uint8_t protocol; + uint8_t data[0]; + }; + +@@ -683,7 +680,7 @@ H_argo_unregister_ring (xen_argo_unregister_ring_t *r) + static int + H_argo_sendv(xen_argo_addr_t *s, xen_argo_addr_t *d, + const xen_argo_iov_t *iovs, uint32_t niov, +- uint32_t protocol) ++ uint8_t protocol) + { + xen_argo_send_addr_t send; + send.dst = *d; +@@ -1242,7 +1239,7 @@ xmit_queue_wakeup_sponsor(struct argo_ring_id *from, xen_argo_addr_t * to, int l + + static int + xmit_queue_inline(struct argo_ring_id *from, xen_argo_addr_t *to, +- void *buf, size_t len, uint32_t protocol) ++ void *buf, size_t len, uint8_t protocol) + { + ssize_t ret; + unsigned long flags; +@@ -1656,7 +1653,7 @@ static int + connector_interrupt(struct ring *r) + { + ssize_t msg_len; +- uint32_t protocol; ++ uint8_t protocol; + struct argo_stream_header sh; + xen_argo_addr_t from; + int ret = 0; +@@ -1762,7 +1759,7 @@ listener_interrupt(struct ring *r) + { + int ret = 0; + ssize_t msg_len; +- uint32_t protocol; ++ uint8_t protocol; + struct argo_stream_header sh; + struct argo_private *p; + xen_argo_addr_t from; +@@ -2033,7 +2030,7 @@ static int stream_connected(struct argo_private *p) + + static size_t + argo_try_send_sponsor(struct argo_private *p, xen_argo_addr_t *dest, +- const void *buf, size_t len, uint32_t protocol) ++ const void *buf, size_t len, uint8_t protocol) + { + size_t ret; + unsigned long flags; +@@ -2085,7 +2082,7 @@ static size_t + argo_try_sendv_sponsor(struct argo_private *p, + xen_argo_addr_t * dest, + const xen_argo_iov_t *iovs, size_t niov, size_t len, +- uint32_t protocol) ++ uint8_t protocol) + { + size_t ret; + unsigned long flags; +@@ -2135,7 +2132,7 @@ argo_try_sendv_sponsor(struct argo_private *p, + static size_t + argo_try_sendv_privates(struct argo_private *p, xen_argo_addr_t * dest, + const xen_argo_iov_t * iovs, size_t niov, size_t len, +- uint32_t protocol) ++ uint8_t protocol) + { + size_t ret; + unsigned long flags; +@@ -2169,7 +2166,7 @@ static ssize_t + argo_sendto_from_sponsor(struct argo_private *p, + const void *buf, size_t len, + int nonblock, xen_argo_addr_t *dest, +- uint32_t protocol) ++ uint8_t protocol) + { + size_t ret = 0, ts_ret; + +@@ -2245,7 +2242,7 @@ argo_sendto_from_sponsor(struct argo_private *p, + static ssize_t + argo_stream_sendvto_from_sponsor(struct argo_private *p, + const xen_argo_iov_t *iovs, size_t niov, size_t len, +- int nonblock, xen_argo_addr_t * dest, uint32_t protocol) ++ int nonblock, xen_argo_addr_t * dest, uint8_t protocol) + { + size_t ret = 0, ts_ret; + +@@ -2315,7 +2312,7 @@ argo_stream_sendvto_from_sponsor(struct argo_private *p, + static ssize_t + argo_stream_sendvto_from_private (struct argo_private *p, + const xen_argo_iov_t * iovs, size_t niov, size_t len, +- int nonblock, xen_argo_addr_t *dest, uint32_t protocol) ++ int nonblock, xen_argo_addr_t *dest, uint8_t protocol) + { + size_t ret = 0, ts_ret; + +@@ -2453,7 +2450,7 @@ argo_recvfrom_dgram(struct argo_private *p, void *buf, size_t len, + int nonblock, int peek, xen_argo_addr_t *src) + { + ssize_t ret; +- uint32_t protocol; ++ uint8_t protocol; + xen_argo_addr_t lsrc; + + if (!src) +--- a/include/xen/argo.h ++++ b/include/xen/argo.h +@@ -159,8 +159,11 @@ typedef struct xen_argo_ring_data + struct xen_argo_ring_message_header + { + uint32_t len; +- struct xen_argo_addr source; +- uint32_t message_type; ++ uint8_t pad; ++ uint8_t message_type; ++ domid_t src_domain_id; ++ xen_argo_port_t src_aport; ++ uint32_t src_sid; + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + uint8_t data[]; + #elif defined(__GNUC__) +@@ -251,13 +254,13 @@ typedef struct xen_argo_viptables_list + * If insufficient space exists in the destination ring, it will return -EAGAIN + * and Xen will notify the caller when sufficient space becomes available. + * +- * The message type is a 32-bit data field available to communicate message ++ * The message type is a 8-bit data field available to communicate message + * context data (eg. kernel-to-kernel, rather than application layer). + * + * arg1: XEN_GUEST_HANDLE(xen_argo_send_addr_t) source and dest addresses + * arg2: XEN_GUEST_HANDLE(xen_argo_iov_t) iovs + * arg3: unsigned long niov +- * arg4: unsigned long message type (32-bit value) ++ * arg4: unsigned long message type (8-bit value) + */ + #define XEN_ARGO_OP_sendv 3 + diff --git a/recipes-openxt/argo-module/argo-module_git.bb b/recipes-openxt/argo-module/argo-module_git.bb index 6644bb4c08..cb7421b48d 100644 --- a/recipes-openxt/argo-module/argo-module_git.bb +++ b/recipes-openxt/argo-module/argo-module_git.bb @@ -9,7 +9,8 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=4641e94ec96f98fabc56ff9cc48be14b" PV = "git${SRCPV}" -SRC_URI = "git://${OPENXT_GIT_MIRROR}/linux-xen-argo.git;protocol=${OPENXT_GIT_PROTOCOL};branch=${OPENXT_BRANCH}" +SRC_URI = "git://${OPENXT_GIT_MIRROR}/linux-xen-argo.git;protocol=${OPENXT_GIT_PROTOCOL};branch=${OPENXT_BRANCH} \ + file://linux-argo-xmit-xsm-context.patch" SRCREV = "${AUTOREV}" S = "${WORKDIR}/git/argo-linux"