Understanding Solana’s “instruction modified data of an account it does not own” error

In my ongoing attempt to understand Solana program development better, I’m trying to do unexpected things to see what happens.

For example, with Solana’s example Hello World program, what happens when you try to have the program modify an account it does not own? After all, the client can provide any account(s) to the program. Normally this would be an account the program owns, but what if it isn’t?

In theory the program should be confirming ownership and indeed the example program does:

if account.owner != program_id {
msg!("Greeted account does not have the correct program id");
return Err(ProgramError::IncorrectProgramId);
}
view raw check.rs hosted with ❤ by GitHub

But if you leave that out, what happens?

Fortunately the Solana network rejects the attempt to modify the data in the other account:

'failed to verify account ...: instruction modified data of an account it does not own'

The docs explain:

The runtime grants the program write access to the account if its id matches the owner… If an account is not owned by a program, the program is only permitted to read its data and credit the account.

I’d argue the wording of the error message could use improvement: “instruction modified data” implies the it successfully modified the data, but in reality it attempted to and the network rejected it.

We can search for the error message above to find where it’s being used:

/// Program modified the data of an account that doesn't belong to it
#[error("instruction modified data of an account it does not own")]
ExternalAccountDataModified,

And digging in more, we can find where that error is thrown:

// For accounts unassigned to the program, the data may not change.
if *program_id != account.owner
&& !system_program::check_id(&program_id)
&& pre_data != &account.data[..]
{
return Err(InstructionError::ExternalAccountDataModified);
}

Given that the network will reject attempts to modify accounts that the program doesn’t own, it doesn’t seem 100% necessary to have the account ownership check in this Hello World program, but it’s still good practice to check before attempting to modify the data. The reason is that other programs may read the data from the account and do something with that data, so if you don’t verify ownership those programs could wind up doing something unintentional because it’s using data from an account it does not own. Again the docs explain:

This is because a malicious user could create accounts with arbitrary data and then pass these accounts to the program in place of valid accounts. The arbitrary data could be crafted in a way that leads to unexpected or harmful program behavior.

Therefore, leave the ownership check in place because you don’t want to forget to include it in a program where it actually matters.

Leave a comment