Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security risk: No compute meter checks for straight line programs #187

Closed
jon-chuang opened this issue Jun 29, 2021 · 2 comments
Closed

Comments

@jon-chuang
Copy link

jon-chuang commented Jun 29, 2021

Problem

A program can be a maximum of 10MB, or roughly 1_250_000 opcodes (8 bytes per opcode). Since there are no compute meter checks for straight line programs, a program can exceed their compute budget willfully.

Solution

Either:

  1. Every random noop (or random subset thereof) should be replaced by emit_validate_and_profile_instruction_count
  2. When emitting instructions, maintain a counter alongside the cumulative cost. Increment counter by cost of ops encountered. Whenever one does emit_validate_and_profile_instruction_count, reset counter. If counter exceeds STRAIGHT_LINE_VALIDATE_THRESHOLD: u64 = 1000, do emit_validate_and_profile_instruction_count. This ensures that at most, a program will exceed the given budget by 1000.

Misc

This also suggests that 10MB programs may be a little too large to do JIT for on-demand - suggesting that programs of a certain size (> 100_000 opcodes) should be JITed asynchronously and interpreted on-demand until JIT is ready.

Will be interested to see JIT timings for programs of varying length.

@jon-chuang
Copy link
Author

jon-chuang commented Jun 29, 2021

As a separate but related question, is JIT currently enabled on mainnet?

Edit: my understanding - no, as process_instruction_jit is not the declared builtin: (in programs/bpf_loader/src/lib.rs:

solana_sdk::declare_builtin!(
    solana_sdk::bpf_loader::ID,
    solana_bpf_loader_program,
    solana_bpf_loader_program::process_instruction
);

@Lichtso
Copy link

Lichtso commented Jul 6, 2021

My worry is not the detection per-se but rather to catch such programs in the act so they don't run for say 100ms rather than say a target 10ms.

We are aware that linear programs can dramatically overrun before they are stopped by an exit branch. However, it was not deemed much of a threat yet, because the cost function and compute-meter economics are still very simple. This will become more of a problem when programs can chose to pay for less and use less / only what they actually need, then they could run disproportionally longer than what they payed for.

Will be interested to see JIT timings for programs of varying length.

We have a standalone CLI tool that you can play around with.

Is JIT currently enabled on mainnet?

It is optional but enabled by default.

Conclusion

We can address this in a general overhaul of the instruction meter which would:

  • Add a non-uniform cost function
  • Insert phony branches in long linear runs
  • Fix the "exception after instruction meter limit reached" situation, if that turns out to be an issue

Thanks for all your hints and contributions. I just wanted to add that you should read and follow our security policy & guideline, that way you would also be eligible for the bounty program.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants