diff --git a/lints/bump_seed_canonicalization/README.md b/lints/bump_seed_canonicalization/README.md index ef126ee..d7ba6c0 100644 --- a/lints/bump_seed_canonicalization/README.md +++ b/lints/bump_seed_canonicalization/README.md @@ -38,6 +38,6 @@ See https://github.com/coral-xyz/sealevel-attacks/blob/master/programs/7-bump-se - If bump is assigned by accessing a struct field - if bump is assigned from a struct implementing `AnchorDeserialize` trait - report a warning to use `#[account(...)` macro - - else report "bump may not be constrainted" warning - - else check if the bump is checked using a comparison operation - - report a warning if the bump is not checked + - else report "bump may not be constrainted" warning + - else if the bump is checked using a comparison operation; do not report + - else report a warning diff --git a/lints/bump_seed_canonicalization/src/lib.rs b/lints/bump_seed_canonicalization/src/lib.rs index 08e6840..88a751e 100644 --- a/lints/bump_seed_canonicalization/src/lib.rs +++ b/lints/bump_seed_canonicalization/src/lib.rs @@ -63,9 +63,9 @@ dylint_linting::declare_late_lint! { /// - If bump is assigned by accessing a struct field /// - if bump is assigned from a struct implementing `AnchorDeserialize` trait /// - report a warning to use `#[account(...)` macro - /// - else report "bump may not be constrainted" warning - /// - else check if the bump is checked using a comparison operation - /// - report a warning if the bump is not checked + /// - else report "bump may not be constrainted" warning + /// - else if the bump is checked using a comparison operation; do not report + /// - else report a warning pub BUMP_SEED_CANONICALIZATION, Warn, "Finds calls to create_program_address that do not check the bump_seed" diff --git a/lints/missing_owner_check/README.md b/lints/missing_owner_check/README.md index d46f696..94dbc84 100644 --- a/lints/missing_owner_check/README.md +++ b/lints/missing_owner_check/README.md @@ -41,15 +41,15 @@ for a secure example. - Get a list of unique and unsafe AccountInfo's referenced in the body - for each expression in the function body - Ignore `.clone()` expressions as the expression referencing original account will be checked - - Check if the expression's type is Solana's AccountInfo (`solana_program::account_info::AccountInfo`) + - Check if the expression's type is Solana's `AccountInfo` (`solana_program::account_info::AccountInfo`) - Ignore local variable expressions (`x` where x is defined in the function `let x = y`) - Removes duplcate warnings: both `x` and `y` are reported by the lint. reporting `y` is sufficient. - Also the owner could be checked on `y`. reporting `x` which a copy/ref of `y` would be false-positive. - - Determine using the expression kind (`.kind`): expr.kind = ExprKind::Path(QPath::Resolved(None, path)); path.segments.len() == 1 + - Determined using the expression kind (`.kind`): expr.kind = ExprKind::Path(QPath::Resolved(None, path)); path.segments.len() == 1 - Ignore safe `.to_account_info()` expressions - - `.to_account_info()` method can be called to convert Anchor different account types to AccountInfo + - `.to_account_info()` method can be called to convert different Anchor account types to `AccountInfo` - The Anchor account types such as `Account` implement `Owner` trait: The owner of the account is checked during deserialization - - The expressions `x.to_account_info` where `x` has one of following types are ignored: + - The expressions `x.to_account_info()` where `x` has one of following types are ignored: - `Account` requires its type argument to implement `anchor_lang::Owner`. - `Program`'s implementation of `try_from` checks the account's program id. So there is no ambiguity in regard to the account's owner. @@ -57,12 +57,12 @@ for a secure example. - `AccountLoader` requires its type argument to implement `anchor_lang::Owner`. - `Signer` are mostly accounts with a private key and most of the times owned by System Program. - `Sysvar` type arguments checks the account key. - - Ignore `x.to_account_info()` expressions called on Anchor AccountInfo to remove duplicates. + - Ignore `x.to_account_info()` expressions called on Anchor `AccountInfo` to remove duplicates. - the lint checks the original expression `x`; no need for checking both. - For each of the collected expressions, check if `owner` is accessed or if the `key` is compared - Ignore the `account_expr` if any of the expressions in the function is `{account_expr}.owner` - Ignore the `account_expr` if `key` is compared - - Check if there is a comparison expression (`==` or `!=`) and one of the expressions being compared accesses key on `account_expr`: - - lhs or rhs of the comparison is `{account_expr}.key()`; The key for Anchor's AccountInfo is accessed using `.key()` - - Or lhs or rhs is `{account_expr}.key`; The key of Solana AccountInfo are accessed using `.key` + - if there is a comparison expression (`==` or `!=`) and one of the expressions being compared accesses key on `account_expr`: + - lhs or rhs of the comparison is `{account_expr}.key()`; The key for Anchor's `AccountInfo` is accessed using `.key()` + - Or lhs or rhs is `{account_expr}.key`; The key of Solana `AccountInfo` are accessed using `.key` - Report the remaining expressions diff --git a/lints/missing_owner_check/src/lib.rs b/lints/missing_owner_check/src/lib.rs index 92dccbc..17afc46 100644 --- a/lints/missing_owner_check/src/lib.rs +++ b/lints/missing_owner_check/src/lib.rs @@ -61,15 +61,15 @@ dylint_linting::declare_late_lint! { /// - Get a list of unique and unsafe AccountInfo's referenced in the body /// - for each expression in the function body /// - Ignore `.clone()` expressions as the expression referencing original account will be checked - /// - Check if the expression's type is Solana's AccountInfo (`solana_program::account_info::AccountInfo`) + /// - Check if the expression's type is Solana's `AccountInfo` (`solana_program::account_info::AccountInfo`) /// - Ignore local variable expressions (`x` where x is defined in the function `let x = y`) /// - Removes duplcate warnings: both `x` and `y` are reported by the lint. reporting `y` is sufficient. /// - Also the owner could be checked on `y`. reporting `x` which a copy/ref of `y` would be false-positive. - /// - Determine using the expression kind (`.kind`): expr.kind = ExprKind::Path(QPath::Resolved(None, path)); path.segments.len() == 1 + /// - Determined using the expression kind (`.kind`): expr.kind = ExprKind::Path(QPath::Resolved(None, path)); path.segments.len() == 1 /// - Ignore safe `.to_account_info()` expressions - /// - `.to_account_info()` method can be called to convert Anchor different account types to AccountInfo + /// - `.to_account_info()` method can be called to convert different Anchor account types to `AccountInfo` /// - The Anchor account types such as `Account` implement `Owner` trait: The owner of the account is checked during deserialization - /// - The expressions `x.to_account_info` where `x` has one of following types are ignored: + /// - The expressions `x.to_account_info()` where `x` has one of following types are ignored: /// - `Account` requires its type argument to implement `anchor_lang::Owner`. /// - `Program`'s implementation of `try_from` checks the account's program id. So there is /// no ambiguity in regard to the account's owner. @@ -77,14 +77,14 @@ dylint_linting::declare_late_lint! { /// - `AccountLoader` requires its type argument to implement `anchor_lang::Owner`. /// - `Signer` are mostly accounts with a private key and most of the times owned by System Program. /// - `Sysvar` type arguments checks the account key. - /// - Ignore `x.to_account_info()` expressions called on Anchor AccountInfo to remove duplicates. + /// - Ignore `x.to_account_info()` expressions called on Anchor `AccountInfo` to remove duplicates. /// - the lint checks the original expression `x`; no need for checking both. /// - For each of the collected expressions, check if `owner` is accessed or if the `key` is compared /// - Ignore the `account_expr` if any of the expressions in the function is `{account_expr}.owner` /// - Ignore the `account_expr` if `key` is compared - /// - Check if there is a comparison expression (`==` or `!=`) and one of the expressions being compared accesses key on `account_expr`: - /// - lhs or rhs of the comparison is `{account_expr}.key()`; The key for Anchor's AccountInfo is accessed using `.key()` - /// - Or lhs or rhs is `{account_expr}.key`; The key of Solana AccountInfo are accessed using `.key` + /// - if there is a comparison expression (`==` or `!=`) and one of the expressions being compared accesses key on `account_expr`: + /// - lhs or rhs of the comparison is `{account_expr}.key()`; The key for Anchor's `AccountInfo` is accessed using `.key()` + /// - Or lhs or rhs is `{account_expr}.key`; The key of Solana `AccountInfo` are accessed using `.key` /// - Report the remaining expressions pub MISSING_OWNER_CHECK, Warn, diff --git a/lints/missing_signer_check/README.md b/lints/missing_signer_check/README.md index 85526d2..ac8b7f5 100644 --- a/lints/missing_signer_check/README.md +++ b/lints/missing_signer_check/README.md @@ -29,7 +29,7 @@ See https://github.com/coral-xyz/sealevel-attacks/blob/master/programs/0-signer- **How the lint is implemented:** - For each free function, function not associated with any type or trait. -- Check the function has an expression of type `AccountInfo` -- Check that the function does **not** take a `Context` type argument where `T` has a `Signer` type field -- Check that the function does **not** has an expression `x.is_signer` where the expression `x` is of type `AccountInfo`. -- Report the function +- If the function has an expression of type `AccountInfo` AND +- If the function does **not** take a `Context` type argument where `T` has a `Signer` type field AND +- If the function does **not** has an expression `x.is_signer` where the expression `x` is of type `AccountInfo`. + - Report the function diff --git a/lints/missing_signer_check/src/lib.rs b/lints/missing_signer_check/src/lib.rs index 6d20eb7..353c3ad 100644 --- a/lints/missing_signer_check/src/lib.rs +++ b/lints/missing_signer_check/src/lib.rs @@ -43,10 +43,10 @@ dylint_linting::declare_late_lint! { /// **How the lint is implemented:** /// /// - For each free function, function not associated with any type or trait. - /// - Check the function has an expression of type `AccountInfo` - /// - Check that the function does **not** take a `Context` type argument where `T` has a `Signer` type field - /// - Check that the function does **not** has an expression `x.is_signer` where the expression `x` is of type `AccountInfo`. - /// - Report the function + /// - If the function has an expression of type `AccountInfo` AND + /// - If the function does **not** take a `Context` type argument where `T` has a `Signer` type field AND + /// - If the function does **not** has an expression `x.is_signer` where the expression `x` is of type `AccountInfo`. + /// - Report the function pub MISSING_SIGNER_CHECK, Warn, "description goes here"