Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:cinder
User: [email protected]
Usertags: pu

Hi,

I have uploaded Cinder 26.0.0-2+deb13u1 to Trixie p-u to address
2 security issues, as per below.

[ Reason ]

- Tracked in launchpad: https://bugs.launchpad.net/cinder/+bug/2138566
project-scope the _attachment_get DB query to prevent cross-project
attachment access

- CVE-2026-93856 / OSSA-2026-045: Cross-project information disclosure
in the Cinder Messages API.

[ Impact ]
The above security problems.

[ Tests ]
The upstream fixes include new tests, also ran during package build
and autopkgtest. I also checked the fix passes my functional test CI.
Also, we've put this in production in our public cloud (different
OpenStack release though, but same patches).

[ Risks ]

CVE-2026-93856's fix is super simple:

-def _messages_get_query(context, project_only=False):
+def _messages_get_query(context, project_only=True):

and so is lp-2138566 fix, that is just adding a constraint:

project_only=project_only

when doing a SQL request with SQLAlchemy. So it is my view that it
is low risk.

[ 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

Please approve cinder/26.0.0-2+deb13u1.

Cheers,

Thomas Goirand (zigo)
diff -Nru cinder-26.0.0/debian/changelog cinder-26.0.0/debian/changelog
--- cinder-26.0.0/debian/changelog      2025-07-10 21:45:33.000000000 +0200
+++ cinder-26.0.0/debian/changelog      2026-10-08 17:31:27.000000000 +0200
@@ -1,3 +1,15 @@
+cinder (2:26.0.0-2+deb13u1) trixie; urgency=high
+
+  * Backported upstream fix: project-scope the _attachment_get DB query
+    to prevent cross-project attachment access (see launchpad bug: #2138566):
+    - lp-2138566_Fix_attachment_access_across_project.patch
+  * CVE-2026-93856 / OSSA-2026-045: Cross-project information disclosure
+    in the Cinder Messages API. Applied upstream patch "Fix cross-project
+    information disclosure in the messages API" (Closes: #1151437):
+    - CVE-2026-93856_Fix_cross-project-info-disclosure-in-messages-API.patch
+
+ -- Thomas Goirand <[email protected]>  Thu, 08 Oct 2026 17:31:27 +0200
+
 cinder (2:26.0.0-2) unstable; urgency=medium
 
   * Set export OS_OSLO_MESSAGING_RABBIT__PROCESSNAME in daemons, so they don't
diff -Nru 
cinder-26.0.0/debian/patches/CVE-2026-93856_Fix_cross-project-info-disclosure-in-messages-API.patch
 
cinder-26.0.0/debian/patches/CVE-2026-93856_Fix_cross-project-info-disclosure-in-messages-API.patch
--- 
cinder-26.0.0/debian/patches/CVE-2026-93856_Fix_cross-project-info-disclosure-in-messages-API.patch
 1970-01-01 01:00:00.000000000 +0100
+++ 
cinder-26.0.0/debian/patches/CVE-2026-93856_Fix_cross-project-info-disclosure-in-messages-API.patch
 2026-10-08 17:31:27.000000000 +0200
@@ -0,0 +1,100 @@
+Description: Fix cross-project information disclosure in the messages API
+ Make the default for project_only=True in _messages_get_query() in the db
+ api, so a 'member'/'reader' user making the "List messages" call of the
+ Block Storage API v3.3 no longer sees other projects' non-expired user
+ messages in the response (CVE-2026-93856).
+Origin: upstream, https://review.opendev.org/c/openstack/cinder/+/1011490
+Change-Id: I18635b1eb801699dd38f9af04b386b28893e6825
+Bug: https://bugs.launchpad.net/bugs/2160671
+Bug-Debian: https://bugs.debian.org/1151437
+Author: Rajat Dhasmana <[email protected]>
+Date: Wed, 7 Oct 2026 12:29:40 -0400
+Last-Update: 2026-10-20
+
+Index: cinder/cinder/db/sqlalchemy/api.py
+===================================================================
+--- cinder.orig/cinder/db/sqlalchemy/api.py
++++ cinder/cinder/db/sqlalchemy/api.py
+@@ -8290,7 +8290,7 @@ def _process_messages_filters(query, fil
+     return query
+ 
+ 
+-def _messages_get_query(context, project_only=False):
++def _messages_get_query(context, project_only=True):
+     return model_query(context, models.Message, project_only=project_only)
+ 
+ 
+Index: cinder/cinder/tests/unit/test_db_api.py
+===================================================================
+--- cinder.orig/cinder/tests/unit/test_db_api.py
++++ cinder/cinder/tests/unit/test_db_api.py
+@@ -2882,6 +2882,50 @@ class DBAPIMessageTestCase(BaseTest):
+                            'project_id': 'fake_id',
+                            'expires_at': time})
+ 
++    def _create_message(self, project_id):
++        message_id = uuidutils.generate_uuid()
++        expires_at = timeutils.utcnow() + datetime.timedelta(days=1)
++        db.message_create(self.context,
++                          {'id': message_id,
++                           'event_id': message_id,
++                           'message_level': 'error',
++                           'project_id': project_id,
++                           'expires_at': expires_at})
++        return message_id
++
++    def test_message_get_all_is_project_scoped(self):
++        project_id = 'project1'
++        other_project_id = 'project2'
++        project_message_id = self._create_message(project_id)
++        other_project_message_id = self._create_message(other_project_id)
++        user_context = context.RequestContext('user1', project_id,
++                                              is_admin=False)
++
++        messages = db.message_get_all(user_context)
++
++        self.assertEqual({project_message_id},
++                         {message['id'] for message in messages})
++        self.assertNotIn(other_project_message_id,
++                         {message['id'] for message in messages})
++        # self.context is an admin context and should see both projects.
++        admin_messages = db.message_get_all(self.context)
++        self.assertEqual({project_message_id, other_project_message_id},
++                         {message['id'] for message in admin_messages})
++
++    def test_message_get_is_project_scoped(self):
++        project_id = 'project1'
++        other_project_id = 'project2'
++        project_message_id = self._create_message(project_id)
++        other_project_message_id = self._create_message(other_project_id)
++        user_context = context.RequestContext('user1', project_id,
++                                              is_admin=False)
++
++        message = db.message_get(user_context, project_message_id)
++        self.assertEqual(project_message_id, message['id'])
++        self.assertRaises(exception.MessageNotFound,
++                          db.message_get, user_context,
++                          other_project_message_id)
++
+     def test_cleanup_expired_messages(self):
+         now = timeutils.utcnow()
+         # message expired 1 day ago
+Index: 
cinder/releasenotes/notes/bug-2160671-cve-2026-93856-2823294ed5a19f9d.yaml
+===================================================================
+--- /dev/null
++++ cinder/releasenotes/notes/bug-2160671-cve-2026-93856-2823294ed5a19f9d.yaml
+@@ -0,0 +1,14 @@
++---
++fixes:
++  - |
++    `Bug #2160671 <https://bugs.launchpad.net/cinder/+bug/2160671>`_:
++    Fixed a cross-project information disclosure issue in the Block Storage
++    API v3.3 (CVE-2026-93856), where a user with the project 'member' or
++    'reader' role making the "List messages" call could find the non-expired
++    user messages for other projects included in the response.
++security:
++  - |
++    This release contains a fix for CVE-2026-93856, `Cross-project
++    information disclosure in the Cinder Messages API`.  See
++    `Bug #2160671 <https://bugs.launchpad.net/cinder/+bug/2160671>`_
++    for details.
diff -Nru 
cinder-26.0.0/debian/patches/lp-2138566_Fix_attachment_access_across_project.patch
 
cinder-26.0.0/debian/patches/lp-2138566_Fix_attachment_access_across_project.patch
--- 
cinder-26.0.0/debian/patches/lp-2138566_Fix_attachment_access_across_project.patch
  1970-01-01 01:00:00.000000000 +0100
+++ 
cinder-26.0.0/debian/patches/lp-2138566_Fix_attachment_access_across_project.patch
  2026-10-08 17:31:27.000000000 +0200
@@ -0,0 +1,93 @@
+Description: Fix: attachment access across project
+ When a non-admin user tries to access an attachment record of
+ another project, we don't have any restriction either in API
+ layer or in DB layer that would prevent it.
+ Though, it seems dangerous, there is no trivial way of gaining
+ access to the UUIDs of attachment records of another project
+ (attachment list doesn't show UUIDs of attachments of another
+ project for non-admins).
+ This reduces the attack vector hence the impact is low.
+ This patch tries to fix it by enforcing a ``project_only``
+ condition that adds a project filter which was missing from
+ ``model_query`` call in the ``_attachment_get`` db method.
+Author: Rajat Dhasmana <[email protected]>
+Date: Fri, 23 Jan 2026 04:15:36 +0000
+Origin: upstream, https://review.opendev.org/c/openstack/cinder/+/974389
+Bug: https://bugs.launchpad.net/bugs/2138566
+Last-Update: 2026-10-08
+
+diff --git a/cinder/db/sqlalchemy/api.py b/cinder/db/sqlalchemy/api.py
+index b40f65f4f..172651e3d 100644
+--- a/cinder/db/sqlalchemy/api.py
++++ b/cinder/db/sqlalchemy/api.py
+@@ -2437,7 +2437,8 @@ def _attachment_get(
+ ):
+     result = (
+         model_query(
+-            context, models.VolumeAttachment, read_deleted=read_deleted
++            context, models.VolumeAttachment, read_deleted=read_deleted,
++            project_only=project_only,
+         )
+         .filter_by(id=attachment_id)
+         .options(joinedload(models.VolumeAttachment.volume))
+diff --git a/cinder/tests/unit/objects/test_volume_attachment.py 
b/cinder/tests/unit/objects/test_volume_attachment.py
+index 41aed7eb1..a536575ac 100644
+--- a/cinder/tests/unit/objects/test_volume_attachment.py
++++ b/cinder/tests/unit/objects/test_volume_attachment.py
+@@ -123,8 +123,10 @@ class 
TestVolumeAttachment(test_objects.BaseObjectsTestCase):
+         self.assertEqual(fields.VolumeAttachStatus.ATTACHED,
+                          attachment.attach_status)
+ 
+-    def test_migrate_attachment_specs(self):
+-        # Create an attachment.
++    @mock.patch('cinder.db.sqlalchemy.models.Volume')
++    def test_migrate_attachment_specs(self, mock_volume_model):
++        mock_volume_model.project_id = self.context.project_id
++        # Create an attachment
+         attachment = objects.VolumeAttachment(
+             self.context, attach_status='attaching', volume_id=fake.VOLUME_ID)
+         attachment.create()
+diff --git a/cinder/tests/unit/policies/test_attachments.py 
b/cinder/tests/unit/policies/test_attachments.py
+index 8d3040b2f..1d32233b0 100644
+--- a/cinder/tests/unit/policies/test_attachments.py
++++ b/cinder/tests/unit/policies/test_attachments.py
+@@ -112,7 +112,7 @@ class AttachmentsPolicyTest(base.BasePolicyTest):
+                                  rule_name, self.controller.create, req,
+                                  body=body)
+ 
+-    @ddt.data(*base.all_users)
++    @ddt.data(*authorized_users)
+     @mock.patch('cinder.volume.rpcapi.VolumeAPI.attachment_update')
+     def test_update_attachment_policy(self, user_id, mock_attachment_update):
+         # Redirect the RPC call directly to the volume manager.
+@@ -149,7 +149,7 @@ class AttachmentsPolicyTest(base.BasePolicyTest):
+                                  rule_name, self.controller.update, req,
+                                  id=attachment_id, body=body)
+ 
+-    @ddt.data(*base.all_users)
++    @ddt.data(*authorized_users)
+     @mock.patch('cinder.volume.rpcapi.VolumeAPI.attachment_delete')
+     def test_delete_attachment_policy(self, user_id, mock_attachment_delete):
+         # Redirect the RPC call directly to the volume manager.
+@@ -172,7 +172,7 @@ class AttachmentsPolicyTest(base.BasePolicyTest):
+                                  rule_name, self.controller.delete, req,
+                                  id=attachment_id)
+ 
+-    @ddt.data(*base.all_users)
++    @ddt.data(*authorized_users)
+     def test_complete_attachment_policy(self, user_id):
+         rule_name = attachments_policies.COMPLETE_POLICY
+         attachment_id = self._create_attachment()
+diff --git 
a/releasenotes/notes/fix-attachment-show-for-other-project-54dbbb35dac1da43.yaml
 
b/releasenotes/notes/fix-attachment-show-for-other-project-54dbbb35dac1da43.yaml
+new file mode 100644
+index 000000000..99620c156
+--- /dev/null
++++ 
b/releasenotes/notes/fix-attachment-show-for-other-project-54dbbb35dac1da43.yaml
+@@ -0,0 +1,7 @@
++---
++fixes:
++  - |
++    `Bug #2138566 <https://bugs.launchpad.net/cinder/+bug/2138566>`_: Fixed
++    issue when a user in a non-admin project is able to access attachment
++    records of another project given they have access to the UUID of the
++    attachment.
diff -Nru cinder-26.0.0/debian/patches/series 
cinder-26.0.0/debian/patches/series
--- cinder-26.0.0/debian/patches/series 2025-07-10 21:45:33.000000000 +0200
+++ cinder-26.0.0/debian/patches/series 2026-10-08 17:31:27.000000000 +0200
@@ -4,3 +4,5 @@
 add-params-thin_provisioning-equal-one.patch
 Fix_type_passed_to_write_function_during_backup_restoration.patch
 fix-db-schema-migration.patch
+lp-2138566_Fix_attachment_access_across_project.patch
+CVE-2026-93856_Fix_cross-project-info-disclosure-in-messages-API.patch

Reply via email to