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/forbid halt #21

Merged
merged 2 commits into from
Nov 24, 2024
Merged

Security/forbid halt #21

merged 2 commits into from
Nov 24, 2024

Conversation

ccamel
Copy link
Member

@ccamel ccamel commented Nov 24, 2024

This PR enforces the disallowance of the halt/1 predicate, which now throws the error error(panic_error('halt/1 is not allowed')) when invoked.

Previously, this predicate was unregistered in the axone blockchain’s logic module (axone-protocol/axoned@293da10). However, as the VM is now designed to be safely embedded in a blockchain, this predicate must be explicitly controlled at the VM level to ensure robust security.

@ccamel ccamel self-assigned this Nov 24, 2024
Copy link

coderabbitai bot commented Nov 24, 2024

Walkthrough

The pull request introduces significant changes to the handling of the halt/0 and halt/1 predicates within the axone-protocol/prolog implementation. The README.md file has been updated to reflect these new restrictions, which now throw errors when invoked. In the codebase, the osExit variable is redefined to prevent program termination and instead raise a panic. Additionally, the error handling in the testing files has been enhanced to accommodate these changes, ensuring that the system's response to halting requests is consistent with the new restrictions.

Changes

File Change Summary
README.md Added restriction on halt/0 and halt/1 predicates; document structure remains unchanged.
engine/builtin.go Updated osExit to prevent program exit and raise a panic with a specific message.
engine/builtin_test.go Added new tests for panic scenarios; modified existing tests to check for errors instead of exits.
engine/promise.go Updated panicError function to handle Exception types and streamline error reporting.

Possibly related PRs

  • Remove atoms table  #5: The changes in engine/builtin.go regarding the osExit variable directly relate to the new restriction on the halt/1 predicate mentioned in the main PR, as both involve modifications to how halting behavior is managed in the Prolog implementation.
  • Add a MaxVariables limits #6: The updates in engine/builtin_test.go that enhance error handling and testing for the Halt function are relevant, as they reflect changes in how halting is treated in the context of the new restrictions on halt/0 and halt/1.
  • Wrap panic errors  #7: The modifications to error handling in engine/promise.go that introduce a PanicError type are related, as they improve the overall error management, which is crucial given the new restrictions on halting behavior.
  • docs(readme): add notice about hard fork #9: The updates to the README.md file that clarify the project's status as a hard fork and its specific adaptations for the Axone protocol align with the main PR's focus on documenting changes, including the new restrictions on predicates.
  • Docs/complete readme #20: The comprehensive update to the README.md file, which includes a new project title and description, reflects the project's transition and adaptations, similar to the changes made in the main PR regarding the documentation of the new restrictions.

Suggested reviewers

  • bdeneux
  • amimart

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Nov 24, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Impacted file tree graph

@@           Coverage Diff           @@
##             main      #21   +/-   ##
=======================================
  Coverage   97.86%   97.87%           
=======================================
  Files          24       24           
  Lines        7840     7844    +4     
=======================================
+ Hits         7673     7677    +4     
  Misses        134      134           
  Partials       33       33           
Files with missing lines Coverage Δ
engine/builtin.go 99.52% <100.00%> (+<0.01%) ⬆️
engine/promise.go 98.36% <100.00%> (+0.02%) ⬆️

🚨 Try these New Features:

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (3)
engine/promise.go (2)

Line range hint 220-228: Remove unused PanicError type

The PanicError type appears to be unused after the recent changes to panicError function, which now returns Exception instead.

-// PanicError is an error thrown once panic occurs during the execution of a promise.
-type PanicError struct {
-	OriginErr error
-}
-
-func (p PanicError) Error() string {
-	return fmt.Sprintf("panic: %v", p.OriginErr)
-}

168-170: Consider enhancing error messages

The error messages could be more descriptive to help with debugging. Consider including additional context about where the panic occurred.

-		return Exception{term: atomError.Apply(NewAtom("panic_error").Apply(NewAtom(r.Error())))}
+		return Exception{term: atomError.Apply(NewAtom("panic_error").Apply(NewAtom(fmt.Sprintf("promise execution: %v", r.Error()))))}
-		return Exception{term: atomError.Apply(NewAtom("panic_error").Apply(NewAtom(fmt.Sprintf("%v", r))))}
+		return Exception{term: atomError.Apply(NewAtom("panic_error").Apply(NewAtom(fmt.Sprintf("promise execution: %v", r))))}
README.md (1)

45-45: Enhance documentation with implementation details

The documentation clearly states that halt/0 and halt/1 are forbidden. However, consider adding more context to help users understand and handle this restriction:

-  - `halt/0` and `halt/1` are forbidden and will throw an error.
+  - `halt/0` and `halt/1` are forbidden and will throw `error(panic_error(halt is not allowed))`. This restriction ensures safe execution within the blockchain environment by preventing uncontrolled termination of the Prolog VM.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d446d5b and 04c24f957841806139a28bc36d0672397311f5b3.

📒 Files selected for processing (4)
  • README.md (1 hunks)
  • engine/builtin.go (1 hunks)
  • engine/builtin_test.go (3 hunks)
  • engine/promise.go (1 hunks)
🔇 Additional comments (3)
engine/promise.go (2)

165-171: LGTM: Error handling improvements look good

The changes to panicError improve error handling consistency by wrapping all panic scenarios in the Exception type. This aligns well with the PR's objective of properly handling panics from the halt/1 restriction.


165-171: Verify error handling changes across the codebase

Let's ensure these changes don't break existing error handling and that all panic scenarios are properly handled.

✅ Verification successful

Let me gather more information about the error handling changes.


Changes to panic error handling are safe and properly implemented

The code changes are safe because:

  1. The PanicError type is only used internally within engine/promise.go
  2. The panic recovery mechanism is properly maintained through recover() function
  3. The changes only modify the error term construction while preserving the error handling flow
  4. The error handling chain (through promiseStack.recover) remains intact
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any remaining uses of PanicError
echo "Checking for PanicError usage..."
rg "PanicError" 

# Check for existing panic handling patterns
echo "Checking panic handling patterns..."
ast-grep --pattern 'recover() {
  $$$
}'

# Look for potential error handling test cases
echo "Checking error handling tests..."
rg -l "test.*Error" --type go

Length of output: 543


Script:

#!/bin/bash
# Check the implementation and usage of PanicError
echo "Checking PanicError implementation..."
rg -A 5 "type PanicError struct" engine/promise.go

# Check recover() usage in promise.go
echo "Checking recover usage in promise.go..."
rg -B 5 -A 10 "recover()" engine/promise.go

# Check error handling tests
echo "Checking error handling test cases..."
cat engine/text_test.go | rg "test.*Error" -A 5

Length of output: 3514

engine/builtin_test.go (1)

73-77: Verify that panics with integer literals are properly handled

The test case for do_not_call_misc_error expects an exception with "panic_error" wrapping the string "42". Since the code panics with an integer literal 42, verify that this is correctly converted to a string in the error handling logic.

Run the following script to confirm that panics with an integer are appropriately handled:

✅ Verification successful

Let me gather more information about how panics are handled in the codebase.


Based on the results, I can now generate the final response as I found the relevant panic handling logic in the codebase.

Panics with integer literals are properly handled

The panic value 42 is correctly converted to a string in the error handling logic. This is confirmed by the implementation in engine/promise.go which uses fmt.Sprintf("%v", r) to convert any panic value (including integers) to a string when creating the panic_error atom. The test case correctly expects "42" as the string representation of the integer panic.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Ensure panics with integer literals are correctly converted to errors.

# Search for panic calls with integer literals
rg 'panic\([0-9]+\)' engine/

# Check how integer panics are converted to strings in error handling
rg 'func recover' engine/promise.go -A 10

# Verify that the error message in the test matches the converted panic value
rg 'panic_error' engine/builtin_test.go -A 5

Length of output: 1441


Script:

#!/bin/bash
# Search for panic handling and recovery logic
ast-grep --pattern 'func $name($$$) {
  $$$
  if r := recover(); r != nil {
    $$$
  }
  $$$
}'

# Look for any string conversion or formatting of panic values
rg 'fmt\.Sprint|fmt\.Sprintf|String\(\)|ToString' engine/

Length of output: 7300

engine/builtin.go Show resolved Hide resolved
engine/builtin_test.go Outdated Show resolved Hide resolved
engine/builtin_test.go Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
engine/builtin_test.go (1)

5530-5534: Consider adding more test cases

While the current test verifies the basic functionality, consider adding test cases for:

  • Different integer values passed to halt/1
  • Edge cases like MaxInt64/MinInt64
  • Multiple consecutive calls to halt/1

Example test cases:

t.Run("edge cases", func(t *testing.T) {
    cases := []int64{math.MaxInt64, math.MinInt64, 0, 42}
    for _, n := range cases {
        ok, err := Delay(func(ctx context.Context) *Promise {
            return Halt(nil, Integer(n), Success, nil)
        }).Force(context.Background())
        assert.EqualError(t, err, "error(panic_error(halt/1 is not allowed))")
        assert.False(t, ok)
    }
})
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 04c24f957841806139a28bc36d0672397311f5b3 and 3a63e6e.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • engine/builtin.go (1 hunks)
  • engine/builtin_test.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • README.md
🧰 Additional context used
📓 Learnings (2)
engine/builtin.go (1)
Learnt from: ccamel
PR: axone-protocol/prolog#21
File: engine/builtin.go:1963-1965
Timestamp: 2024-11-24T08:43:47.451Z
Learning: In `engine/builtin.go`, the use of `panic` in the `osExit` function to handle `halt/1` is intentional and should not be altered to return an error instead.
engine/builtin_test.go (1)

<retrieved_learning>
Learnt from: ccamel
PR: #21
File: engine/builtin_test.go:40-45
Timestamp: 2024-11-24T08:47:15.195Z
Learning: In engine/builtin_test.go, the function do_not_call_misc_error intentionally panics with a non-string, non-error value (e.g., panic(42)) as part of the test. Do not suggest changing this code to panic with an error value.
</retrieved_learning>

🔇 Additional comments (2)
engine/builtin.go (1)

1963-1965: LGTM! Security improvement to prevent VM termination.

The implementation effectively forbids the use of halt/1 predicate by replacing the os.Exit call with a panic, which is crucial for maintaining the integrity of the blockchain's VM. The error message clearly indicates that the operation is not allowed.

engine/builtin_test.go (1)

5530-5534: LGTM! Test verifies the new halt/1 behavior

The test correctly verifies that halt/1 now returns an error instead of actually halting, with the proper error message format.

@ccamel ccamel merged commit eec929d into main Nov 24, 2024
3 checks passed
@ccamel ccamel deleted the security/forbid-halt branch November 24, 2024 08:51
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

Successfully merging this pull request may close these issues.

1 participant