summaryrefslogtreecommitdiff
path: root/quantum/split_common
diff options
context:
space:
mode:
authorStefan Kerkmann <karlk90@pm.me>2022-08-06 10:46:59 +0200
committerGitHub <noreply@github.com>2022-08-06 18:46:59 +1000
commited9bdcbc3608819e17ff7a11221e651bf51ec1cc (patch)
tree36e87885a316d67edc7fe64a04ca0db90c890e4c /quantum/split_common
parentcac704241404908794514b7a534e58c96aff4d6b (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.c18
-rw-r--r--quantum/split_common/transport.h9
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
798void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { 799void 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)
118typedef struct _rpc_sync_info_t { 118typedef 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