diff options
| author | Stefan Kerkmann <karlk90@pm.me> | 2022-08-06 10:46:59 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-06 18:46:59 +1000 |
| commit | ed9bdcbc3608819e17ff7a11221e651bf51ec1cc (patch) | |
| tree | 36e87885a316d67edc7fe64a04ca0db90c890e4c /quantum/split_common | |
| parent | cac704241404908794514b7a534e58c96aff4d6b (diff) | |
[Core] guard RPC invocation by checking RPC info against crc checksum (#17840)
Diffstat (limited to 'quantum/split_common')
| -rw-r--r-- | quantum/split_common/transactions.c | 18 | ||||
| -rw-r--r-- | quantum/split_common/transport.h | 9 |
2 files changed, 18 insertions, 9 deletions
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index 9e3df534e3..719068908f 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c | |||
| @@ -694,7 +694,7 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { | |||
| 694 | #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | 694 | #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) |
| 695 | [PUT_RPC_INFO] = trans_initiator2target_initializer_cb(rpc_info, slave_rpc_info_callback), | 695 | [PUT_RPC_INFO] = trans_initiator2target_initializer_cb(rpc_info, slave_rpc_info_callback), |
| 696 | [PUT_RPC_REQ_DATA] = trans_initiator2target_initializer(rpc_m2s_buffer), | 696 | [PUT_RPC_REQ_DATA] = trans_initiator2target_initializer(rpc_m2s_buffer), |
| 697 | [EXECUTE_RPC] = trans_initiator2target_initializer_cb(rpc_info.transaction_id, slave_rpc_exec_callback), | 697 | [EXECUTE_RPC] = trans_initiator2target_initializer_cb(rpc_info.payload.transaction_id, slave_rpc_exec_callback), |
| 698 | [GET_RPC_RESP_DATA] = trans_target2initiator_initializer(rpc_s2m_buffer), | 698 | [GET_RPC_RESP_DATA] = trans_target2initiator_initializer(rpc_s2m_buffer), |
| 699 | #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | 699 | #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) |
| 700 | }; | 700 | }; |
| @@ -760,7 +760,8 @@ bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer | |||
| 760 | if (target2initiator_buffer_size > RPC_S2M_BUFFER_SIZE) return false; | 760 | if (target2initiator_buffer_size > RPC_S2M_BUFFER_SIZE) return false; |
| 761 | 761 | ||
| 762 | // Prepare the metadata block | 762 | // Prepare the metadata block |
| 763 | rpc_sync_info_t info = {.transaction_id = transaction_id, .m2s_length = initiator2target_buffer_size, .s2m_length = target2initiator_buffer_size}; | 763 | rpc_sync_info_t info = {.payload = {.transaction_id = transaction_id, .m2s_length = initiator2target_buffer_size, .s2m_length = target2initiator_buffer_size}}; |
| 764 | info.checksum = crc8(&info.payload, sizeof(info.payload)); | ||
| 764 | 765 | ||
| 765 | // Make sure the local side knows that we're not sending the full block of data | 766 | // Make sure the local side knows that we're not sending the full block of data |
| 766 | split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = initiator2target_buffer_size; | 767 | split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = initiator2target_buffer_size; |
| @@ -791,18 +792,23 @@ void slave_rpc_info_callback(uint8_t initiator2target_buffer_size, const void *i | |||
| 791 | // Ignore the args -- the `split_shmem` already has the info, we just need to act upon it. | 792 | // Ignore the args -- the `split_shmem` already has the info, we just need to act upon it. |
| 792 | // We must keep the `split_transaction_table` non-const, so that it is able to be modified at runtime. | 793 | // We must keep the `split_transaction_table` non-const, so that it is able to be modified at runtime. |
| 793 | 794 | ||
| 794 | split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = split_shmem->rpc_info.m2s_length; | 795 | split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = split_shmem->rpc_info.payload.m2s_length; |
| 795 | split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = split_shmem->rpc_info.s2m_length; | 796 | split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = split_shmem->rpc_info.payload.s2m_length; |
| 796 | } | 797 | } |
| 797 | 798 | ||
| 798 | void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { | 799 | void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { |
| 799 | // We can assume that the buffer lengths are correctly set, now, given that sequentially the rpc_info callback was already executed. | 800 | // We can assume that the buffer lengths are correctly set, now, given that sequentially the rpc_info callback was already executed. |
| 800 | // Go through the rpc_info and execute _that_ transaction's callback, with the scratch buffers as inputs. | 801 | // Go through the rpc_info and execute _that_ transaction's callback, with the scratch buffers as inputs. |
| 801 | int8_t transaction_id = split_shmem->rpc_info.transaction_id; | 802 | // As a safety precaution we check that the received payload matches its checksum first. |
| 803 | if (crc8(&split_shmem->rpc_info.payload, sizeof(split_shmem->rpc_info.payload)) != split_shmem->rpc_info.checksum) { | ||
| 804 | return; | ||
| 805 | } | ||
| 806 | |||
| 807 | int8_t transaction_id = split_shmem->rpc_info.payload.transaction_id; | ||
| 802 | if (transaction_id < NUM_TOTAL_TRANSACTIONS) { | 808 | if (transaction_id < NUM_TOTAL_TRANSACTIONS) { |
| 803 | split_transaction_desc_t *trans = &split_transaction_table[transaction_id]; | 809 | split_transaction_desc_t *trans = &split_transaction_table[transaction_id]; |
| 804 | if (trans->slave_callback) { | 810 | if (trans->slave_callback) { |
| 805 | trans->slave_callback(split_shmem->rpc_info.m2s_length, split_shmem->rpc_m2s_buffer, split_shmem->rpc_info.s2m_length, split_shmem->rpc_s2m_buffer); | 811 | trans->slave_callback(split_shmem->rpc_info.payload.m2s_length, split_shmem->rpc_m2s_buffer, split_shmem->rpc_info.payload.s2m_length, split_shmem->rpc_s2m_buffer); |
| 806 | } | 812 | } |
| 807 | } | 813 | } |
| 808 | } | 814 | } |
diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index e62679990a..06778ad14a 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h | |||
| @@ -116,9 +116,12 @@ typedef struct _split_slave_pointing_sync_t { | |||
| 116 | 116 | ||
| 117 | #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | 117 | #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) |
| 118 | typedef struct _rpc_sync_info_t { | 118 | typedef struct _rpc_sync_info_t { |
| 119 | int8_t transaction_id; | 119 | uint8_t checksum; |
| 120 | uint8_t m2s_length; | 120 | struct { |
| 121 | uint8_t s2m_length; | 121 | int8_t transaction_id; |
| 122 | uint8_t m2s_length; | ||
| 123 | uint8_t s2m_length; | ||
| 124 | } payload; | ||
| 122 | } rpc_sync_info_t; | 125 | } rpc_sync_info_t; |
| 123 | #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | 126 | #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) |
| 124 | 127 | ||
