[Core] guard RPC invocation by checking RPC info against crc checksum (#17840)
This commit is contained in:
		
							parent
							
								
									cac7042414
								
							
						
					
					
						commit
						ed9bdcbc36
					
				| @ -694,7 +694,7 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { | ||||
| #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | ||||
|         [PUT_RPC_INFO]  = trans_initiator2target_initializer_cb(rpc_info, slave_rpc_info_callback), | ||||
|     [PUT_RPC_REQ_DATA]  = trans_initiator2target_initializer(rpc_m2s_buffer), | ||||
|     [EXECUTE_RPC]       = trans_initiator2target_initializer_cb(rpc_info.transaction_id, slave_rpc_exec_callback), | ||||
|     [EXECUTE_RPC]       = trans_initiator2target_initializer_cb(rpc_info.payload.transaction_id, slave_rpc_exec_callback), | ||||
|     [GET_RPC_RESP_DATA] = trans_target2initiator_initializer(rpc_s2m_buffer), | ||||
| #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
 | ||||
| }; | ||||
| @ -760,7 +760,8 @@ bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer | ||||
|     if (target2initiator_buffer_size > RPC_S2M_BUFFER_SIZE) return false; | ||||
| 
 | ||||
|     // Prepare the metadata block
 | ||||
|     rpc_sync_info_t info = {.transaction_id = transaction_id, .m2s_length = initiator2target_buffer_size, .s2m_length = target2initiator_buffer_size}; | ||||
|     rpc_sync_info_t info = {.payload = {.transaction_id = transaction_id, .m2s_length = initiator2target_buffer_size, .s2m_length = target2initiator_buffer_size}}; | ||||
|     info.checksum        = crc8(&info.payload, sizeof(info.payload)); | ||||
| 
 | ||||
|     // Make sure the local side knows that we're not sending the full block of data
 | ||||
|     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 | ||||
|     // Ignore the args -- the `split_shmem` already has the info, we just need to act upon it.
 | ||||
|     // We must keep the `split_transaction_table` non-const, so that it is able to be modified at runtime.
 | ||||
| 
 | ||||
|     split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size  = split_shmem->rpc_info.m2s_length; | ||||
|     split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = split_shmem->rpc_info.s2m_length; | ||||
|     split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size  = split_shmem->rpc_info.payload.m2s_length; | ||||
|     split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = split_shmem->rpc_info.payload.s2m_length; | ||||
| } | ||||
| 
 | ||||
| void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { | ||||
|     // We can assume that the buffer lengths are correctly set, now, given that sequentially the rpc_info callback was already executed.
 | ||||
|     // Go through the rpc_info and execute _that_ transaction's callback, with the scratch buffers as inputs.
 | ||||
|     int8_t transaction_id = split_shmem->rpc_info.transaction_id; | ||||
|     // As a safety precaution we check that the received payload matches its checksum first.
 | ||||
|     if (crc8(&split_shmem->rpc_info.payload, sizeof(split_shmem->rpc_info.payload)) != split_shmem->rpc_info.checksum) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     int8_t transaction_id = split_shmem->rpc_info.payload.transaction_id; | ||||
|     if (transaction_id < NUM_TOTAL_TRANSACTIONS) { | ||||
|         split_transaction_desc_t *trans = &split_transaction_table[transaction_id]; | ||||
|         if (trans->slave_callback) { | ||||
|             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); | ||||
|             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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -116,9 +116,12 @@ typedef struct _split_slave_pointing_sync_t { | ||||
| 
 | ||||
| #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | ||||
| typedef struct _rpc_sync_info_t { | ||||
|     uint8_t checksum; | ||||
|     struct { | ||||
|         int8_t  transaction_id; | ||||
|         uint8_t m2s_length; | ||||
|         uint8_t s2m_length; | ||||
|     } payload; | ||||
| } rpc_sync_info_t; | ||||
| #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user