keylime/0005-Address-some-improvements-from-code-review.patch
Sergio Arroutbi d3a4e38571
Add patches to fix DB connection leaks
Resolves: #RHEL-153811

Backport upstream fixes for database connection pool exhaustion
that occurred during multi-host push attestation with multiple
agents, causing QueuePool timeout and HTTP 500 errors.

Upstream commits:
- 5b622eae Close DB sessions to prevent connection exhaustion
- bc28d5d2 Include thread-safe session management
- 4f5f09a6 Address some improvements from code review
- 309a0ef0 Fix race condition in SessionManager
- e75921f0 Fix linter errors in PersistableModel.get() and .all()
- 2d809d8b refactor: Remove dead code AuthSession.authenticate_agent()
- e935df8f db: Clean up scoped session after each request
- 08c0c67c fix: Check active flag in _extract_identity and guard receive_pop
- d74e7499 fix: Add fork-safety to DBManager via dispose()

Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
2026-03-23 11:28:49 +01:00

80 lines
3.0 KiB
Diff

From 4f5f09a69e01c0116f1977aa3a741f3678bb8e67 Mon Sep 17 00:00:00 2001
From: Sergio Arroutbi <sarroutb@redhat.com>
Date: Thu, 12 Mar 2026 15:18:56 +0100
Subject: [PATCH 5/6] Address some improvements from code review
Include agent variable None initialization
and address thread safety for ContextManager
Signed-off-by: Sergio Arroutbi <sarroutb@redhat.com>
---
keylime/db/keylime_db.py | 7 ++++++-
keylime/web/verifier/session_controller.py | 3 +++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/keylime/db/keylime_db.py b/keylime/db/keylime_db.py
index 6fd3f08..cf608fa 100644
--- a/keylime/db/keylime_db.py
+++ b/keylime/db/keylime_db.py
@@ -1,4 +1,5 @@
import os
+import threading
from configparser import NoOptionError
from contextlib import contextmanager
from sqlite3 import Connection as SQLite3Connection
@@ -89,10 +90,12 @@ def make_engine(service: str, **engine_args: Any) -> Engine:
class SessionManager:
engine: Optional[Engine]
_scoped_session: Optional[scoped_session]
+ _lock: threading.Lock
def __init__(self) -> None:
self.engine = None
self._scoped_session = None
+ self._lock = threading.Lock()
def make_session(self, engine: Engine) -> Session:
"""
@@ -100,7 +103,9 @@ class SessionManager:
"""
self.engine = engine
if self._scoped_session is None:
- self._scoped_session = scoped_session(sessionmaker())
+ with self._lock:
+ if self._scoped_session is None:
+ self._scoped_session = scoped_session(sessionmaker())
try:
self._scoped_session.configure(bind=self.engine) # type: ignore
self._scoped_session.configure(expire_on_commit=False) # type: ignore
diff --git a/keylime/web/verifier/session_controller.py b/keylime/web/verifier/session_controller.py
index 3faa310..c8664e2 100644
--- a/keylime/web/verifier/session_controller.py
+++ b/keylime/web/verifier/session_controller.py
@@ -185,6 +185,7 @@ class SessionController(Controller):
return
# Check if agent exists - this is where we validate enrollment
+ agent = None
with get_session_context() as session:
agent = session.query(VerfierMain).filter(VerfierMain.agent_id == agent_id).one_or_none()
if agent:
@@ -382,6 +383,7 @@ class SessionController(Controller):
# POST /v3[.:minor]/agents/:agent_id/session
def create(self, agent_id, **params):
+ agent = None
with get_session_context() as session:
agent = session.query(VerfierMain).filter(VerfierMain.agent_id == agent_id).one_or_none()
if agent:
@@ -407,6 +409,7 @@ class SessionController(Controller):
self.respond(200, "Success", auth_session.render())
def update(self, agent_id, token, **params):
+ agent = None
with get_session_context() as session:
agent = session.query(VerfierMain).filter(VerfierMain.agent_id == agent_id).one_or_none()
if agent:
--
2.53.0