Browse code

libsolv: Fix for CVE-2018-20532, CVE-2018-20533, CVE-2018-20534

Change-Id: Ic02ea57c934dfeda1fff2e46f60372a94a0e3b73
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6716
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>

Keerthana K authored on 2019/02/14 18:11:28
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,348 @@
0
+From c5883b20b7b021ee94111cb72777ab3ba3f50950 Mon Sep 17 00:00:00 2001
1
+From: Jaroslav Rohel <jrohel@redhat.com>
2
+Date: Fri, 7 Dec 2018 07:05:10 +0100
3
+Subject: [PATCH 1/7] Fix: Dereference of null pointer
4
+
5
+---
6
+ ext/repo_repomdxml.c | 2 +-
7
+ 1 file changed, 1 insertion(+), 1 deletion(-)
8
+
9
+diff --git a/ext/repo_repomdxml.c b/ext/repo_repomdxml.c
10
+index fd46272b..46d83615 100644
11
+--- a/ext/repo_repomdxml.c
12
+@@ -181,7 +181,7 @@ startElement(struct solv_xmlparser *xmlp, int state, const char *name, const cha
13
+             while (value)
14
+ 	      {
15
+ 		char *p = strchr(value, ',');
16
+-		if (*p)
17
++		if (p)
18
+ 		  *p++ = 0;
19
+ 		if (*value)
20
+ 		  repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_UPDATES, value);
21
+
22
+From 8e1dba061d7962441f7e06b9a94d0ff24b158c6a Mon Sep 17 00:00:00 2001
23
+From: Jaroslav Rohel <jrohel@redhat.com>
24
+Date: Tue, 11 Dec 2018 09:50:06 +0100
25
+Subject: [PATCH 2/7] Fix: Add va_end() before return
26
+
27
+The va_end() performs cleanup.
28
+If va_end() is not called before a function that calls va_start() returns,
29
+the behavior is undefined.
30
+---
31
+ src/pool.c | 1 +
32
+ 1 file changed, 1 insertion(+)
33
+
34
+diff --git a/src/pool.c b/src/pool.c
35
+index 383edb2a..be6a4193 100644
36
+--- a/src/pool.c
37
+@@ -1536,6 +1536,7 @@ pool_debug(Pool *pool, int type, const char *format, ...)
38
+         vprintf(format, args);
39
+       else
40
+         vfprintf(stderr, format, args);
41
++      va_end(args);
42
+       return;
43
+     }
44
+   vsnprintf(buf, sizeof(buf), format, args);
45
+
46
+From 98a75959e13699e2ef35b0b011a88a6d224f227e Mon Sep 17 00:00:00 2001
47
+From: Jaroslav Rohel <jrohel@redhat.com>
48
+Date: Tue, 11 Dec 2018 10:14:04 +0100
49
+Subject: [PATCH 3/7] Fix: Memory leaks
50
+
51
+---
52
+ ext/repo_rpmdb.c  | 16 ++++++++++++++++
53
+ ext/testcase.c    |  4 ++++
54
+ tools/repo2solv.c |  1 +
55
+ 3 files changed, 21 insertions(+)
56
+
57
+diff --git a/ext/repo_rpmdb.c b/ext/repo_rpmdb.c
58
+index 9acb4006..0d648208 100644
59
+--- a/ext/repo_rpmdb.c
60
+@@ -1896,6 +1896,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
61
+   if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb)
62
+     {
63
+       pool_error(pool, -1, "%s: not a rpm", rpm);
64
++      solv_chksum_free(leadsigchksumh, NULL);
65
++      solv_chksum_free(chksumh, NULL);
66
+       fclose(fp);
67
+       return 0;
68
+     }
69
+@@ -1908,12 +1910,16 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
70
+   if (lead[78] != 0 || lead[79] != 5)
71
+     {
72
+       pool_error(pool, -1, "%s: not a rpm v5 header", rpm);
73
++      solv_chksum_free(leadsigchksumh, NULL);
74
++      solv_chksum_free(chksumh, NULL);
75
+       fclose(fp);
76
+       return 0;
77
+     }
78
+   if (getu32(lead + 96) != 0x8eade801)
79
+     {
80
+       pool_error(pool, -1, "%s: bad signature header", rpm);
81
++      solv_chksum_free(leadsigchksumh, NULL);
82
++      solv_chksum_free(chksumh, NULL);
83
+       fclose(fp);
84
+       return 0;
85
+     }
86
+@@ -1922,6 +1928,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
87
+   if (sigcnt >= MAX_SIG_CNT || sigdsize >= MAX_SIG_DSIZE)
88
+     {
89
+       pool_error(pool, -1, "%s: bad signature header", rpm);
90
++      solv_chksum_free(leadsigchksumh, NULL);
91
++      solv_chksum_free(chksumh, NULL);
92
+       fclose(fp);
93
+       return 0;
94
+     }
95
+@@ -1971,6 +1981,8 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
96
+ 	  if (fread(lead, l, 1, fp) != 1)
97
+ 	    {
98
+ 	      pool_error(pool, -1, "%s: unexpected EOF", rpm);
99
++          solv_chksum_free(leadsigchksumh, NULL);
100
++          solv_chksum_free(chksumh, NULL);
101
+ 	      fclose(fp);
102
+ 	      return 0;
103
+ 	    }
104
+@@ -1991,6 +2003,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
105
+   if (fread(lead, 16, 1, fp) != 1)
106
+     {
107
+       pool_error(pool, -1, "%s: unexpected EOF", rpm);
108
++      solv_chksum_free(chksumh, NULL);
109
+       fclose(fp);
110
+       return 0;
111
+     }
112
+@@ -1999,6 +2012,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
113
+   if (getu32(lead) != 0x8eade801)
114
+     {
115
+       pool_error(pool, -1, "%s: bad header", rpm);
116
++      solv_chksum_free(chksumh, NULL);
117
+       fclose(fp);
118
+       return 0;
119
+     }
120
+@@ -2007,6 +2021,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
121
+   if (sigcnt >= MAX_HDR_CNT || sigdsize >= MAX_HDR_DSIZE)
122
+     {
123
+       pool_error(pool, -1, "%s: bad header", rpm);
124
++      solv_chksum_free(chksumh, NULL);
125
+       fclose(fp);
126
+       return 0;
127
+     }
128
+diff --git a/ext/testcase.c b/ext/testcase.c
129
+index b815c563..33998d47 100644
130
+--- a/ext/testcase.c
131
+@@ -2311,6 +2311,7 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
132
+ 	  if (fclose(fp))
133
+ 	    {
134
+ 	      pool_debug(solv->pool, SOLV_ERROR, "testcase_write: write error\n");
135
++              solv_free(result);
136
+ 	      strqueue_free(&sq);
137
+ 	      return 0;
138
+ 	    }
139
+@@ -2323,12 +2324,14 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
140
+   if (!(fp = fopen(out, "w")))
141
+     {
142
+       pool_debug(solv->pool, SOLV_ERROR, "testcase_write: could not open '%s' for writing\n", out);
143
++      solv_free(cmd);
144
+       strqueue_free(&sq);
145
+       return 0;
146
+     }
147
+   if (*cmd && fwrite(cmd, strlen(cmd), 1, fp) != 1)
148
+     {
149
+       pool_debug(solv->pool, SOLV_ERROR, "testcase_write: write error\n");
150
++      solv_free(cmd);
151
+       strqueue_free(&sq);
152
+       fclose(fp);
153
+       return 0;
154
+@@ -2336,6 +2339,7 @@ testcase_write_mangled(Solver *solv, const char *dir, int resultflags, const cha
155
+   if (fclose(fp))
156
+     {
157
+       pool_debug(solv->pool, SOLV_ERROR, "testcase_write: write error\n");
158
++      solv_free(cmd);
159
+       strqueue_free(&sq);
160
+       return 0;
161
+     }
162
+From 95c3d1b3aad7a003d129b957cf449d11edaca67b Mon Sep 17 00:00:00 2001
163
+From: Jaroslav Rohel <jrohel@redhat.com>
164
+Date: Tue, 11 Dec 2018 10:22:09 +0100
165
+Subject: [PATCH 4/7] Fix: testsolv segfault
166
+
167
+ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fab0e11bf2b bp 0x7ffdfc044b70 sp 0x7ffdfc044a90 T0)
168
+0 0x7fab0e11bf2a in testcase_str2dep_complex /home/company/real_sanitize/libsolv-master/ext/testcase.c:577
169
+1 0x7fab0e11c80f in testcase_str2dep /home/company/real_sanitize/libsolv-master/ext/testcase.c:656
170
+2 0x7fab0e12e64a in testcase_read /home/company/real_sanitize/libsolv-master/ext/testcase.c:2952
171
+3 0x402aa5 in main /home/company/real_sanitize/libsolv-master/tools/testsolv.c:148
172
+4 0x7fab0d9d2a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
173
+5 0x401bb8 in _start (/home/company/real_sanitize/libsolv-master/build/install/bin/testsolv+0x401bb8)
174
+---
175
+ ext/testcase.c | 2 ++
176
+ 1 file changed, 2 insertions(+)
177
+
178
+diff --git a/ext/testcase.c b/ext/testcase.c
179
+index 33998d47..fe2636cb 100644
180
+--- a/ext/testcase.c
181
+@@ -576,6 +576,8 @@ testcase_str2dep_complex(Pool *pool, const char **sp, int relop)
182
+   Id flags, id, id2, namespaceid = 0;
183
+   struct oplist *op;
184
+ 
185
++  if (!s)
186
++    return 0;
187
+   while (*s == ' ' || *s == '\t')
188
+     s++;
189
+   if (!strncmp(s, "namespace:", 10))
190
+
191
+From 6de825c4d27022e48570824f0be77132c5b6d45a Mon Sep 17 00:00:00 2001
192
+From: Jaroslav Rohel <jrohel@redhat.com>
193
+Date: Tue, 11 Dec 2018 10:27:15 +0100
194
+Subject: [PATCH 5/7] Fix: testsolv segfaults
195
+
196
+ERROR: AddressSanitizer: SEGV on unknown address 0x0000000002f0 (pc 0x7f31501d3bd2 bp 0x7ffcfe4d4a50 sp 0x7ffcfe4d4a30 T0)
197
+0 0x7f31501d3bd1 in pool_whatprovides /home/company/real_sanitize/libsolv-master/src/pool.h:331
198
+1 0x7f31501d895e in testcase_str2solvid /home/company/real_sanitize/libsolv-master/ext/testcase.c:793
199
+2 0x7f31501e8388 in testcase_read /home/company/real_sanitize/libsolv-master/ext/testcase.c:2807
200
+3 0x402aa5 in main /home/company/real_sanitize/libsolv-master/tools/testsolv.c:148
201
+4 0x7f314fa8da3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
202
+5 0x401bb8 in _start (/home/company/real_sanitize/libsolv-master/build/install/bin/testsolv+0x401bb8)
203
+
204
+ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f5af9e7815f bp 0x7ffc4c843a40 sp 0x7ffc4c8436c0 T0)
205
+0 0x7f5af9e7815e in testcase_read /home/company/real_sanitize/libsolv-master/ext/testcase.c:2799
206
+1 0x402aa5 in main /home/company/real_sanitize/libsolv-master/tools/testsolv.c:148
207
+2 0x7f5af971da3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
208
+3 0x401bb8 in _start (/home/company/real_sanitize/libsolv-master/build/install/bin/testsolv+0x401bb8)
209
+---
210
+ ext/testcase.c | 2 +-
211
+ 1 file changed, 1 insertion(+), 1 deletion(-)
212
+
213
+diff --git a/ext/testcase.c b/ext/testcase.c
214
+index fe2636cb..c8dd14ee 100644
215
+--- a/ext/testcase.c
216
+@@ -2718,7 +2718,7 @@ testcase_read(Pool *pool, FILE *fp, const char *testcase, Queue *job, char **res
217
+ 	{
218
+ 	  int i = strlen(pieces[1]);
219
+ 	  s = strchr(pieces[1], '(');
220
+-	  if (!s && pieces[1][i - 1] != ')')
221
++	  if (!s || pieces[1][i - 1] != ')')
222
+ 	    {
223
+ 	      pool_debug(pool, SOLV_ERROR, "testcase_read: bad namespace '%s'\n", pieces[1]);
224
+ 	    }
225
+From bbfce7d10015fd7f72bcd5dbbca6c30f02cd7f4d Mon Sep 17 00:00:00 2001
226
+From: Jaroslav Rohel <jrohel@redhat.com>
227
+Date: Tue, 11 Dec 2018 12:40:42 +0100
228
+Subject: [PATCH 6/7] Fix: Be sure that NONBLOCK is set
229
+
230
+---
231
+ examples/solv/fastestmirror.c | 6 +++++-
232
+ 1 file changed, 5 insertions(+), 1 deletion(-)
233
+
234
+diff --git a/examples/solv/fastestmirror.c b/examples/solv/fastestmirror.c
235
+index d2ebd97a..0ee4e73b 100644
236
+--- a/examples/solv/fastestmirror.c
237
+@@ -68,7 +68,11 @@ findfastest(char **urls, int nurls)
238
+ 	  socks[i] = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
239
+ 	  if (socks[i] >= 0)
240
+ 	    {
241
+-	      fcntl(socks[i], F_SETFL, O_NONBLOCK);
242
++	      if (fcntl(socks[i], F_SETFL, O_NONBLOCK) == -1)
243
++            {
244
++		      close(socks[i]);
245
++		      socks[i] = -1;
246
++            }
247
+ 	      if (connect(socks[i], result->ai_addr, result->ai_addrlen) == -1)
248
+ 		{
249
+ 		  if (errno != EINPROGRESS)
250
+
251
+From 2d7b115fbbe6b2f2894221e010cd75638a8eaa37 Mon Sep 17 00:00:00 2001
252
+From: Jaroslav Rohel <jrohel@redhat.com>
253
+Date: Tue, 11 Dec 2018 12:58:34 +0100
254
+Subject: [PATCH 7/7] Don't set values that are never read
255
+
256
+---
257
+ ext/pool_fileconflicts.c | 1 -
258
+ ext/repo_appdata.c       | 2 +-
259
+ ext/repo_comps.c         | 2 +-
260
+ src/cleandeps.c          | 1 -
261
+ src/dirpool.c            | 2 +-
262
+ src/order.c              | 1 -
263
+ src/repopage.c           | 1 -
264
+ 7 files changed, 3 insertions(+), 7 deletions(-)
265
+
266
+diff --git a/ext/pool_fileconflicts.c b/ext/pool_fileconflicts.c
267
+index eaeb52b2..2fd3d540 100644
268
+--- a/ext/pool_fileconflicts.c
269
+@@ -590,7 +590,6 @@ findfileconflicts_alias_cb(void *cbdatav, const char *fn, struct filelistinfo *i
270
+ 
271
+   if (!info->dirlen)
272
+     return;
273
+-  dp = fn + info->dirlen;
274
+   if (info->diridx != cbdata->lastdiridx)
275
+     {
276
+       cbdata->lastdiridx = info->diridx;
277
+diff --git a/ext/repo_appdata.c b/ext/repo_appdata.c
278
+index 31749686..b798af4c 100644
279
+--- a/ext/repo_appdata.c
280
+@@ -129,7 +129,7 @@ startElement(void *userData, const char *name, const char **atts)
281
+ {
282
+   struct parsedata *pd = userData;
283
+   Pool *pool = pd->pool;
284
+-  Solvable *s = pd->solvable;
285
++  Solvable *s;
286
+   struct stateswitch *sw;
287
+   const char *type;
288
+ 
289
+diff --git a/ext/repo_comps.c b/ext/repo_comps.c
290
+index 9400e1ea..69916567 100644
291
+--- a/ext/repo_comps.c
292
+@@ -150,7 +150,7 @@ startElement(void *userData, const char *name, const char **atts)
293
+ {
294
+   struct parsedata *pd = userData;
295
+   Pool *pool = pd->pool;
296
+-  Solvable *s = pd->solvable;
297
++  Solvable *s;
298
+   struct stateswitch *sw;
299
+ 
300
+ #if 0
301
+diff --git a/src/dirpool.c b/src/dirpool.c
302
+index afb26ea5..bed9435e 100644
303
+--- a/src/dirpool.c
304
+@@ -85,7 +85,7 @@ dirpool_make_dirtraverse(Dirpool *dp)
305
+     return;
306
+   dp->dirs = solv_extend_resize(dp->dirs, dp->ndirs, sizeof(Id), DIR_BLOCK);
307
+   dirtraverse = solv_calloc_block(dp->ndirs, sizeof(Id), DIR_BLOCK);
308
+-  for (parent = 0, i = 0; i < dp->ndirs; i++)
309
++  for (i = 0; i < dp->ndirs; i++)
310
+     {
311
+       if (dp->dirs[i] > 0)
312
+ 	continue;
313
+diff --git a/src/order.c b/src/order.c
314
+index c0cc07f4..c45a9a22 100644
315
+--- a/src/order.c
316
+@@ -1008,7 +1008,6 @@ transaction_order(Transaction *trans, int flags)
317
+ #if 0
318
+ printf("do %s [%d]\n", pool_solvid2str(pool, te->p), temedianr[i]);
319
+ #endif
320
+-      s = pool->solvables + te->p;
321
+       for (j = te->edges; od.invedgedata[j]; j++)
322
+ 	{
323
+ 	  struct _TransactionElement *te2 = od.tes + od.invedgedata[j];
324
+diff --git a/src/repopage.c b/src/repopage.c
325
+index 2b7a863b..85d53eb9 100644
326
+--- a/src/repopage.c
327
+@@ -399,7 +399,6 @@ compress_buf(const unsigned char *in, unsigned int in_len,
328
+ 	      litlen -= 32;
329
+ 	    }
330
+ 	}
331
+-      litofs = 0;
332
+     }
333
+   return oo;
334
+ }
... ...
@@ -1,11 +1,12 @@
1 1
 Summary:        Libsolv-0.6.19
2 2
 Name:           libsolv
3 3
 Version:        0.6.26
4
-Release:        3%{?dist}
4
+Release:        4%{?dist}
5 5
 License:        BSD
6 6
 URL:            https://github.com/openSUSE/libsolv
7 7
 Source0:        https://github.com/openSUSE/libsolv/archive/%{name}-%{version}.tar.gz
8 8
 %define sha1    libsolv=7699af00e648bf3e631246559c48ceb7f3f544b9
9
+Patch0:         CVE-2018-20532-20533-20534.patch
9 10
 Group:          Development/Tools
10 11
 Vendor:         VMware, Inc.
11 12
 Distribution:   Photon
... ...
@@ -29,6 +30,7 @@ for developing applications that use libsolv.
29 29
 
30 30
 %prep
31 31
 %setup -q
32
+%patch0 -p1
32 33
 %build
33 34
 cmake \
34 35
     -DCMAKE_INSTALL_PREFIX=%{_prefix} \
... ...
@@ -61,6 +63,8 @@ make %{?_smp_mflags} test
61 61
 %{_mandir}/man3/*
62 62
 
63 63
 %changelog
64
+*   Thu Feb 14 2019 Keerthana K <keerthanak@vmware.com> 0.6.26-4
65
+-   Fix for CVE-2018-20532, CVE-2018-20533, CVE-2018-20534.
64 66
 *   Fri Apr 21 2017 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 0.6.26-3
65 67
 -   update libdb make config
66 68
 *   Fri Apr 14 2017 Alexey Makhalov <amakhalov@vmware.com> 0.6.26-2