From f29f1a2a3832aa33863e30c851e6f6565e78ad73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Wed, 25 Sep 2024 16:21:50 -0700 Subject: [PATCH] trusty-ut-ctrl: Allow stream mode When using vsock in stream mode (or any other stream mode connection) message boundaries are not preserved, so the original messages can get both split and merged. The TEST_MESSAGE and TEST_TEXT messages don't have a length field which makes it imposible to support every possible message that can be sent over a channel that preserves message boundaries. Since the current message header types don't contain any printable character, we assume any of these characters in a message payload means that two messages got merged, so we split them back up. Additionally, if we receive a message that does not start with a valid message header, we assume it is a continuation of the previous message. Test: trusty-ut-ctrl -D VSOCK:2:1 com.android.libctest ^Z fg Bug: 298705967 Change-Id: I0e470a23664268f86e4defd824c47be3479c8f25 --- trusty/utils/trusty-ut-ctrl/ut-ctrl.c | 57 +++++++++++++++++++++------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/trusty/utils/trusty-ut-ctrl/ut-ctrl.c b/trusty/utils/trusty-ut-ctrl/ut-ctrl.c index 6cc66707e..31cfd4c79 100644 --- a/trusty/utils/trusty-ut-ctrl/ut-ctrl.c +++ b/trusty/utils/trusty-ut-ctrl/ut-ctrl.c @@ -95,12 +95,26 @@ enum test_message_header { TEST_FAILED = 1, TEST_MESSAGE = 2, TEST_TEXT = 3, + TEST_OPCODE_COUNT, }; +static int get_msg_len(const char* buf, int max_buf_len) { + int buf_len; + for (buf_len = 0; buf_len < max_buf_len; buf_len++) { + if ((unsigned char)buf[buf_len] < TEST_OPCODE_COUNT) { + break; + } + } + return buf_len; +} + static int run_trusty_unitest(const char* utapp) { int fd; - int rc; - char rx_buf[1024]; + char read_buf[1024]; + int read_len; + char* rx_buf; + int rx_buf_len; + int cmd = -1; /* connect to unitest app */ fd = tipc_connect(dev_name, utapp); @@ -110,22 +124,39 @@ static int run_trusty_unitest(const char* utapp) { } /* wait for test to complete */ + rx_buf_len = 0; for (;;) { - rc = read(fd, rx_buf, sizeof(rx_buf)); - if (rc <= 0 || rc >= (int)sizeof(rx_buf)) { - fprintf(stderr, "%s: Read failed: %d\n", __func__, rc); - tipc_close(fd); - return -1; + if (rx_buf_len == 0) { + read_len = read(fd, read_buf, sizeof(read_buf)); + if (read_len <= 0 || read_len > (int)sizeof(read_buf)) { + fprintf(stderr, "%s: Read failed: %d, %s\n", __func__, read_len, + read_len < 0 ? strerror(errno) : ""); + tipc_close(fd); + return -1; + } + rx_buf = read_buf; + rx_buf_len = read_len; } - if (rx_buf[0] == TEST_PASSED) { + int msg_len = get_msg_len(rx_buf, rx_buf_len); + if (msg_len == 0) { + cmd = rx_buf[0]; + rx_buf++; + rx_buf_len--; + } + + if (cmd == TEST_PASSED) { break; - } else if (rx_buf[0] == TEST_FAILED) { + } else if (cmd == TEST_FAILED) { break; - } else if (rx_buf[0] == TEST_MESSAGE || rx_buf[0] == TEST_TEXT) { - write(STDOUT_FILENO, rx_buf + 1, rc - 1); + } else if (cmd == TEST_MESSAGE || cmd == TEST_TEXT) { + if (msg_len) { + write(STDOUT_FILENO, rx_buf, msg_len); + rx_buf += msg_len; + rx_buf_len -= msg_len; + } } else { - fprintf(stderr, "%s: Bad message header: %d\n", __func__, rx_buf[0]); + fprintf(stderr, "%s: Bad message header: %d\n", __func__, cmd); break; } } @@ -133,7 +164,7 @@ static int run_trusty_unitest(const char* utapp) { /* close connection to unitest app */ tipc_close(fd); - return rx_buf[0] == TEST_PASSED ? 0 : -1; + return cmd == TEST_PASSED ? 0 : -1; } int main(int argc, char** argv) {