[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#954269: buster-pu: package manila/1:7.0.0-1 CVE-2020-9543



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

Dear Stable Release Team,

The security team told me that this update is a no-DSA. Can I upload this
Manila update to proposed-updates then?

If you didn't know, Manila is OpenStack's file system share as a service
(like for example, NFS share as a service, running on top of a Cinder or
a Ceph block storage, or CephFS, or a proprietary NAS, etc.).

FYI, the security bug is that anyone knowing an UUID of a Manila share,
can basically do whatever it wants with it. It's no DSA because guessing
such an UUID isn't practical, and an operator would likely notice if one
is attempting to brute-force. I still think it deserves patching Buster.

Debdiff attached.

Cheers,

Thomas Goirand (zigo)
diff -Nru manila-7.0.0/debian/changelog manila-7.0.0/debian/changelog
--- manila-7.0.0/debian/changelog	2018-09-05 15:53:37.000000000 +0200
+++ manila-7.0.0/debian/changelog	2020-03-09 15:53:45.000000000 +0100
@@ -1,3 +1,11 @@
+manila (1:7.0.0-1+deb10u1) buster; urgency=medium
+
+  * CVE-2020-9543: Manila allows other project users to view, update, delete,
+    or share resources that do not belong to them. Applied upstream patch:
+    share_networks: enable project_only API only (Closes: #953581).
+
+ -- Thomas Goirand <zigo@debian.org>  Mon, 09 Mar 2020 15:53:45 +0100
+
 manila (1:7.0.0-1) unstable; urgency=medium
 
   [ Ondřej Nový ]
diff -Nru manila-7.0.0/debian/patches/CVE-2020-9543_share_networks_enable_project_only_API_only.patch manila-7.0.0/debian/patches/CVE-2020-9543_share_networks_enable_project_only_API_only.patch
--- manila-7.0.0/debian/patches/CVE-2020-9543_share_networks_enable_project_only_API_only.patch	1970-01-01 01:00:00.000000000 +0100
+++ manila-7.0.0/debian/patches/CVE-2020-9543_share_networks_enable_project_only_API_only.patch	2020-03-09 15:53:45.000000000 +0100
@@ -0,0 +1,124 @@
+Description: CVE-2020-9543: share_networks: enable project_only API only
+ At the moment, the share_network database API which the web
+ API layer interacts with directly does not have any checking
+ for project_id which means that a user has the ability to run
+ operations against any other share_network if they have the ID.
+ .
+ This patch implements the usage of project_only in the database
+ query which ensures that administrators still have the behaviour
+ of getting any share network they want, but users can only pull
+ up those which are part of their context/authenticated project.
+ .
+ This patch also adjusts a few other tests due to the fact that
+ the existing tests would run a lot of inserts with a different
+ project_id than the context, which is not allowed in this new
+ API behaviour.  Therefore, the instances that involved projects
+ different than the context were converted to elevated ones.
+ .
+ There was also an instance where they were being created with a
+ project_id that did not match the fake context, therefore the
+ context was adjusted accordingly as well.
+Author: Mohammed Naser <mnaser@vexxhost.com>
+Date: Fri, 31 Jan 2020 16:13:24 +0100
+Change-Id: Id67a939a475c4ac06d546b7e095bd10f1a6d2619
+Origin: upstream
+Bug-Debian: https://bugs.debian.org/953581
+Last-Update: 2020-03-09
+
+Index: manila/manila/db/sqlalchemy/api.py
+===================================================================
+--- manila.orig/manila/db/sqlalchemy/api.py
++++ manila/manila/db/sqlalchemy/api.py
+@@ -3330,7 +3330,8 @@ def _security_service_get_query(context,
+ def _network_get_query(context, session=None):
+     if session is None:
+         session = get_session()
+-    return (model_query(context, models.ShareNetwork, session=session).
++    return (model_query(context, models.ShareNetwork, session=session,
++                        project_only=True).
+             options(joinedload('share_instances'),
+                     joinedload('security_services'),
+                     joinedload('share_servers')))
+Index: manila/manila/tests/db/sqlalchemy/test_api.py
+===================================================================
+--- manila.orig/manila/tests/db/sqlalchemy/test_api.py
++++ manila/manila/tests/db/sqlalchemy/test_api.py
+@@ -1966,7 +1966,7 @@ class ShareNetworkDatabaseAPITestCase(Ba
+         share_nw_dict2['project_id'] = 'fake project 2'
+         result1 = db_api.share_network_create(self.fake_context,
+                                               self.share_nw_dict)
+-        result2 = db_api.share_network_create(self.fake_context,
++        result2 = db_api.share_network_create(self.fake_context.elevated(),
+                                               share_nw_dict2)
+ 
+         self._check_fields(expected=self.share_nw_dict, actual=result1)
+@@ -1999,6 +1999,33 @@ class ShareNetworkDatabaseAPITestCase(Ba
+         self.assertEqual(0, len(result['share_instances']))
+         self.assertEqual(0, len(result['security_services']))
+ 
++    def _create_share_network_for_project(self, project_id):
++        ctx = context.RequestContext(user_id='fake user',
++                                     project_id=project_id,
++                                     is_admin=False)
++
++        share_data = self.share_nw_dict.copy()
++        share_data['project_id'] = project_id
++
++        db_api.share_network_create(ctx, share_data)
++        return share_data
++
++    def test_get_other_tenant_as_admin(self):
++        expected = self._create_share_network_for_project('fake project 2')
++        result = db_api.share_network_get(self.fake_context.elevated(),
++                                          self.share_nw_dict['id'])
++
++        self._check_fields(expected=expected, actual=result)
++        self.assertEqual(0, len(result['share_instances']))
++        self.assertEqual(0, len(result['security_services']))
++
++    def test_get_other_tenant(self):
++        self._create_share_network_for_project('fake project 2')
++        self.assertRaises(exception.ShareNetworkNotFound,
++                          db_api.share_network_get,
++                          self.fake_context,
++                          self.share_nw_dict['id'])
++
+     @ddt.data([{'id': 'fake share id1'}],
+               [{'id': 'fake share id1'}, {'id': 'fake share id2'}],)
+     def test_get_with_shares(self, shares):
+@@ -2094,25 +2121,30 @@ class ShareNetworkDatabaseAPITestCase(Ba
+             share_network_dict.update({'id': fake_id,
+                                        'neutron_subnet_id': fake_id})
+             share_networks.append(share_network_dict)
+-            db_api.share_network_create(self.fake_context, share_network_dict)
++            db_api.share_network_create(self.fake_context.elevated(),
++                                        share_network_dict)
+             index += 1
+ 
+-        result = db_api.share_network_get_all(self.fake_context)
++        result = db_api.share_network_get_all(self.fake_context.elevated())
+ 
+         self.assertEqual(len(share_networks), len(result))
+         for index, net in enumerate(share_networks):
+             self._check_fields(expected=net, actual=result[index])
+ 
+     def test_get_all_by_project(self):
++        db_api.share_network_create(self.fake_context, self.share_nw_dict)
++
+         share_nw_dict2 = dict(self.share_nw_dict)
+         share_nw_dict2['id'] = 'fake share nw id2'
+         share_nw_dict2['project_id'] = 'fake project 2'
+         share_nw_dict2['neutron_subnet_id'] = 'fake subnet id2'
+-        db_api.share_network_create(self.fake_context, self.share_nw_dict)
+-        db_api.share_network_create(self.fake_context, share_nw_dict2)
++        new_context = context.RequestContext(user_id='fake user 2',
++                                             project_id='fake project 2',
++                                             is_admin=False)
++        db_api.share_network_create(new_context, share_nw_dict2)
+ 
+         result = db_api.share_network_get_all_by_project(
+-            self.fake_context,
++            self.fake_context.elevated(),
+             share_nw_dict2['project_id'])
+ 
+         self.assertEqual(1, len(result))
diff -Nru manila-7.0.0/debian/patches/series manila-7.0.0/debian/patches/series
--- manila-7.0.0/debian/patches/series	2018-09-05 15:53:37.000000000 +0200
+++ manila-7.0.0/debian/patches/series	2020-03-09 15:53:45.000000000 +0100
@@ -1 +1,2 @@
 install-missing-files.patch
+CVE-2020-9543_share_networks_enable_project_only_API_only.patch

Reply to: