Delete MAX_POLICY_DEPTH; rather, align with MAX_PARSE_SCRIPT_RECURSION_DEPTH from the parsing stage
What changed, and why it matters
This commit changes how deeply nested Bitcoin wallet policies can be when processed by a Ledger hardware wallet app. It removes a separate, smaller limit (10 levels) and instead uses the same deeper limit already applied during an earlier parsing stage. The change is likely a hardening or consistency fix rather than an obvious exploit, but it could affect whether very deep policies are accepted or rejected.
Review what MAX_PARSE_SCRIPT_RECURSION_DEPTH is set to and confirm it provides an adequate safety margin for the device's stack/heap. Verify that the parsing stage and processing stage now reject the same maximum depth, and add regression tests for boundary-depth policies. Treat this as a defense-in-depth consistency improvement unless further review shows a reachable vulnerability.
Security signals we found
Depth-limit constant unified across parsing and processing stages
Removal of a stricter local limit that could create inconsistent policy acceptance
No new input validation or memory safety bug introduced by the diff itself
Evidence from the diff
The patch deletes the local MAX_POLICY_DEPTH (10) constant in src/handler/lib/policy.c and replaces it with MAX_PARSE_SCRIPT_RECURSION_DEPTH, which governs recursion during the prior script/policy parsing stage. The policy parser’s node-state stack and its depth guard now use this shared constant. This aligns the processing-stage depth limit with the parsing-stage limit, preventing a scenario where parsing accepts a policy that processing later rejects, or vice versa. No overflow, underflow, or logic bug is visible in the diff; the change is a limit unification.
Changed components
Ledger Bitcoin app policy parser (src/handler/lib/policy.c)Policy depth enforcement during wallet policy processingInspect captured patch +3 / −4
diff --git a/src/handler/lib/policy.c b/src/handler/lib/policy.c
index 86788eb..dd90b1e 100644
--- a/src/handler/lib/policy.c
+++ b/src/handler/lib/policy.c
@@ -18,8 +18,6 @@
#include "segwit_addr.h"
#include "wallet.h"
-#define MAX_POLICY_DEPTH 10
-
// The last opcode must be processed as a VERIFY flag
#define PROCESSOR_FLAG_V 1
@@ -46,7 +44,8 @@ typedef struct {
const wallet_derivation_info_t *wdi;
bool is_taproot;
- policy_parser_node_state_t nodes[MAX_POLICY_DEPTH]; // stack of nodes being processed
+ policy_parser_node_state_t
+ nodes[MAX_PARSE_SCRIPT_RECURSION_DEPTH]; // stack of nodes being processed
int node_stack_eos; // index of node being processed within nodes; will be set -1 at the end of
// processing
@@ -374,7 +373,7 @@ __attribute__((warn_unused_result)) static int state_stack_push(policy_parser_st
uint8_t flags) {
++state->node_stack_eos;
- if (state->node_stack_eos >= MAX_POLICY_DEPTH) {
+ if (state->node_stack_eos >= MAX_PARSE_SCRIPT_RECURSION_DEPTH) {
return WITH_ERROR(-1, "Reached maximum policy depth");
}
Why this scored 31/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.