Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: [email protected] Control: affects -1 + src:ceph User: [email protected] Usertags: pu
Hi, I'd like to upgrade Ceph in Trixie p-u to fix an issue the ceph-mgr, where it cannot start. See debian bug #1148903. [ Reason ] As per the patch header: python3-bcrypt is built with PyO3, and PyO3 extensions cannot be imported inside a Python subinterpreter, which is how ceph-mgr loads its modules. With Python 3.13's python3-bcrypt, every mgr module fails to load with "ImportError: PyO3 modules do not yet support subinterpreters", breaking the mgr (and the dashboard module, which imports bcrypt as well). So we got to fix that for ceph-mgr to work in Trixie. [ Impact ] Users can't start ceph-mgr, and therefore, cannot use cephfs. [ Tests ] I've tested this fix myself manually. [ Risks ] Not much risk: since ceph-mgr is currently broken, it cannot get worse. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] As per debdiff: the 0011-mgr-replace-bcrypt-with-crypt_r.patch, plus replacing python3-bcrypt by python3-crypt-r as new runtime depends. Please allow me to upload ceph/18.2.7+ds-1+deb13u2. Cheers, Thomas Goirand (zigo)
diff -Nru ceph-18.2.7+ds/debian/changelog ceph-18.2.7+ds/debian/changelog --- ceph-18.2.7+ds/debian/changelog 2026-05-10 21:17:37.000000000 +0200 +++ ceph-18.2.7+ds/debian/changelog 2026-10-16 10:12:37.000000000 +0200 @@ -1,3 +1,16 @@ +ceph (18.2.7+ds-1+deb13u2) trixie; urgency=medium + + * mgr: replace the python3-bcrypt import with crypt_r: PyO3 extensions + cannot be imported inside a Python subinterpreter, which is how + ceph-mgr loads its modules, so every mgr module failed to load with + Python 3.13's python3-bcrypt, including the dashboard module. + crypt_r computes the same $2b$ bcrypt hashes, so existing password + hashes keep verifying (Closes: #1148903). + * ceph-mgr, ceph-mgr-dashboard: replace the python3-bcrypt dependency + with python3-crypt-r. + + -- Thomas Goirand <[email protected]> Fri, 16 Oct 2026 11:14:03 +0200 + ceph (18.2.7+ds-1+deb13u1) trixie-security; urgency=high * Non-maintainer upload by the Security Team. diff -Nru ceph-18.2.7+ds/debian/control ceph-18.2.7+ds/debian/control --- ceph-18.2.7+ds/debian/control 2026-05-10 21:06:34.000000000 +0200 +++ ceph-18.2.7+ds/debian/control 2026-10-16 10:12:37.000000000 +0200 @@ -354,7 +354,7 @@ ceph-mgr-modules-core (>= ${source:Version}), libsqlite3-mod-ceph (<< ${source:Version}.1~), libsqlite3-mod-ceph (>= ${source:Version}), - python3-bcrypt, + python3-crypt-r, python3-ceph-argparse (= ${binary:Version}), python3-cephfs (= ${binary:Version}), python3-cherrypy3, @@ -408,7 +408,7 @@ ceph-common (>= ${binary:Version}), ceph-mgr (<< ${binary:Version}.1~), ceph-mgr (>= ${binary:Version}), - python3-bcrypt, + python3-crypt-r, python3-cherrypy3, python3-jwt, python3-more-itertools, diff -Nru ceph-18.2.7+ds/debian/patches/py313-compat/0011-mgr-replace-bcrypt-with-crypt_r.patch ceph-18.2.7+ds/debian/patches/py313-compat/0011-mgr-replace-bcrypt-with-crypt_r.patch --- ceph-18.2.7+ds/debian/patches/py313-compat/0011-mgr-replace-bcrypt-with-crypt_r.patch 1970-01-01 01:00:00.000000000 +0100 +++ ceph-18.2.7+ds/debian/patches/py313-compat/0011-mgr-replace-bcrypt-with-crypt_r.patch 2026-10-16 10:12:37.000000000 +0200 @@ -0,0 +1,68 @@ +Description: mgr: replace the bcrypt import with crypt_r + python3-bcrypt is built with PyO3, and PyO3 extensions cannot be + imported inside a Python subinterpreter, which is how ceph-mgr loads + its modules. With Python 3.13's python3-bcrypt, every mgr module + fails to load with "ImportError: PyO3 modules do not yet support + subinterpreters", breaking the mgr (and the dashboard module, which + imports bcrypt as well). + . + Use crypt_r (libxcrypt) instead: it computes the same $2b$ bcrypt + hashes, so existing password hashes keep verifying. + . + Patch based on the workaround posted by Jakob Haufe in #1148903, + with the blowfish cost kept at 12 (crypt_r.mksalt expects the + literal iteration count, hence rounds=4096 = 2^12) to match + bcrypt.gensalt()'s default. +Author: Thomas Goirand <[email protected]> +Assisted-By: Infomaniak Euria-Code +Bug-Debian: https://bugs.debian.org/1148903 +Last-Update: 2026-10-16 + +Index: ceph/src/pybind/mgr/dashboard/services/access_control.py +=================================================================== +--- ceph.orig/src/pybind/mgr/dashboard/services/access_control.py ++++ ceph/src/pybind/mgr/dashboard/services/access_control.py +@@ -11,8 +11,8 @@ import time + from datetime import datetime, timedelta + from string import ascii_lowercase, ascii_uppercase, digits, punctuation + from typing import List, Optional, Sequence ++import re + +-import bcrypt + from mgr_module import CLICheckNonemptyFileInput, CLIReadCommand, CLIWriteCommand + from mgr_util import password_hash + +@@ -888,7 +888,8 @@ def ac_user_set_password_hash(_, usernam + hashed_password = inbuf + try: + # make sure the hashed_password is actually a bcrypt hash +- bcrypt.checkpw(b'', hashed_password.encode('utf-8')) ++ if not re.fullmatch(r'\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}', hashed_password): ++ raise ValueError('Invalid bcrypt hash') + user = mgr.ACCESS_CTRL_DB.get_user(username) + user.set_password_hash(hashed_password) + +Index: ceph/src/pybind/mgr/mgr_util.py +=================================================================== +--- ceph.orig/src/pybind/mgr/mgr_util.py ++++ ceph/src/pybind/mgr/mgr_util.py +@@ -3,7 +3,7 @@ import os + if 'UNITTEST' in os.environ: + import tests + +-import bcrypt ++import crypt_r as crypt + import cephfs + import contextlib + import datetime +@@ -880,7 +880,7 @@ def password_hash(password: Optional[str + if not password: + return None + if not salt_password: +- salt = bcrypt.gensalt() ++ salt = crypt.mksalt(crypt.METHOD_BLOWFISH, rounds=4096) + else: +- salt = salt_password.encode('utf8') +- return bcrypt.hashpw(password.encode('utf8'), salt).decode('utf8') ++ salt = salt_password ++ return crypt.crypt(password, salt) diff -Nru ceph-18.2.7+ds/debian/patches/series ceph-18.2.7+ds/debian/patches/series --- ceph-18.2.7+ds/debian/patches/series 2026-05-10 21:15:52.000000000 +0200 +++ ceph-18.2.7+ds/debian/patches/series 2026-10-16 10:12:37.000000000 +0200 @@ -41,3 +41,4 @@ py313-compat/0010-ceph-volume-fix-importlib.metadata-compat.patch mgr-alerts-enforce-ssl-context-to-SMTP_SSL.patch Check-if-HTTP_X_AMZ_COPY_SOURCE-header-is-empty.patch +py313-compat/0011-mgr-replace-bcrypt-with-crypt_r.patch

