~ubuntu-server-dev/glance/havana

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2014-0162.patch

  • Committer: Chuck Short
  • Date: 2014-04-11 14:42:55 UTC
  • Revision ID: zulcss@ubuntu.com-20140411144255-owfu2uci8mypsvaf
[13069a4] To prevent remote code injection on Sheepdog store

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 13069a4017d36a549576a21ca3ec5b15c411effc Mon Sep 17 00:00:00 2001
 
2
From: Zhi Yan Liu <zhiyanl@cn.ibm.com>
 
3
Date: Sat, 29 Mar 2014 03:35:35 +0800
 
4
Subject: [PATCH 23/23] To prevent remote code injection on Sheepdog store
 
5
 
 
6
Change-Id: Iae92eaf9eb023f36a1bab7c20ea41c985f2bf51b
 
7
Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
 
8
diff -Naurp glance-2013.2.3.orig/glance/store/sheepdog.py glance-2013.2.3/glance/store/sheepdog.py
 
9
--- glance-2013.2.3.orig/glance/store/sheepdog.py       2014-04-03 14:43:55.000000000 -0400
 
10
+++ glance-2013.2.3/glance/store/sheepdog.py    2014-04-11 10:15:46.137975403 -0400
 
11
@@ -25,6 +25,7 @@ from glance.common import exception
 
12
 from glance.openstack.common import excutils
 
13
 import glance.openstack.common.log as logging
 
14
 from glance.openstack.common import processutils
 
15
+from glance.openstack.common import uuidutils
 
16
 import glance.store
 
17
 import glance.store.base
 
18
 import glance.store.location
 
19
@@ -32,7 +33,7 @@ import glance.store.location
 
20
 
 
21
 LOG = logging.getLogger(__name__)
 
22
 
 
23
-DEFAULT_ADDR = 'localhost'
 
24
+DEFAULT_ADDR = '127.0.0.1'
 
25
 DEFAULT_PORT = '7000'
 
26
 DEFAULT_CHUNKSIZE = 64  # in MiB
 
27
 
 
28
@@ -63,18 +64,14 @@ class SheepdogImage:
 
29
         self.chunk_size = chunk_size
 
30
 
 
31
     def _run_command(self, command, data, *params):
 
32
-        cmd = ("collie vdi %(command)s -a %(addr)s -p %(port)s %(name)s "
 
33
-               "%(params)s" %
 
34
-               {"command": command,
 
35
-                "addr": self.addr,
 
36
-                "port": self.port,
 
37
-                "name": self.name,
 
38
-                "params": " ".join(map(str, params))})
 
39
+        cmd = ["collie", "vdi"]
 
40
+        cmd.extend(command)
 
41
+        cmd.extend(["-a", self.addr, "-p", self.port, self.name])
 
42
+        cmd.extend(params)
 
43
 
 
44
         try:
 
45
-            return processutils.execute(
 
46
-                cmd, process_input=data, shell=True)[0]
 
47
-        except processutils.ProcessExecutionError as exc:
 
48
+            return processutils.execute(*cmd, process_input=data)[0]
 
49
+        except (processutils.ProcessExecutionError, OSError) as exc:
 
50
             LOG.error(exc)
 
51
             raise glance.store.BackendException(exc)
 
52
 
 
53
@@ -84,7 +81,7 @@ class SheepdogImage:
 
54
 
 
55
         Sheepdog Usage: collie vdi list -r -a address -p port image
 
56
         """
 
57
-        out = self._run_command("list -r", None)
 
58
+        out = self._run_command(["list", "-r"], None)
 
59
         return long(out.split(' ')[3])
 
60
 
 
61
     def read(self, offset, count):
 
62
@@ -94,7 +91,7 @@ class SheepdogImage:
 
63
 
 
64
         Sheepdog Usage: collie vdi read -a address -p port image offset len
 
65
         """
 
66
-        return self._run_command("read", None, str(offset), str(count))
 
67
+        return self._run_command(["read"], None, str(offset), str(count))
 
68
 
 
69
     def write(self, data, offset, count):
 
70
         """
 
71
@@ -103,7 +100,7 @@ class SheepdogImage:
 
72
 
 
73
         Sheepdog Usage: collie vdi write -a address -p port image offset len
 
74
         """
 
75
-        self._run_command("write", data, str(offset), str(count))
 
76
+        self._run_command(["write"], data, str(offset), str(count))
 
77
 
 
78
     def create(self, size):
 
79
         """
 
80
@@ -111,7 +108,7 @@ class SheepdogImage:
 
81
 
 
82
         Sheepdog Usage: collie vdi create -a address -p port image size
 
83
         """
 
84
-        self._run_command("create", None, str(size))
 
85
+        self._run_command(["create"], None, str(size))
 
86
 
 
87
     def delete(self):
 
88
         """
 
89
@@ -119,7 +116,7 @@ class SheepdogImage:
 
90
 
 
91
         Sheepdog Usage: collie vdi delete -a address -p port image
 
92
         """
 
93
-        self._run_command("delete", None)
 
94
+        self._run_command(["delete"], None)
 
95
 
 
96
     def exist(self):
 
97
         """
 
98
@@ -127,7 +124,7 @@ class SheepdogImage:
 
99
 
 
100
         Sheepdog Usage: collie vdi list -r -a address -p port image
 
101
         """
 
102
-        out = self._run_command("list -r", None)
 
103
+        out = self._run_command(["list", "-r"], None)
 
104
         if not out:
 
105
             return False
 
106
         else:
 
107
@@ -138,7 +135,7 @@ class StoreLocation(glance.store.locatio
 
108
     """
 
109
     Class describing a Sheepdog URI. This is of the form:
 
110
 
 
111
-        sheepdog://image
 
112
+        sheepdog://image-id
 
113
 
 
114
     """
 
115
 
 
116
@@ -149,10 +146,14 @@ class StoreLocation(glance.store.locatio
 
117
         return "sheepdog://%s" % self.image
 
118
 
 
119
     def parse_uri(self, uri):
 
120
-        if not uri.startswith('sheepdog://'):
 
121
-            raise exception.BadStoreUri(uri, "URI must start with %s://" %
 
122
-                                        'sheepdog')
 
123
-        self.image = uri[11:]
 
124
+        valid_schema = 'sheepdog://'
 
125
+        if not uri.startswith(valid_schema):
 
126
+            raise exception.BadStoreUri(_("URI must start with %s://") %
 
127
+                                        valid_schema)
 
128
+        self.image = uri[len(valid_schema):]
 
129
+        if not uuidutils.is_uuid_like(self.image):
 
130
+            raise exception.BadStoreUri(_("URI must contains well-formated "
 
131
+                                          "image id"))
 
132
 
 
133
 
 
134
 class ImageIterator(object):
 
135
@@ -192,7 +193,7 @@ class Store(glance.store.base.Store):
 
136
 
 
137
         try:
 
138
             self.chunk_size = CONF.sheepdog_store_chunk_size * 1024 * 1024
 
139
-            self.addr = CONF.sheepdog_store_address
 
140
+            self.addr = CONF.sheepdog_store_address.strip()
 
141
             self.port = CONF.sheepdog_store_port
 
142
         except cfg.ConfigFileValueError as e:
 
143
             reason = _("Error in store configuration: %s") % e
 
144
@@ -200,10 +201,18 @@ class Store(glance.store.base.Store):
 
145
             raise exception.BadStoreConfiguration(store_name='sheepdog',
 
146
                                                   reason=reason)
 
147
 
 
148
+        if ' ' in self.addr:
 
149
+            reason = (_("Invalid address configuration of sheepdog store: %s")
 
150
+                      % self.addr)
 
151
+            LOG.error(reason)
 
152
+            raise exception.BadStoreConfiguration(store_name='sheepdog',
 
153
+                                                  reason=reason)
 
154
+
 
155
         try:
 
156
-            processutils.execute("collie", shell=True)
 
157
-        except processutils.ProcessExecutionError as exc:
 
158
-            reason = _("Error in store configuration: %s") % exc
 
159
+            cmd = ["collie", "vdi", "list", "-a", self.addr, "-p", self.port]
 
160
+            processutils.execute(*cmd)
 
161
+        except Exception as e:
 
162
+            reason = _("Error in store configuration: %s") % e
 
163
             LOG.error(reason)
 
164
             raise exception.BadStoreConfiguration(store_name='sheepdog',
 
165
                                                   reason=reason)
 
166
diff -Naurp glance-2013.2.3.orig/glance/tests/unit/test_sheepdog_store.py glance-2013.2.3/glance/tests/unit/test_sheepdog_store.py
 
167
--- glance-2013.2.3.orig/glance/tests/unit/test_sheepdog_store.py       2014-04-03 14:43:55.000000000 -0400
 
168
+++ glance-2013.2.3/glance/tests/unit/test_sheepdog_store.py    2014-04-11 10:15:46.137975403 -0400
 
169
@@ -57,4 +57,5 @@ class TestStore(base.StoreClearingUnitTe
 
170
                           'fake_image_id',
 
171
                           utils.LimitingReader(StringIO.StringIO('xx'), 1),
 
172
                           2)
 
173
-        self.assertEqual(called_commands, ['list -r', 'create', 'delete'])
 
174
+        self.assertEqual([['list', '-r'], ['create'], ['delete']],
 
175
+                         called_commands)
 
176
diff -Naurp glance-2013.2.3.orig/glance/tests/unit/test_store_location.py glance-2013.2.3/glance/tests/unit/test_store_location.py
 
177
--- glance-2013.2.3.orig/glance/tests/unit/test_store_location.py       2014-04-03 14:43:55.000000000 -0400
 
178
+++ glance-2013.2.3/glance/tests/unit/test_store_location.py    2014-04-11 10:15:46.141975403 -0400
 
179
@@ -52,7 +52,7 @@ class TestStoreLocation(base.StoreCleari
 
180
             'rbd://imagename',
 
181
             'rbd://fsid/pool/image/snap',
 
182
             'rbd://%2F/%2F/%2F/%2F',
 
183
-            'sheepdog://imagename',
 
184
+            'sheepdog://244e75f1-9c69-4167-9db7-1aa7d1973f6c',
 
185
             'cinder://12345678-9012-3455-6789-012345678901',
 
186
         ]
 
187
 
 
188
@@ -367,15 +367,18 @@ class TestStoreLocation(base.StoreCleari
 
189
         """
 
190
         Test the specific StoreLocation for the Sheepdog store
 
191
         """
 
192
-        uri = 'sheepdog://imagename'
 
193
+        uri = 'sheepdog://244e75f1-9c69-4167-9db7-1aa7d1973f6c'
 
194
         loc = glance.store.sheepdog.StoreLocation({})
 
195
         loc.parse_uri(uri)
 
196
-        self.assertEqual('imagename', loc.image)
 
197
+        self.assertEqual('244e75f1-9c69-4167-9db7-1aa7d1973f6c', loc.image)
 
198
 
 
199
-        bad_uri = 'sheepdog:/image'
 
200
+        bad_uri = 'sheepdog:/244e75f1-9c69-4167-9db7-1aa7d1973f6c'
 
201
         self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri)
 
202
 
 
203
-        bad_uri = 'http://image'
 
204
+        bad_uri = 'http://244e75f1-9c69-4167-9db7-1aa7d1973f6c'
 
205
+        self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri)
 
206
+
 
207
+        bad_uri = 'image; name'
 
208
         self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri)
 
209
 
 
210
     def test_cinder_store_good_location(self):