Browse code

Fix systemd CVE-2018-15686

Change-Id: Ia7b36a216a4b5ec72fdee396f0c3aefc9557e43d
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6451
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>

suezzelur authored on 2019/01/05 10:15:54
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,254 @@
0
+diff -rup systemd-228/src/basic/def.h systemd-228-1/src/basic/def.h
1
+--- systemd-228/src/basic/def.h	2015-11-17 23:59:06.000000000 -0800
2
+@@ -92,3 +92,5 @@
3
+         "/usr/local/lib/" n "\0" \
4
+         "/usr/lib/" n "\0" \
5
+         _CONF_PATHS_SPLIT_USR(n)
6
++
7
++#define LONG_LINE_MAX (1U*1024U*1024U)
8
+diff -rup systemd-228/src/basic/fileio.c systemd-228-1/src/basic/fileio.c
9
+--- systemd-228/src/basic/fileio.c	2015-11-17 23:59:06.000000000 -0800
10
+@@ -1240,3 +1240,75 @@ int read_timestamp_file(const char *fn,
11
+         *ret = (usec_t) t;
12
+         return 0;
13
+ }
14
++
15
++DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
16
++
17
++int read_line(FILE *f, size_t limit, char **ret) {
18
++        _cleanup_free_ char *buffer = NULL;
19
++        size_t n = 0, allocated = 0, count = 0;
20
++
21
++        assert(f);
22
++
23
++        /* Something like a bounded version of getline().
24
++         *
25
++         * Considers EOF, \n and \0 end of line delimiters, and does not include these delimiters in the string
26
++         * returned.
27
++         *
28
++         * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
29
++         * the number of characters in the returned string). When EOF is hit, 0 is returned.
30
++         *
31
++         * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
32
++         * delimiters. If the limit is hit we fail and return -ENOBUFS.
33
++         *
34
++         * If a line shall be skipped ret may be initialized as NULL. */
35
++
36
++        if (ret) {
37
++                if (!GREEDY_REALLOC(buffer, allocated, 1))
38
++                        return -ENOMEM;
39
++        }
40
++
41
++        {
42
++                _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
43
++                flockfile(f);
44
++
45
++                for (;;) {
46
++                        int c;
47
++
48
++                        if (n >= limit)
49
++                                return -ENOBUFS;
50
++
51
++                        errno = 0;
52
++                        c = fgetc_unlocked(f);
53
++                        if (c == EOF) {
54
++                                /* if we read an error, and have no data to return, then propagate the error */
55
++                                if (ferror_unlocked(f) && n == 0)
56
++                                        return errno > 0 ? -errno : -EIO;
57
++
58
++                                break;
59
++                        }
60
++
61
++                        count++;
62
++
63
++                        if (IN_SET(c, '\n', 0)) /* Reached a delimiter */
64
++                                break;
65
++
66
++                        if (ret) {
67
++                                if (!GREEDY_REALLOC(buffer, allocated, n + 2))
68
++                                        return -ENOMEM;
69
++
70
++                                buffer[n] = (char) c;
71
++                        }
72
++
73
++                        n++;
74
++                }
75
++        }
76
++
77
++        if (ret) {
78
++                buffer[n] = 0;
79
++
80
++                *ret = buffer;
81
++                buffer = NULL;
82
++        }
83
++
84
++        return (int) count;
85
++}
86
+diff -rup systemd-228/src/basic/fileio.h systemd-228-1/src/basic/fileio.h
87
+--- systemd-228/src/basic/fileio.h	2015-11-17 23:59:06.000000000 -0800
88
+@@ -41,6 +41,7 @@ int write_string_stream(FILE *f, const c
89
+ int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags);
90
+ 
91
+ int read_one_line_file(const char *fn, char **line);
92
++int read_line(FILE *f, size_t limit, char **ret);
93
+ int read_full_file(const char *fn, char **contents, size_t *size);
94
+ int read_full_stream(FILE *f, char **contents, size_t *size);
95
+ 
96
+diff -rup systemd-228/src/core/job.c systemd-228-1/src/core/job.c
97
+--- systemd-228/src/core/job.c	2015-11-17 23:59:06.000000000 -0800
98
+@@ -29,6 +29,7 @@
99
+ #include "dbus-job.h"
100
+ #include "dbus.h"
101
+ #include "escape.h"
102
++#include "fileio.h"
103
+ #include "job.h"
104
+ #include "log.h"
105
+ #include "macro.h"
106
+@@ -1000,23 +1001,25 @@ int job_serialize(Job *j, FILE *f, FDSet
107
+ }
108
+ 
109
+ int job_deserialize(Job *j, FILE *f, FDSet *fds) {
110
++        int r;
111
++
112
+         assert(j);
113
+ 
114
+         for (;;) {
115
+-                char line[LINE_MAX], *l, *v;
116
++                _cleanup_free_ char *line = NULL;
117
++                char *l, *v;
118
+                 size_t k;
119
+ 
120
+-                if (!fgets(line, sizeof(line), f)) {
121
+-                        if (feof(f))
122
+-                                return 0;
123
+-                        return -errno;
124
+-                }
125
++                r = read_line(f, LONG_LINE_MAX, &line);
126
++                if (r < 0)
127
++                        return log_error_errno(r, "Failed to read serialization line: %m");
128
++                if (r == 0)
129
++                        return 0;
130
+ 
131
+-                char_array_0(line);
132
+                 l = strstrip(line);
133
+ 
134
+                 /* End marker */
135
+-                if (l[0] == 0)
136
++                if (isempty(l))
137
+                         return 0;
138
+ 
139
+                 k = strcspn(l, "=");
140
+diff -rup systemd-228/src/core/manager.c systemd-228-1/src/core/manager.c
141
+--- systemd-228/src/core/manager.c	2015-11-17 23:59:06.000000000 -0800
142
+@@ -2335,21 +2335,19 @@ int manager_deserialize(Manager *m, FILE
143
+         m->n_reloading ++;
144
+ 
145
+         for (;;) {
146
+-                char line[LINE_MAX], *l;
147
+-
148
+-                if (!fgets(line, sizeof(line), f)) {
149
+-                        if (feof(f))
150
+-                                r = 0;
151
+-                        else
152
+-                                r = -errno;
153
++                _cleanup_free_ char *line = NULL;
154
++                 const char *l;
155
+ 
156
++                r = read_line(f, LONG_LINE_MAX, &line);
157
++                if (r < 0) {
158
++                        r = log_error_errno(r, "Failed to read serialization line: %m");
159
+                         goto finish;
160
+                 }
161
++                if (r == 0)
162
++                        break;
163
+ 
164
+-                char_array_0(line);
165
+                 l = strstrip(line);
166
+-
167
+-                if (l[0] == 0)
168
++                if (isempty(l)) /* end marker */
169
+                         break;
170
+ 
171
+                 if (startswith(l, "current-job-id=")) {
172
+@@ -2471,20 +2469,17 @@ int manager_deserialize(Manager *m, FILE
173
+         }
174
+ 
175
+         for (;;) {
176
++                _cleanup_free_ char *name = NULL;
177
+                 Unit *u;
178
+-                char name[UNIT_NAME_MAX+2];
179
+ 
180
+                 /* Start marker */
181
+-                if (!fgets(name, sizeof(name), f)) {
182
+-                        if (feof(f))
183
+-                                r = 0;
184
+-                        else
185
+-                                r = -errno;
186
+-
187
++                r = read_line(f, LONG_LINE_MAX, &name);
188
++                if (r < 0) {
189
++                        r = log_error_errno(r, "Failed to read serialization line: %m");
190
+                         goto finish;
191
+                 }
192
+-
193
+-                char_array_0(name);
194
++                if (r == 0)
195
++                        break;
196
+ 
197
+                 r = manager_load_unit(m, strstrip(name), NULL, NULL, &u);
198
+                 if (r < 0)
199
+@@ -2496,9 +2491,6 @@ int manager_deserialize(Manager *m, FILE
200
+         }
201
+ 
202
+ finish:
203
+-        if (ferror(f))
204
+-                r = -EIO;
205
+-
206
+         assert(m->n_reloading > 0);
207
+         m->n_reloading --;
208
+ 
209
+diff -rup systemd-228/src/core/unit.c systemd-228-1/src/core/unit.c
210
+--- systemd-228/src/core/unit.c	2015-11-17 23:59:06.000000000 -0800
211
+@@ -2678,20 +2678,19 @@ int unit_deserialize(Unit *u, FILE *f, F
212
+                 rt = (ExecRuntime**) ((uint8_t*) u + offset);
213
+ 
214
+         for (;;) {
215
+-                char line[LINE_MAX], *l, *v;
216
++                _cleanup_free_ char *line = NULL;
217
++                char *l, *v;
218
+                 size_t k;
219
+ 
220
+-                if (!fgets(line, sizeof(line), f)) {
221
+-                        if (feof(f))
222
+-                                return 0;
223
+-                        return -errno;
224
+-                }
225
++                r = read_line(f, LONG_LINE_MAX, &line);
226
++                if (r < 0)
227
++                        return log_error_errno(r, "Failed to read serialization line: %m");
228
++                if (r == 0) /* eof */
229
++                        break;
230
+ 
231
+-                char_array_0(line);
232
+                 l = strstrip(line);
233
+ 
234
+-                /* End marker */
235
+-                if (isempty(l))
236
++                if (isempty(l)) /* End marker */
237
+                         return 0;
238
+ 
239
+                 k = strcspn(l, "=");
240
+@@ -2838,6 +2837,7 @@ int unit_deserialize(Unit *u, FILE *f, F
241
+                                 log_unit_warning(u, "Failed to deserialize unit parameter '%s', ignoring.", l);
242
+                 }
243
+         }
244
++        return 0;
245
+ }
246
+ 
247
+ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep) {
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:          Systemd-228
2 2
 Name:             systemd
3 3
 Version:          228
4
-Release:          48%{?dist}
4
+Release:          49%{?dist}
5 5
 License:          LGPLv2+ and GPLv2+ and MIT
6 6
 URL:              http://www.freedesktop.org/wiki/Software/systemd/
7 7
 Group:            System Environment/Security
... ...
@@ -47,6 +47,7 @@ Patch29:          systemd-228-CVE-2017-15908-dns-pkt-loop-fix.patch
47 47
 Patch30:          systemd-228-CVE-2017-18078.patch
48 48
 Patch31:          systemd-228-CVE-2018-1049.patch
49 49
 Patch32:          systemd-228-CVE-2018-15688.patch 
50
+Patch33:          systemd-228-CVE-2018-15686.patch 
50 51
 Requires:         Linux-PAM
51 52
 Requires:         libcap
52 53
 Requires:         xz
... ...
@@ -113,6 +114,7 @@ sed -i "s:blkid/::" $(grep -rl "blkid/blkid.h")
113 113
 %patch30 -p1
114 114
 %patch31 -p1
115 115
 %patch32 -p1
116
+%patch33 -p1
116 117
 sed -i "s#\#DefaultTasksMax=512#DefaultTasksMax=infinity#g" src/core/system.conf
117 118
 
118 119
 %build
... ...
@@ -253,6 +255,8 @@ rm -rf %{buildroot}/*
253 253
 
254 254
 
255 255
 %changelog
256
+*    Fri Jan 04 2019 Anish Swaminathan <anishs@vmware.com> 228-49
257
+-    Fix CVE-2018-15686
256 258
 *    Fri Nov 02 2018 Tapas Kundu <tkundu@vmware.com> 228-48
257 259
 -    Fix CVE-2018-15688
258 260
 *    Mon Jul 23 2018 Ankit Jain <ankitja@vmware.com>  228-47