From a035475031e1e04e19b1757145591753647ad9c5 Mon Sep 17 00:00:00 2001 From: Liu Yuan Date: Thu, 12 Apr 2018 18:06:35 +0800 Subject: [PATCH] IOC mediator: support IOC signal whitelist This patch implements the signal whitelist feature. All the signal messages will be discarded if they are not existed in whitelist. Signed-off-by: Liu Yuan Reviewed-by: Wang Yu Reviewed-by: Liu Shuo Reviewed-by: Zhao Yakui Acked-by: Eddie Dong --- hw/platform/ioc.c | 14 +++++++ hw/platform/ioc_cbc.c | 86 ++++++++++++++++++++++++++++++++++++++++++- include/ioc.h | 6 +++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/hw/platform/ioc.c b/hw/platform/ioc.c index c12aeb0ab..634d609b2 100644 --- a/hw/platform/ioc.c +++ b/hw/platform/ioc.c @@ -1183,6 +1183,20 @@ ioc_init(void) if (ioc_ch_init(ioc) != 0) goto chl_err; + /* Initlialize CBC rx/tx signal and group whitelists */ + wlist_init_signal(cbc_rx_signal_table, ARRAY_SIZE(cbc_rx_signal_table), + wlist_rx_signal_table, + ARRAY_SIZE(wlist_rx_signal_table)); + wlist_init_group(cbc_rx_group_table, ARRAY_SIZE(cbc_rx_group_table), + wlist_rx_group_table, + ARRAY_SIZE(wlist_rx_group_table)); + wlist_init_signal(cbc_tx_signal_table, ARRAY_SIZE(cbc_tx_signal_table), + wlist_tx_signal_table, + ARRAY_SIZE(wlist_tx_signal_table)); + wlist_init_group(cbc_tx_group_table, ARRAY_SIZE(cbc_tx_group_table), + wlist_tx_group_table, + ARRAY_SIZE(wlist_tx_group_table)); + /* Setup IOC rx members */ snprintf(ioc->rx_name, sizeof(ioc->rx_name), "ioc_rx"); ioc->ioc_dev_rx = cbc_rx_handler; diff --git a/hw/platform/ioc_cbc.c b/hw/platform/ioc_cbc.c index 159a0ce64..07851c6be 100644 --- a/hw/platform/ioc_cbc.c +++ b/hw/platform/ioc_cbc.c @@ -308,13 +308,47 @@ cbc_disable_signal_group(uint16_t id, struct cbc_group *table, size_t size) p->flag = CBC_INACTIVE; } +/* + * Search one cbc_signal with signal id in the whitelist table. + */ +static struct cbc_signal * +wlist_find_signal(uint16_t id, struct wlist_signal *list, size_t size) +{ + int i; + + for (i = 0; i < size; i++) { + if (id == list[i].id) + return list[i].sig; + } + return NULL; +} + +/* + * Search one cbc_group with group id in the whitelist table. + */ +static struct +cbc_group *wlist_find_group(uint16_t id, struct wlist_group *list, size_t size) +{ + int i; + + for (i = 0; i < size; i++) { + if (id == list[i].id) + return list[i].grp; + } + return NULL; +} + /* * Whitelist verification for a signal. */ static int wlist_verify_signal(uint16_t id, struct wlist_signal *list, size_t size) { - /* TODO: implementation */ + struct cbc_signal *sig; + + sig = wlist_find_signal(id, list, size); + if (!sig || sig->flag == CBC_INACTIVE) + return -1; return 0; } @@ -324,7 +358,11 @@ wlist_verify_signal(uint16_t id, struct wlist_signal *list, size_t size) static int wlist_verify_group(uint16_t id, struct wlist_group *list, size_t size) { - /* TODO: implementation */ + struct cbc_group *grp; + + grp = wlist_find_group(id, list, size); + if (!grp || grp->flag == CBC_INACTIVE) + return -1; return 0; } @@ -813,3 +851,47 @@ cbc_tx_handler(struct cbc_pkt *pkt) pkt->req->rtype); } } + +/* + * Initialize whitelist node with cbc_group, + * so that whitelist can access cbc_group flag via group id. + */ +void +wlist_init_group(struct cbc_group *cbc_tbl, size_t cbc_size, + struct wlist_group *wlist_tbl, size_t wlist_size) +{ + int i, j; + + if (!cbc_tbl || cbc_size == 0 || !wlist_tbl || wlist_size == 0) + return; + for (i = 0; i < wlist_size; i++) { + for (j = 0; j < cbc_size; j++) { + if (wlist_tbl[i].id == cbc_tbl[j].id) { + wlist_tbl[i].grp = &cbc_tbl[j]; + break; + } + } + } +} + +/* + * Initialize whitelist node with cbc_signal, + * so that whitelist can access cbc_signal flag via signal id. + */ +void +wlist_init_signal(struct cbc_signal *cbc_tbl, size_t cbc_size, + struct wlist_signal *wlist_tbl, size_t wlist_size) +{ + int i, j; + + if (!cbc_tbl || cbc_size == 0 || !wlist_tbl || wlist_size == 0) + return; + for (i = 0; i < wlist_size; i++) { + for (j = 0; j < cbc_size; j++) { + if (wlist_tbl[i].id == cbc_tbl[j].id) { + wlist_tbl[i].sig = &cbc_tbl[j]; + break; + } + } + } +} diff --git a/include/ioc.h b/include/ioc.h index 815b530b6..49b0ed5c4 100644 --- a/include/ioc.h +++ b/include/ioc.h @@ -729,4 +729,10 @@ int cbc_copy_to_ring(const uint8_t *buf, size_t size, struct cbc_ring *ring); /* Build a cbc_request based on CBC link layer protocol */ void cbc_unpack_link(struct ioc_dev *ioc); + +/* Whitelist initialization */ +void wlist_init_signal(struct cbc_signal *cbc_tbl, size_t cbc_size, + struct wlist_signal *wlist_tbl, size_t wlist_size); +void wlist_init_group(struct cbc_group *cbc_tbl, size_t cbc_size, + struct wlist_group *wlist_tbl, size_t wlist_size); #endif