From 8539b0c680657a433be577f97a13dab2efc5d15f Mon Sep 17 00:00:00 2001 From: kevinaud Date: Thu, 16 Dec 2021 20:20:58 -0600 Subject: [PATCH] Added safety check to IDL write instruction handler. --- lang/src/error.rs | 3 +++ lang/syn/src/codegen/program/handlers.rs | 13 ++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lang/src/error.rs b/lang/src/error.rs index 00a3efc85c..0abd17ac4c 100644 --- a/lang/src/error.rs +++ b/lang/src/error.rs @@ -34,6 +34,9 @@ pub enum ErrorCode { /// 1001 - Invalid program given to the IDL instruction #[msg("Invalid program given to the IDL instruction")] IdlInstructionInvalidProgram, + /// 1002 - Canonical IDL account cannot be written to, must write to an IDL buffer + #[msg("Canonical IDL account cannot be written to, must write to an IDL buffer")] + IdlInstructionWritingToCanonicalAccount, // Constraints /// 2000 - A mut constraint was violated diff --git a/lang/syn/src/codegen/program/handlers.rs b/lang/syn/src/codegen/program/handlers.rs index 3bfa47e1b3..d0ccec6ae6 100644 --- a/lang/syn/src/codegen/program/handlers.rs +++ b/lang/syn/src/codegen/program/handlers.rs @@ -64,7 +64,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { Err(anchor_lang::__private::ErrorCode::IdlInstructionStub.into()) } - // One time IDL account initializer. Will faill on subsequent + // One time IDL account initializer. Will fail on subsequent // invocations. #[inline(never)] pub fn __idl_create_account( @@ -152,8 +152,15 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { #[cfg(not(feature = "no-log-ix-name"))] anchor_lang::prelude::msg!("Instruction: IdlWrite"); - let mut idl = &mut accounts.idl; - idl.data.extend(idl_data); + let mut buffer = &mut accounts.idl; + + // Ensure that the instruction is writing to a buffer account, not the canonical IDL + // account. + if buffer.key == IdlAccount::address(program_id) { + return Err(anchor_lang::__private::ErrorCode::IdlInstructionWritingToCanonicalAccount.into()); + } + + buffer.data.extend(idl_data); Ok(()) }