Browse code

keepalived: Fix CVE-2018-19044

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

ashwin-h authored on 2019/02/15 04:51:11
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,189 @@
0
+diff -Naur a/keepalived/core/pidfile.c b/keepalived/core/pidfile.c
1
+--- a/keepalived/core/pidfile.c	2019-02-15 01:01:32.886542487 +0530
2
+@@ -54,7 +54,7 @@
3
+ pidfile_write(const char *pid_file, int pid)
4
+ {
5
+ 	FILE *pidfile = NULL;
6
+-	int pidfd = creat(pid_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
7
++        int pidfd = open(pid_file, O_NOFOLLOW | O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
8
+ 	if (pidfd != -1) pidfile = fdopen(pidfd, "w");
9
+ 
10
+ 	if (!pidfile) {
11
+diff -Naur a/keepalived/vrrp/vrrp_dbus.c b/keepalived/vrrp/vrrp_dbus.c
12
+--- a/keepalived/vrrp/vrrp_dbus.c	2019-02-15 01:01:32.886542487 +0530
13
+@@ -551,7 +551,7 @@
14
+ 	size_t length;
15
+ 	gchar *ret = NULL;
16
+ 
17
+-	f = fopen(filepath, "rb");
18
++	f = fopen(filepath, "r");
19
+ 	if (f) {
20
+ 		fseek(f, 0, SEEK_END);
21
+ 		length = (size_t)ftell(f);
22
+diff -Naur a/keepalived/vrrp/vrrp_print.c b/keepalived/vrrp/vrrp_print.c
23
+--- a/keepalived/vrrp/vrrp_print.c	2019-02-15 01:01:32.886542487 +0530
24
+@@ -34,6 +34,7 @@
25
+ #include "keepalived_netlink.h"
26
+ #include "rttables.h"
27
+ #include "logger.h"
28
++#include "utils.h"
29
+ 
30
+ #include <time.h>
31
+ #include <errno.h>
32
+@@ -350,7 +351,7 @@
33
+ vrrp_print_data(void)
34
+ {
35
+ 	FILE *file;
36
+-	file = fopen ("/tmp/keepalived.data","w");
37
++	file = fopen_safe("/tmp/keepalived.data","w");
38
+ 
39
+ 	if (!file) {
40
+ 		log_message(LOG_INFO, "Can't open /tmp/keepalived.data (%d: %s)",
41
+@@ -374,7 +375,9 @@
42
+ vrrp_print_stats(void)
43
+ {
44
+ 	FILE *file;
45
+-	file = fopen ("/tmp/keepalived.stats","w");
46
++	file = fopen_safe("/tmp/keepalived.stats","w");
47
++	element e;
48
++	vrrp_t *vrrp;
49
+ 
50
+ 	if (!file) {
51
+ 		log_message(LOG_INFO, "Can't open /tmp/keepalived.stats (%d: %s)",
52
+@@ -382,19 +385,13 @@
53
+ 		return;
54
+ 	}
55
+ 
56
+-	list l = vrrp_data->vrrp;
57
+-	element e;
58
+-	vrrp_t *vrrp;
59
+-
60
+-	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
61
+-		vrrp = ELEMENT_DATA(e);
62
++	LIST_FOREACH(vrrp_data->vrrp, vrrp, e) {
63
+ 		fprintf(file, "VRRP Instance: %s\n", vrrp->iname);
64
+ 		fprintf(file, "  Advertisements:\n");
65
+ 		fprintf(file, "    Received: %" PRIu64 "\n", vrrp->stats->advert_rcvd);
66
+ 		fprintf(file, "    Sent: %d\n", vrrp->stats->advert_sent);
67
+ 		fprintf(file, "  Became master: %d\n", vrrp->stats->become_master);
68
+-		fprintf(file, "  Released master: %d\n",
69
+-			vrrp->stats->release_master);
70
++                fprintf(file, "  Released master: %d\n", vrrp->stats->release_master);
71
+ 		fprintf(file, "  Packet Errors:\n");
72
+ 		fprintf(file, "    Length: %" PRIu64 "\n", vrrp->stats->packet_len_err);
73
+ 		fprintf(file, "    TTL: %" PRIu64 "\n", vrrp->stats->ip_ttl_err);
74
+diff -Naur a/lib/list.h b/lib/list.h
75
+--- a/lib/list.h	2019-02-15 01:01:55.538543574 +0530
76
+@@ -51,6 +51,7 @@
77
+ #define LIST_ISEMPTY(L)		((L) == NULL || ((L)->head == NULL && (L)->tail == NULL))
78
+ #define LIST_EXISTS(L)		((L) != NULL)
79
+ #define LIST_SIZE(V)		((V)->count)
80
++#define LIST_FOREACH(L,V,E)     for ((E) = ((L) ? LIST_HEAD(L) : NULL); (E) && ((V) = ELEMENT_DATA(E), 1); ELEMENT_NEXT(E))
81
+ 
82
+ /* Prototypes */
83
+ extern list alloc_list(void (*free_func) (void *), void (*dump_func) (void *));
84
+diff -Naur a/lib/memory.c b/lib/memory.c
85
+--- a/lib/memory.c	2019-02-15 01:01:55.538543574 +0530
86
+@@ -441,7 +441,7 @@
87
+ 	}
88
+ 
89
+ 	snprintf(log_name, log_name_len, "/tmp/%s_mem.%d.log", prog_name, getpid());
90
+-	log_op = fopen(log_name, "a");
91
++	log_op = fopen_safe(log_name, "a");
92
+ 	if (log_op == NULL) {
93
+ 		log_message(LOG_INFO, "Unable to open %s for appending", log_name);
94
+ 		log_op = stderr;
95
+diff -Naur a/lib/parser.c b/lib/parser.c
96
+--- a/lib/parser.c	2019-02-15 01:01:55.538543574 +0530
97
+@@ -153,12 +153,12 @@
98
+ {
99
+ 	unsigned int i;
100
+ 	keyword_t *keyword_vec;
101
+-	char file_name[21];
102
++	char file_name[22];
103
+ 
104
+ 	if (!level) {
105
+ 		sprintf(file_name, "/tmp/keywords.%d", getpid());
106
+ 		snprintf(file_name, sizeof(file_name), "/tmp/keywords.%d", getpid());
107
+-		fp = fopen(file_name, "w");
108
++		fp = fopen_safe(file_name, "w");
109
+ 		if (!fp)
110
+ 			return;
111
+ 	}
112
+diff -Naur a/lib/utils.c b/lib/utils.c
113
+--- a/lib/utils.c	2019-02-15 01:01:55.538543574 +0530
114
+@@ -89,7 +89,7 @@
115
+ void
116
+ write_stacktrace(const char *file_name)
117
+ {
118
+-	int fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT, 0644);
119
++        int fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
120
+ 	void *buffer[100];
121
+ 	int nptrs;
122
+ 
123
+@@ -518,6 +518,47 @@
124
+ 	return (*str1 == 0 && *str2 == 0);
125
+ }
126
+ 
127
++/* We need to use O_NOFOLLOW if opening a file for write, so that a non privileged user can't
128
++ * create a symbolic link from the path to a system file and cause a system file to be overwritten. */
129
++FILE *fopen_safe(const char *path, const char *mode)
130
++{
131
++    int fd;
132
++    FILE *file;
133
++    int flags = O_NOFOLLOW | O_CREAT;
134
++
135
++    if (mode[0] == 'r')
136
++        return fopen(path, mode);
137
++
138
++    if (mode[0] != 'a' && mode[0] != 'w')
139
++        return NULL;
140
++
141
++    if (mode[1] &&
142
++        (mode[1] != '+' || mode[2]))
143
++        return NULL;
144
++
145
++    if (mode[0] == 'w')
146
++        flags |= O_TRUNC;
147
++    else
148
++        flags |= O_APPEND;
149
++
150
++    if (mode[1])
151
++        flags |= O_RDWR;
152
++    else
153
++        flags |= O_WRONLY;
154
++
155
++    fd = open(path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
156
++    if (fd == -1)
157
++        return NULL;
158
++
159
++    file = fdopen (fd, "w");
160
++    if (!file) {
161
++        close(fd);
162
++        return NULL;
163
++    }
164
++
165
++    return file;
166
++}
167
++
168
+ void
169
+ set_std_fd(int force)
170
+ {
171
+diff -Naur a/lib/utils.h b/lib/utils.h
172
+--- a/lib/utils.h	2019-02-15 01:01:55.538543574 +0530
173
+@@ -70,6 +70,7 @@
174
+ extern int inet_sockaddrcmp(struct sockaddr_storage *, struct sockaddr_storage *);
175
+ extern char *get_local_name(void);
176
+ extern int string_equal(const char *, const char *);
177
++extern FILE *fopen_safe(const char *, const char *);
178
+ extern void set_std_fd(int);
179
+ #if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
180
+ extern int fork_exec(char **argv);
... ...
@@ -1,7 +1,7 @@
1 1
 Summary:    HA monitor built upon LVS, VRRP and services poller 
2 2
 Name:       keepalived
3 3
 Version:    1.3.5
4
-Release:    1%{?dist}
4
+Release:    2%{?dist}
5 5
 License:    GPL
6 6
 URL:        http://www.keepalived.org/
7 7
 Group:      Applications/System
... ...
@@ -10,6 +10,7 @@ Distribution: Photon
10 10
 Source0:     http://www.keepalived.org/software/%{name}-%{version}.tar.gz
11 11
 %define sha1 keepalived=5a373d8f5d382700cf53b827947a92a7f4cef148
12 12
 Source1:     keepalived.service
13
+Patch0:         CVE-2018-19044.patch
13 14
 BuildRequires:    openssl-devel
14 15
 BuildRequires:    iptables
15 16
 BuildRequires:    libmnl-devel
... ...
@@ -34,6 +35,7 @@ healthchecks and LVS directors failover.
34 34
 
35 35
 %prep
36 36
 %setup -q
37
+%patch0 -p1
37 38
 
38 39
 %build
39 40
 ./configure \
... ...
@@ -85,5 +87,7 @@ fi
85 85
 %{_mandir}/man8/keepalived.8*
86 86
 
87 87
 %changelog
88
+*   Thu Feb 14 2019 <ashwinh@vmware.com> 1.3.5-2
89
+-   Fix CVE-2018-19044
88 90
 *   Thu Apr 06 2017 Dheeraj Shetty <dheerajs@vmware.com> 1.3.5-1
89 91
 -   Initial build.  First version