chore(core): remove double check when changing pin#6132
Conversation
|
Looks like you changed |
c526f71 to
7fd0ed1
Compare
2b1e5ec to
24d8160
Compare
7ef7b49 to
b920599
Compare
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. 💤 Files selected but had no reviewable changes (1)
You can disable this status message by setting the
WalkthroughThe PR replaces boolean return values for storage unlock and PIN-change operations with two new enums ( Sequence Diagram(s)sequenceDiagram
participant UI as Client/UI
participant App as Application
participant Bind as Language Bindings
participant Sys as Syscall/SMCall Verifier
participant Stor as Secure Storage
UI->>App: request change PIN (new_pin, new_ext_salt)
App->>Bind: config.change_pin(new_pin, new_ext_salt)
Bind->>Sys: syscall/storage_change_pin(newpin, newpin_len, new_ext_salt)
Sys->>Stor: storage_change_pin(newpin, newpin_len, new_ext_salt)
Stor-->>Sys: storage_pin_change_result_t (e.g. PIN_CHANGE_OK / PIN_CHANGE_*)
Sys-->>Bind: storage_pin_change_result_t
Bind-->>App: propagate enum result
App-->>UI: success / raise error based on enum
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
storage/tests/tests/storage_model.py (1)
40-48: Inconsistent behavior:unlock()vscheck_pin()for old PIN verification.The
StorageModel.change_pin()usesself.unlock(oldpin)to verify the old PIN (line 43), but the equivalent implementation instorage/tests/python/src/storage.pyusesself.check_pin(oldpin)instead. This creates a behavioral difference:
unlock()decrementspin_remand can trigger a wipe on wrong PINcheck_pin()(if it exists in this model) would typically just verify without side effectsSince the storage is already unlocked at this point, calling
unlock()with a wrongoldpinwould unexpectedly decrement the PIN counter and potentially wipe storage, which seems like unintended behavior for a PIN change operation.Consider aligning with the Python storage implementation by using a
check_pin()method instead, or documenting this as intentional behavior.core/src/apps/management/change_pin.py (1)
41-54: Replaceconfig.check_pin()withconfig.unlock()to unlock storage before callingchange_pin().The
config.change_pin()call requires unlocked storage (per mock docstring), but the code only callsconfig.check_pin(curpin, salt), which validates the PIN without unlocking. This should beconfig.unlock(curpin, salt)instead.core/embed/sys/smcall/stm32/smcall_verifiers.c (2)
278-281: Critical: Type mismatch returns success on access violation.The function returns
storage_unlock_result_t, but theaccess_violationpath returnssecfalse. Ifsecfalseequals 0 (which is common), this would incorrectly returnUNLOCK_OK(which is also 0), indicating a successful unlock on access violation.This is a security issue - an access violation should return a failure code like
UNLOCK_UNKNOWNor a dedicated access violation error code.🐛 Proposed fix
access_violation: apptask_access_violation(); - return secfalse; + return UNLOCK_UNKNOWN; }
295-298: Critical: Type mismatch returns success on access violation.Same issue as
storage_unlock__verified- returningsecfalsefor astorage_pin_change_result_twould incorrectly indicatePIN_CHANGE_OKifsecfalseequals 0.🐛 Proposed fix
access_violation: apptask_access_violation(); - return secfalse; + return PIN_CHANGE_UNKNOWN; }core/embed/sys/syscall/stm32/syscall_verifiers.c (2)
655-658: Critical: Type mismatch returns success on access violation.Same issue as in
smcall_verifiers.c- the function returnsstorage_unlock_result_t, butsecfalseis returned on access violation, which would incorrectly indicateUNLOCK_OKifsecfalseequals 0.🐛 Proposed fix
access_violation: apptask_access_violation(); - return secfalse; + return UNLOCK_UNKNOWN; }
672-675: Critical: Type mismatch returns success on access violation.Same issue - returning
secfalsefor astorage_pin_change_result_twould incorrectly indicatePIN_CHANGE_OK.🐛 Proposed fix
access_violation: apptask_access_violation(); - return secfalse; + return PIN_CHANGE_UNKNOWN; }
🤖 Fix all issues with AI agents
In `@core/embed/sys/syscall/stm32/syscall_verifiers.h`:
- Around line 183-188: The verifier functions storage_unlock__verified and
storage_change_pin__verified currently return the generic secfalse on
access_violation which doesn't match their declared return types
storage_unlock_result_t and storage_pin_change_result_t; change the
access_violation return to a proper enum sentinel (e.g. return
UNLOCK_NOT_INITIALIZED for storage_unlock__verified and
PIN_CHANGE_NOT_INITIALIZED for storage_change_pin__verified) or add and return a
dedicated ACCESS_VIOLATION variant in those enums, and keep the
apptask_access_violation() call intact; update any enum definitions and usages
to ensure the chosen enum constants are defined and mapped consistently.
In `@legacy/firmware/protect.c`:
- Around line 283-287: config_changePin currently returns only bool so every
failure maps to the wipe‑code message; update the fix by changing
config_changePin to return a discriminated result (enum) describing outcomes
(e.g., Success, Error_SameAsWipeCode, Error_RemovalNotAllowed,
Error_StorageFailure), then update the caller in protect.c to inspect that enum
and call fsm_sendFailure(FailureType_Failure_ProcessError, ...) with a specific
message for Error_SameAsWipeCode and a generic "Could not change PIN" (or
appropriate messages) for other errors; alternatively, if changing the API is
infeasible, replace the hardcoded wipe‑code string with a single generic failure
message so non‑wipe failures are not misleading.
🧹 Nitpick comments (4)
core/embed/upymod/modtrezorconfig/modtrezorconfig.c (1)
88-134: Document that most failures raise exceptions.The unlock path now raises
RuntimeErrorfor many failure codes, but the docstring above still says “False on failure.” Consider updating it to avoid misleading callers.core/src/apps/management/sd_protect.py (3)
68-94: Consider using exception chaining for clearer error tracing.The
raise wire.ProcessError(...)on line 94 should use exception chaining to preserve the original error context or explicitly suppress it.♻️ Proposed fix
except RuntimeError: # Failed to set salt in storage. Clean up the prepared salt file. try: storage_sd_salt.remove_sd_salt() except Exception: # The cleanup is not necessary for the correct functioning of # SD-protection. If it fails for any reason, we suppress the # exception. pass - raise wire.ProcessError("Failed to set salt in storage") + raise wire.ProcessError("Failed to set salt in storage") from None
121-124: Use exception chaining for consistency.Similar to the enable flow, use
from Noneto explicitly suppress the exception chain.♻️ Proposed fix
try: config.change_pin(pin, None) except RuntimeError: - raise wire.FirmwareError("Failed to remove SD salt") + raise wire.FirmwareError("Failed to remove SD salt") from None
163-166: Use exception chaining for consistency.Same pattern as the other flows.
♻️ Proposed fix
try: config.change_pin(pin, new_salt) except RuntimeError: - raise wire.FirmwareError("Failed to set new salt in storage") + raise wire.FirmwareError("Failed to set new salt in storage") from None
[no changelog]
28796b3 to
e05002a
Compare
[no changelog]




























































































































































Remove the second pin check during pin change.
[no changelog]