|
|
a37e1c |
diff --git a/keepalived/core/pidfile.c b/keepalived/core/pidfile.c
|
|
|
a37e1c |
index f3f3a2c8..6cfbfe8d 100644
|
|
|
a37e1c |
--- a/keepalived/core/pidfile.c
|
|
|
a37e1c |
+++ b/keepalived/core/pidfile.c
|
|
|
a37e1c |
@@ -54,7 +54,7 @@ int
|
|
|
a37e1c |
pidfile_write(const char *pid_file, int pid)
|
|
|
a37e1c |
{
|
|
|
a37e1c |
FILE *pidfile = NULL;
|
|
|
a37e1c |
- int pidfd = creat(pid_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
|
a37e1c |
+ int pidfd = open(pid_file, O_NOFOLLOW | O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
|
a37e1c |
if (pidfd != -1) pidfile = fdopen(pidfd, "w");
|
|
|
a37e1c |
|
|
|
a37e1c |
if (!pidfile) {
|
|
|
a37e1c |
diff --git a/keepalived/vrrp/vrrp_dbus.c b/keepalived/vrrp/vrrp_dbus.c
|
|
|
a37e1c |
index f29a974f..1320a6c2 100644
|
|
|
a37e1c |
--- a/keepalived/vrrp/vrrp_dbus.c
|
|
|
a37e1c |
+++ b/keepalived/vrrp/vrrp_dbus.c
|
|
|
a37e1c |
@@ -551,7 +551,7 @@ read_file(gchar* filepath)
|
|
|
a37e1c |
size_t length;
|
|
|
a37e1c |
gchar *ret = NULL;
|
|
|
a37e1c |
|
|
|
a37e1c |
- f = fopen(filepath, "rb");
|
|
|
a37e1c |
+ f = fopen(filepath, "r");
|
|
|
a37e1c |
if (f) {
|
|
|
a37e1c |
fseek(f, 0, SEEK_END);
|
|
|
a37e1c |
length = (size_t)ftell(f);
|
|
|
a37e1c |
diff --git a/keepalived/vrrp/vrrp_print.c b/keepalived/vrrp/vrrp_print.c
|
|
|
a37e1c |
index 7adb701d..03840adf 100644
|
|
|
a37e1c |
--- a/keepalived/vrrp/vrrp_print.c
|
|
|
a37e1c |
+++ b/keepalived/vrrp/vrrp_print.c
|
|
|
a37e1c |
@@ -27,6 +27,7 @@
|
|
|
a37e1c |
#include "vrrp.h"
|
|
|
a37e1c |
#include "vrrp_data.h"
|
|
|
a37e1c |
#include "vrrp_print.h"
|
|
|
a37e1c |
+#include "utils.h"
|
|
|
a37e1c |
#ifdef _HAVE_FIB_ROUTING_
|
|
|
a37e1c |
#include "vrrp_iproute.h"
|
|
|
a37e1c |
#include "vrrp_iprule.h"
|
|
|
a37e1c |
@@ -350,7 +351,7 @@ void
|
|
|
a37e1c |
vrrp_print_data(void)
|
|
|
a37e1c |
{
|
|
|
a37e1c |
FILE *file;
|
|
|
a37e1c |
- file = fopen ("/tmp/keepalived.data","w");
|
|
|
a37e1c |
+ file = fopen_safe("/tmp/keepalived.data","w");
|
|
|
a37e1c |
|
|
|
a37e1c |
if (!file) {
|
|
|
a37e1c |
log_message(LOG_INFO, "Can't open /tmp/keepalived.data (%d: %s)",
|
|
|
a37e1c |
@@ -374,7 +375,7 @@ void
|
|
|
a37e1c |
vrrp_print_stats(void)
|
|
|
a37e1c |
{
|
|
|
a37e1c |
FILE *file;
|
|
|
a37e1c |
- file = fopen ("/tmp/keepalived.stats","w");
|
|
|
a37e1c |
+ file = fopen_safe("/tmp/keepalived.stats","w");
|
|
|
a37e1c |
|
|
|
a37e1c |
if (!file) {
|
|
|
a37e1c |
log_message(LOG_INFO, "Can't open /tmp/keepalived.stats (%d: %s)",
|
|
|
a37e1c |
@@ -393,8 +394,7 @@ vrrp_print_stats(void)
|
|
|
a37e1c |
fprintf(file, " Received: %" PRIu64 "\n", vrrp->stats->advert_rcvd);
|
|
|
a37e1c |
fprintf(file, " Sent: %d\n", vrrp->stats->advert_sent);
|
|
|
a37e1c |
fprintf(file, " Became master: %d\n", vrrp->stats->become_master);
|
|
|
a37e1c |
- fprintf(file, " Released master: %d\n",
|
|
|
a37e1c |
- vrrp->stats->release_master);
|
|
|
a37e1c |
+ fprintf(file, " Released master: %d\n", vrrp->stats->release_master);
|
|
|
a37e1c |
fprintf(file, " Packet Errors:\n");
|
|
|
a37e1c |
fprintf(file, " Length: %" PRIu64 "\n", vrrp->stats->packet_len_err);
|
|
|
a37e1c |
fprintf(file, " TTL: %" PRIu64 "\n", vrrp->stats->ip_ttl_err);
|
|
|
a37e1c |
diff --git a/lib/memory.c b/lib/memory.c
|
|
|
a37e1c |
index 96a4e7b9..04b3d6ee 100644
|
|
|
a37e1c |
--- a/lib/memory.c
|
|
|
a37e1c |
+++ b/lib/memory.c
|
|
|
a37e1c |
@@ -441,7 +441,7 @@ mem_log_init(const char* prog_name, const char *banner)
|
|
|
a37e1c |
}
|
|
|
a37e1c |
|
|
|
a37e1c |
snprintf(log_name, log_name_len, "/tmp/%s_mem.%d.log", prog_name, getpid());
|
|
|
a37e1c |
- log_op = fopen(log_name, "a");
|
|
|
a37e1c |
+ log_op = fopen_safe(log_name, "a");
|
|
|
a37e1c |
if (log_op == NULL) {
|
|
|
a37e1c |
log_message(LOG_INFO, "Unable to open %s for appending", log_name);
|
|
|
a37e1c |
log_op = stderr;
|
|
|
a37e1c |
diff --git a/lib/parser.c b/lib/parser.c
|
|
|
a37e1c |
index 2f7959e8..a5c3465b 100644
|
|
|
a37e1c |
--- a/lib/parser.c
|
|
|
a37e1c |
+++ b/lib/parser.c
|
|
|
a37e1c |
@@ -153,12 +153,12 @@ dump_keywords(vector_t *keydump, int level, FILE *fp)
|
|
|
a37e1c |
{
|
|
|
a37e1c |
unsigned int i;
|
|
|
a37e1c |
keyword_t *keyword_vec;
|
|
|
a37e1c |
- char file_name[21];
|
|
|
a37e1c |
+ char file_name[22];
|
|
|
a37e1c |
|
|
|
a37e1c |
if (!level) {
|
|
|
a37e1c |
sprintf(file_name, "/tmp/keywords.%d", getpid());
|
|
|
a37e1c |
snprintf(file_name, sizeof(file_name), "/tmp/keywords.%d", getpid());
|
|
|
a37e1c |
- fp = fopen(file_name, "w");
|
|
|
a37e1c |
+ fp = fopen_safe(file_name, "w");
|
|
|
a37e1c |
if (!fp)
|
|
|
a37e1c |
return;
|
|
|
a37e1c |
}
|
|
|
a37e1c |
diff --git a/lib/utils.c b/lib/utils.c
|
|
|
a37e1c |
index 88465609..f317937e 100644
|
|
|
a37e1c |
--- a/lib/utils.c
|
|
|
a37e1c |
+++ b/lib/utils.c
|
|
|
a37e1c |
@@ -89,7 +89,7 @@ dump_buffer(char *buff, size_t count, FILE* fp)
|
|
|
a37e1c |
void
|
|
|
a37e1c |
write_stacktrace(const char *file_name)
|
|
|
a37e1c |
{
|
|
|
a37e1c |
- int fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT, 0644);
|
|
|
a37e1c |
+ 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);
|
|
|
a37e1c |
void *buffer[100];
|
|
|
a37e1c |
int nptrs;
|
|
|
a37e1c |
|
|
|
a37e1c |
@@ -518,6 +518,47 @@ string_equal(const char *str1, const char *str2)
|
|
|
a37e1c |
return (*str1 == 0 && *str2 == 0);
|
|
|
a37e1c |
}
|
|
|
a37e1c |
|
|
|
a37e1c |
+/* We need to use O_NOFOLLOW if opening a file for write, so that a non privileged user can't
|
|
|
a37e1c |
+ * create a symbolic link from the path to a system file and cause a system file to be overwritten. */
|
|
|
a37e1c |
+FILE *fopen_safe(const char *path, const char *mode)
|
|
|
a37e1c |
+{
|
|
|
a37e1c |
+ int fd;
|
|
|
a37e1c |
+ FILE *file;
|
|
|
a37e1c |
+ int flags = O_NOFOLLOW | O_CREAT;
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ if (mode[0] == 'r')
|
|
|
a37e1c |
+ return fopen(path, mode);
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ if (mode[0] != 'a' && mode[0] != 'w')
|
|
|
a37e1c |
+ return NULL;
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ if (mode[1] &&
|
|
|
a37e1c |
+ (mode[1] != '+' || mode[2]))
|
|
|
a37e1c |
+ return NULL;
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ if (mode[0] == 'w')
|
|
|
a37e1c |
+ flags |= O_TRUNC;
|
|
|
a37e1c |
+ else
|
|
|
a37e1c |
+ flags |= O_APPEND;
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ if (mode[1])
|
|
|
a37e1c |
+ flags |= O_RDWR;
|
|
|
a37e1c |
+ else
|
|
|
a37e1c |
+ flags |= O_WRONLY;
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ fd = open(path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
|
|
a37e1c |
+ if (fd == -1)
|
|
|
a37e1c |
+ return NULL;
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ file = fdopen (fd, "w");
|
|
|
a37e1c |
+ if (!file) {
|
|
|
a37e1c |
+ close(fd);
|
|
|
a37e1c |
+ return NULL;
|
|
|
a37e1c |
+ }
|
|
|
a37e1c |
+
|
|
|
a37e1c |
+ return file;
|
|
|
a37e1c |
+}
|
|
|
a37e1c |
+
|
|
|
a37e1c |
void
|
|
|
a37e1c |
set_std_fd(int force)
|
|
|
a37e1c |
{
|
|
|
a37e1c |
diff --git a/lib/utils.h b/lib/utils.h
|
|
|
a37e1c |
index ec717125..1e440795 100644
|
|
|
a37e1c |
--- a/lib/utils.h
|
|
|
a37e1c |
+++ b/lib/utils.h
|
|
|
a37e1c |
@@ -70,6 +70,7 @@ extern int inet_inaddrcmp(int, void *, void *);
|
|
|
a37e1c |
extern int inet_sockaddrcmp(struct sockaddr_storage *, struct sockaddr_storage *);
|
|
|
a37e1c |
extern char *get_local_name(void);
|
|
|
a37e1c |
extern int string_equal(const char *, const char *);
|
|
|
a37e1c |
+extern FILE *fopen_safe(const char *, const char *);
|
|
|
a37e1c |
extern void set_std_fd(int);
|
|
|
a37e1c |
#if !defined _HAVE_LIBIPTC_ || defined _LIBIPTC_DYNAMIC_
|
|
|
a37e1c |
extern int fork_exec(char **argv);
|