diff -Naur a/keepalived/core/pidfile.c b/keepalived/core/pidfile.c
--- a/keepalived/core/pidfile.c	2019-02-15 01:01:32.886542487 +0530
+++ b/keepalived/core/pidfile.c	2019-02-15 01:01:09.414541360 +0530
@@ -54,7 +54,7 @@
 pidfile_write(const char *pid_file, int pid)
 {
 	FILE *pidfile = NULL;
-	int pidfd = creat(pid_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+        int pidfd = open(pid_file, O_NOFOLLOW | O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 	if (pidfd != -1) pidfile = fdopen(pidfd, "w");
 
 	if (!pidfile) {
diff -Naur a/keepalived/vrrp/vrrp_dbus.c b/keepalived/vrrp/vrrp_dbus.c
--- a/keepalived/vrrp/vrrp_dbus.c	2019-02-15 01:01:32.886542487 +0530
+++ b/keepalived/vrrp/vrrp_dbus.c	2019-02-15 01:04:31.058551041 +0530
@@ -551,7 +551,7 @@
 	size_t length;
 	gchar *ret = NULL;
 
-	f = fopen(filepath, "rb");
+	f = fopen(filepath, "r");
 	if (f) {
 		fseek(f, 0, SEEK_END);
 		length = (size_t)ftell(f);
diff -Naur a/keepalived/vrrp/vrrp_print.c b/keepalived/vrrp/vrrp_print.c
--- a/keepalived/vrrp/vrrp_print.c	2019-02-15 01:01:32.886542487 +0530
+++ b/keepalived/vrrp/vrrp_print.c	2019-02-15 01:01:09.410541360 +0530
@@ -34,6 +34,7 @@
 #include "keepalived_netlink.h"
 #include "rttables.h"
 #include "logger.h"
+#include "utils.h"
 
 #include <time.h>
 #include <errno.h>
@@ -350,7 +351,7 @@
 vrrp_print_data(void)
 {
 	FILE *file;
-	file = fopen ("/tmp/keepalived.data","w");
+	file = fopen_safe("/tmp/keepalived.data","w");
 
 	if (!file) {
 		log_message(LOG_INFO, "Can't open /tmp/keepalived.data (%d: %s)",
@@ -374,7 +375,9 @@
 vrrp_print_stats(void)
 {
 	FILE *file;
-	file = fopen ("/tmp/keepalived.stats","w");
+	file = fopen_safe("/tmp/keepalived.stats","w");
+	element e;
+	vrrp_t *vrrp;
 
 	if (!file) {
 		log_message(LOG_INFO, "Can't open /tmp/keepalived.stats (%d: %s)",
@@ -382,19 +385,13 @@
 		return;
 	}
 
-	list l = vrrp_data->vrrp;
-	element e;
-	vrrp_t *vrrp;
-
-	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
-		vrrp = ELEMENT_DATA(e);
+	LIST_FOREACH(vrrp_data->vrrp, vrrp, e) {
 		fprintf(file, "VRRP Instance: %s\n", vrrp->iname);
 		fprintf(file, "  Advertisements:\n");
 		fprintf(file, "    Received: %" PRIu64 "\n", vrrp->stats->advert_rcvd);
 		fprintf(file, "    Sent: %d\n", vrrp->stats->advert_sent);
 		fprintf(file, "  Became master: %d\n", vrrp->stats->become_master);
-		fprintf(file, "  Released master: %d\n",
-			vrrp->stats->release_master);
+                fprintf(file, "  Released master: %d\n", vrrp->stats->release_master);
 		fprintf(file, "  Packet Errors:\n");
 		fprintf(file, "    Length: %" PRIu64 "\n", vrrp->stats->packet_len_err);
 		fprintf(file, "    TTL: %" PRIu64 "\n", vrrp->stats->ip_ttl_err);
diff -Naur a/lib/list.h b/lib/list.h
--- a/lib/list.h	2019-02-15 01:01:55.538543574 +0530
+++ b/lib/list.h	2019-02-15 01:17:13.926587668 +0530
@@ -51,6 +51,7 @@
 #define LIST_ISEMPTY(L)		((L) == NULL || ((L)->head == NULL && (L)->tail == NULL))
 #define LIST_EXISTS(L)		((L) != NULL)
 #define LIST_SIZE(V)		((V)->count)
+#define LIST_FOREACH(L,V,E)     for ((E) = ((L) ? LIST_HEAD(L) : NULL); (E) && ((V) = ELEMENT_DATA(E), 1); ELEMENT_NEXT(E))
 
 /* Prototypes */
 extern list alloc_list(void (*free_func) (void *), void (*dump_func) (void *));
diff -Naur a/lib/memory.c b/lib/memory.c
--- a/lib/memory.c	2019-02-15 01:01:55.538543574 +0530
+++ b/lib/memory.c	2019-02-15 01:01:20.114541874 +0530
@@ -441,7 +441,7 @@
 	}
 
 	snprintf(log_name, log_name_len, "/tmp/%s_mem.%d.log", prog_name, getpid());
-	log_op = fopen(log_name, "a");
+	log_op = fopen_safe(log_name, "a");
 	if (log_op == NULL) {
 		log_message(LOG_INFO, "Unable to open %s for appending", log_name);
 		log_op = stderr;
diff -Naur a/lib/parser.c b/lib/parser.c
--- a/lib/parser.c	2019-02-15 01:01:55.538543574 +0530
+++ b/lib/parser.c	2019-02-15 01:01:20.114541874 +0530
@@ -153,12 +153,12 @@
 {
 	unsigned int i;
 	keyword_t *keyword_vec;
-	char file_name[21];
+	char file_name[22];
 
 	if (!level) {
 		sprintf(file_name, "/tmp/keywords.%d", getpid());
 		snprintf(file_name, sizeof(file_name), "/tmp/keywords.%d", getpid());
-		fp = fopen(file_name, "w");
+		fp = fopen_safe(file_name, "w");
 		if (!fp)
 			return;
 	}
diff -Naur a/lib/utils.c b/lib/utils.c
--- a/lib/utils.c	2019-02-15 01:01:55.538543574 +0530
+++ b/lib/utils.c	2019-02-15 01:01:20.114541874 +0530
@@ -89,7 +89,7 @@
 void
 write_stacktrace(const char *file_name)
 {
-	int fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT, 0644);
+        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);
 	void *buffer[100];
 	int nptrs;
 
@@ -518,6 +518,47 @@
 	return (*str1 == 0 && *str2 == 0);
 }
 
+/* We need to use O_NOFOLLOW if opening a file for write, so that a non privileged user can't
+ * create a symbolic link from the path to a system file and cause a system file to be overwritten. */
+FILE *fopen_safe(const char *path, const char *mode)
+{
+    int fd;
+    FILE *file;
+    int flags = O_NOFOLLOW | O_CREAT;
+
+    if (mode[0] == 'r')
+        return fopen(path, mode);
+
+    if (mode[0] != 'a' && mode[0] != 'w')
+        return NULL;
+
+    if (mode[1] &&
+        (mode[1] != '+' || mode[2]))
+        return NULL;
+
+    if (mode[0] == 'w')
+        flags |= O_TRUNC;
+    else
+        flags |= O_APPEND;
+
+    if (mode[1])
+        flags |= O_RDWR;
+    else
+        flags |= O_WRONLY;
+
+    fd = open(path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+    if (fd == -1)
+        return NULL;
+
+    file = fdopen (fd, "w");
+    if (!file) {
+        close(fd);
+        return NULL;
+    }
+
+    return file;
+}
+
 void
 set_std_fd(int force)
 {
diff -Naur a/lib/utils.h b/lib/utils.h
--- a/lib/utils.h	2019-02-15 01:01:55.538543574 +0530
+++ b/lib/utils.h	2019-02-15 01:01:20.114541874 +0530
@@ -70,6 +70,7 @@
 extern int inet_sockaddrcmp(struct sockaddr_storage *, struct sockaddr_storage *);
 extern char *get_local_name(void);
 extern int string_equal(const char *, const char *);
+extern FILE *fopen_safe(const char *, const char *);
 extern void set_std_fd(int);
 #if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
 extern int fork_exec(char **argv);