From e9e3a68cf6ff7e5c703e61c6cf951125d1851321 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Tue, 10 Mar 2020 14:39:33 -0400
Subject: [PATCH] Raise the stack limit while validating the proof

We don't need to mess with the Python stack limit.  The proof is validated in
Rust.  We just need to offer more stack space to the Rust implementation.
---
 src/_zkapauthorizer/controller.py | 36 +++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py
index 61399a1..693e3eb 100644
--- a/src/_zkapauthorizer/controller.py
+++ b/src/_zkapauthorizer/controller.py
@@ -41,6 +41,15 @@ from base64 import (
     b64encode,
     b64decode,
 )
+from contextlib import (
+    contextmanager,
+)
+from resource import (
+    RLIMIT_STACK,
+    getrlimit,
+    setrlimit,
+)
+
 import attr
 
 from zope.interface import (
@@ -469,12 +478,14 @@ class RistrettoRedeemer(object):
         clients_proof = privacypass.BatchDLEQProof.decode_base64(
             marshaled_proof.encode("ascii"),
         )
-        clients_unblinded_tokens = clients_proof.invalid_or_unblind(
-            random_tokens,
-            blinded_tokens,
-            clients_signed_tokens,
-            public_key,
-        )
+        with unlimited_stack():
+            self._log.info("Decoded batch proof")
+            clients_unblinded_tokens = clients_proof.invalid_or_unblind(
+                random_tokens,
+                blinded_tokens,
+                clients_signed_tokens,
+                public_key,
+            )
         self._log.info("Validated proof")
         returnValue(list(
             UnblindedToken(token.encode_base64().decode("ascii"))
@@ -795,3 +806,16 @@ def bracket(first, last, between):
     else:
         yield last()
         returnValue(result)
+
+
+@contextmanager
+def unlimited_stack():
+    """
+    A context manager which removes the resource limit on stack size for
+    execution of the context.
+    """
+    soft, hard = getrlimit(RLIMIT_STACK)
+    # We can raise the soft limit to the hard limit and no higher.
+    setrlimit(RLIMIT_STACK, (hard, hard))
+    yield
+    setrlimit(RLIMIT_STACK, (soft, hard))
-- 
GitLab