Fix CPI duplicate account privilege escalation (#22752)
* Adds TEST_DUPLICATE_PRIVILEGE_ESCALATION_SIGNER and TEST_DUPLICATE_PRIVILEGE_ESCALATION_WRITABLE. * Moves CPI privilege verification out of deduplication loop.
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							fa51e5b704
						
					
				
				
					commit
					a71f05f86c
				
			| @@ -698,33 +698,6 @@ impl<'a> InvokeContext<'a> { | ||||
|                         ); | ||||
|                         InstructionError::MissingAccount | ||||
|                     })?; | ||||
|                 let borrowed_account = instruction_context | ||||
|                     .try_borrow_account(self.transaction_context, index_in_caller)?; | ||||
|  | ||||
|                 // Readonly in caller cannot become writable in callee | ||||
|                 if account_meta.is_writable && !borrowed_account.is_writable() { | ||||
|                     ic_msg!( | ||||
|                         self, | ||||
|                         "{}'s writable privilege escalated", | ||||
|                         borrowed_account.get_key(), | ||||
|                     ); | ||||
|                     return Err(InstructionError::PrivilegeEscalation); | ||||
|                 } | ||||
|  | ||||
|                 // To be signed in the callee, | ||||
|                 // it must be either signed in the caller or by the program | ||||
|                 if account_meta.is_signer | ||||
|                     && !(borrowed_account.is_signer() | ||||
|                         || signers.contains(borrowed_account.get_key())) | ||||
|                 { | ||||
|                     ic_msg!( | ||||
|                         self, | ||||
|                         "{}'s signer privilege escalated", | ||||
|                         borrowed_account.get_key() | ||||
|                     ); | ||||
|                     return Err(InstructionError::PrivilegeEscalation); | ||||
|                 } | ||||
|  | ||||
|                 duplicate_indicies.push(deduplicated_instruction_accounts.len()); | ||||
|                 deduplicated_instruction_accounts.push(InstructionAccount { | ||||
|                     index_in_transaction, | ||||
| @@ -734,6 +707,35 @@ impl<'a> InvokeContext<'a> { | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|         for instruction_account in deduplicated_instruction_accounts.iter() { | ||||
|             let borrowed_account = instruction_context.try_borrow_account( | ||||
|                 self.transaction_context, | ||||
|                 instruction_account.index_in_caller, | ||||
|             )?; | ||||
|  | ||||
|             // Readonly in caller cannot become writable in callee | ||||
|             if instruction_account.is_writable && !borrowed_account.is_writable() { | ||||
|                 ic_msg!( | ||||
|                     self, | ||||
|                     "{}'s writable privilege escalated", | ||||
|                     borrowed_account.get_key(), | ||||
|                 ); | ||||
|                 return Err(InstructionError::PrivilegeEscalation); | ||||
|             } | ||||
|  | ||||
|             // To be signed in the callee, | ||||
|             // it must be either signed in the caller or by the program | ||||
|             if instruction_account.is_signer | ||||
|                 && !(borrowed_account.is_signer() || signers.contains(borrowed_account.get_key())) | ||||
|             { | ||||
|                 ic_msg!( | ||||
|                     self, | ||||
|                     "{}'s signer privilege escalated", | ||||
|                     borrowed_account.get_key() | ||||
|                 ); | ||||
|                 return Err(InstructionError::PrivilegeEscalation); | ||||
|             } | ||||
|         } | ||||
|         let instruction_accounts: Vec<InstructionAccount> = duplicate_indicies | ||||
|             .into_iter() | ||||
|             .map(|duplicate_index| deduplicated_instruction_accounts[duplicate_index].clone()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user