Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cinder/db/sqlalchemy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8289,7 +8289,7 @@ def _process_messages_filters(query, filters):
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)


Expand Down
44 changes: 44 additions & 0 deletions cinder/tests/unit/test_db_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2882,6 +2882,50 @@ def _create_fake_messages(self, m_id, time):
'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
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Loading