diff options
author | Stefan Adolfsson <sadolfsson@chromium.org> | 2018-05-25 14:47:38 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-22 08:16:02 -0700 |
commit | e7bff8f8804e23680ff1fe57062c70debe856d21 (patch) | |
tree | 04fc7efd12b0cc5a129a2957a11dbe66f9dbd802 /test | |
parent | e8252556d52f897f2ea443e1cdd1bb0ebf7174ab (diff) | |
download | chrome-ec-e7bff8f8804e23680ff1fe57062c70debe856d21.tar.gz |
CEC: Add unit tests for buffer handling
Makes sure that we don't have and that we don't introduce
buffer overflows in the CEC buffer handling.
Signed-off-by: Stefan Adolfsson <sadolfsson@chromium.org>
BUG=b:80288314
BRANCH=none
TEST=make -j runtests
Change-Id: Iad5f79add99e2582e60f0d11ed53a27ac67e8b8c
Reviewed-on: https://chromium-review.googlesource.com/1073415
Commit-Ready: Stefan Adolfsson <sadolfsson@chromium.org>
Tested-by: Stefan Adolfsson <sadolfsson@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Zhongze Hu <frankhu@google.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/build.mk | 2 | ||||
-rw-r--r-- | test/cec.c | 132 | ||||
-rw-r--r-- | test/cec.tasklist | 19 | ||||
-rw-r--r-- | test/test_config.h | 4 |
4 files changed, 157 insertions, 0 deletions
diff --git a/test/build.mk b/test/build.mk index 967231684e..4fffada544 100644 --- a/test/build.mk +++ b/test/build.mk @@ -18,6 +18,7 @@ test-list-host += battery_get_params_smart test-list-host += bklight_lid test-list-host += bklight_passthru test-list-host += button +test-list-host += cec test-list-host += charge_manager test-list-host += charge_manager_drp_charging test-list-host += charge_ramp @@ -73,6 +74,7 @@ battery_get_params_smart-y=battery_get_params_smart.o bklight_lid-y=bklight_lid.o bklight_passthru-y=bklight_passthru.o button-y=button.o +cec-y=cec.o charge_manager-y=charge_manager.o charge_manager_drp_charging-y=charge_manager.o charge_ramp-y+=charge_ramp.o diff --git a/test/cec.c b/test/cec.c new file mode 100644 index 0000000000..3487ec1df4 --- /dev/null +++ b/test/cec.c @@ -0,0 +1,132 @@ +/* Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Test the buffer handling of HDMI CEC + */ + +#include <string.h> + +#include "cec.h" +#include "test_util.h" + +struct overflow_msg { + struct cec_msg_transfer transfer; + uint8_t overflow_detector; +} overflow_msg; +/* Ensure the overflow detector is located directly after the buffer */ +BUILD_ASSERT(offsetof(struct overflow_msg, overflow_detector) == + offsetof(struct cec_msg_transfer, buf) + MAX_CEC_MSG_LEN); + + +struct overflow_circbuf { + struct cec_rx_cb circbuf; + uint8_t overflow_detector[CEC_CIRCBUF_SIZE]; +} overflow_circbuf; +/* Ensure the overflow detector is located directly after the buffer */ +BUILD_ASSERT(offsetof(struct overflow_circbuf, overflow_detector) == + offsetof(struct cec_rx_cb, buf) + CEC_CIRCBUF_SIZE); + + +static struct cec_rx_cb *circbuf; + +/* Tests */ +static int test_msg_overflow(void) +{ + int i; + + /* Overwrite the buffer by 1 byte */ + for (i = 0; i < (MAX_CEC_MSG_LEN+1)*8; i++) { + msgt_set_bit(&overflow_msg.transfer, 1); + msgt_inc_bit(&overflow_msg.transfer); + } + + /* Make sure we actually wrote the whole buffer with ones */ + for (i = 0; i < MAX_CEC_MSG_LEN; i++) + TEST_ASSERT(overflow_msg.transfer.buf[i] == 0xff); + + /* Verify that the attempt to overflow the buffer did not succeed */ + TEST_ASSERT(overflow_msg.overflow_detector == 0); + + /* The full indicator is when byte reaches MAX_CEC_MSG_LEN */ + TEST_ASSERT(overflow_msg.transfer.byte == MAX_CEC_MSG_LEN); + + /* Check that the indicator stays the same if we write another byte */ + for (i = 0; i < 8; i++) { + msgt_set_bit(&overflow_msg.transfer, 1); + msgt_inc_bit(&overflow_msg.transfer); + } + TEST_ASSERT(overflow_msg.transfer.byte == MAX_CEC_MSG_LEN); + + return EC_SUCCESS; +} + + + +static int verify_no_circbuf_overflow(void) +{ + int i; + + for (i = 0; i < CEC_CIRCBUF_SIZE; i++) { + if (overflow_circbuf.overflow_detector[i] != 0) + return EC_ERROR_OVERFLOW; + } + return EC_SUCCESS; +} + + +static void clear_circbuf(void) +{ + memset(circbuf, 0, sizeof(struct cec_rx_cb)); + +} + +static int fill_queue(uint8_t *msg, int msg_size) +{ + int i; + + /* + * Fill the queue. Every push adds the message and one extra byte for + * the length field. The maximum data we can add is one less than + * CEC_CIRCBUF_SIZE since write_pointer==read_pointer is used to + * indicate an empty buffer + */ + clear_circbuf(); + + for (i = 0; i < (CEC_CIRCBUF_SIZE - 1)/(msg_size + 1); i++) + TEST_ASSERT(rx_circbuf_push(circbuf, msg, msg_size) == 0); + + /* Now the queue should be full */ + TEST_ASSERT(rx_circbuf_push(circbuf, msg, msg_size) + == EC_ERROR_OVERFLOW); + + /* Verify nothing was written outside of the queue */ + TEST_ASSERT(verify_no_circbuf_overflow() == EC_SUCCESS); + + return EC_SUCCESS; +} + +static int test_circbuf_overflow(void) +{ + uint8_t msg[CEC_CIRCBUF_SIZE]; + + memset(msg, 0xff, sizeof(msg)); + + TEST_ASSERT(fill_queue(msg, 1) == EC_SUCCESS); + TEST_ASSERT(fill_queue(msg, 2) == EC_SUCCESS); + TEST_ASSERT(fill_queue(msg, 3) == EC_SUCCESS); + TEST_ASSERT(fill_queue(msg, MAX_CEC_MSG_LEN) == EC_SUCCESS); + + return EC_SUCCESS; +} + +void run_test(void) +{ + circbuf = &overflow_circbuf.circbuf; + + RUN_TEST(test_msg_overflow); + + RUN_TEST(test_circbuf_overflow); + + test_print_result(); +} diff --git a/test/cec.tasklist b/test/cec.tasklist new file mode 100644 index 0000000000..7015e106a9 --- /dev/null +++ b/test/cec.tasklist @@ -0,0 +1,19 @@ +/* Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Test the buffer handling of HDMI CEC + */ + +/** + * List of enabled tasks in the priority order + * + * The first one has the lowest priority. + * + * For each task, use the macro TASK_TEST(n, r, d, s) where : + * 'n' in the name of the task + * 'r' in the main routine of the task + * 'd' in an opaque parameter passed to the routine at startup + * 's' is the stack size in bytes; must be a multiple of 8 + */ +#define CONFIG_TEST_TASK_LIST /* No test task */ diff --git a/test/test_config.h b/test/test_config.h index 8efe426e38..be1068ac33 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -167,6 +167,10 @@ int ncp15wb_calculate_temp(uint16_t adc); #define I2C_PORT_CHARGER 0 #endif +#ifdef TEST_CEC +#define CONFIG_CEC +#endif + #ifdef TEST_LIGHTBAR #define CONFIG_I2C #define CONFIG_I2C_MASTER |