diff --git a/SOURCES/bz1654301-fix-improper-pathname-validation.patch b/SOURCES/bz1654301-fix-improper-pathname-validation.patch new file mode 100644 index 0000000..e0552fb --- /dev/null +++ b/SOURCES/bz1654301-fix-improper-pathname-validation.patch @@ -0,0 +1,171 @@ +diff --git a/keepalived/core/pidfile.c b/keepalived/core/pidfile.c +index f3f3a2c8..6cfbfe8d 100644 +--- a/keepalived/core/pidfile.c ++++ b/keepalived/core/pidfile.c +@@ -54,7 +54,7 @@ int + 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 --git a/keepalived/vrrp/vrrp_dbus.c b/keepalived/vrrp/vrrp_dbus.c +index f29a974f..1320a6c2 100644 +--- a/keepalived/vrrp/vrrp_dbus.c ++++ b/keepalived/vrrp/vrrp_dbus.c +@@ -551,7 +551,7 @@ read_file(gchar* filepath) + 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 --git a/keepalived/vrrp/vrrp_print.c b/keepalived/vrrp/vrrp_print.c +index 7adb701d..03840adf 100644 +--- a/keepalived/vrrp/vrrp_print.c ++++ b/keepalived/vrrp/vrrp_print.c +@@ -27,6 +27,7 @@ + #include "vrrp.h" + #include "vrrp_data.h" + #include "vrrp_print.h" ++#include "utils.h" + #ifdef _HAVE_FIB_ROUTING_ + #include "vrrp_iproute.h" + #include "vrrp_iprule.h" +@@ -350,7 +351,7 @@ void + 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,7 @@ void + vrrp_print_stats(void) + { + FILE *file; +- file = fopen ("/tmp/keepalived.stats","w"); ++ file = fopen_safe("/tmp/keepalived.stats","w"); + + if (!file) { + log_message(LOG_INFO, "Can't open /tmp/keepalived.stats (%d: %s)", +@@ -393,8 +394,7 @@ vrrp_print_stats(void) + 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 --git a/lib/memory.c b/lib/memory.c +index 96a4e7b9..04b3d6ee 100644 +--- a/lib/memory.c ++++ b/lib/memory.c +@@ -441,7 +441,7 @@ mem_log_init(const char* prog_name, const char *banner) + } + + 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 --git a/lib/parser.c b/lib/parser.c +index 2f7959e8..a5c3465b 100644 +--- a/lib/parser.c ++++ b/lib/parser.c +@@ -153,12 +153,12 @@ dump_keywords(vector_t *keydump, int level, FILE *fp) + { + 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 --git a/lib/utils.c b/lib/utils.c +index 88465609..f317937e 100644 +--- a/lib/utils.c ++++ b/lib/utils.c +@@ -89,7 +89,7 @@ dump_buffer(char *buff, size_t count, FILE* fp) + 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 @@ string_equal(const char *str1, const char *str2) + 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 --git a/lib/utils.h b/lib/utils.h +index ec717125..1e440795 100644 +--- a/lib/utils.h ++++ b/lib/utils.h +@@ -70,6 +70,7 @@ extern int inet_inaddrcmp(int, void *, void *); + 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); diff --git a/SOURCES/bz1667292-fix-vrrp_script-misc_script.patch b/SOURCES/bz1667292-fix-vrrp_script-misc_script.patch new file mode 100644 index 0000000..355d3cd --- /dev/null +++ b/SOURCES/bz1667292-fix-vrrp_script-misc_script.patch @@ -0,0 +1,54 @@ +From 83d10ba08b8cd550196ae14f4f40fdbb72078057 Mon Sep 17 00:00:00 2001 +From: Quentin Armitage +Date: Thu, 22 Mar 2018 16:54:54 +0000 +Subject: [PATCH] Fix vrrp_script and check_misc scripts of type + +--- + keepalived/check/check_misc.c | 8 ++++++++ + keepalived/vrrp/vrrp.c | 7 +++++++ + 2 files changed, 15 insertions(+) + +diff --git a/keepalived/check/check_misc.c b/keepalived/check/check_misc.c +index ccb9b63b..7d7e740b 100644 +--- a/keepalived/check/check_misc.c ++++ b/keepalived/check/check_misc.c +@@ -149,6 +149,14 @@ check_misc_script_security(void) + continue; + + misc_script = CHECKER_ARG(checker); ++ ++ /* If the misc check script starts "path[0] == '<' && ++ misc_script->path[strspn(misc_script->path + 1, " \t") + 1] == '/') ++ return 0; ++ + script.name = misc_script->path; + script.uid = misc_script->uid; + script.gid = misc_script->gid; +diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c +index 3d2bfe41..c18a8d17 100644 +--- a/keepalived/vrrp/vrrp.c ++++ b/keepalived/vrrp/vrrp.c +@@ -149,6 +149,13 @@ check_track_script_secure(tracked_sc_t *script) + if (script->scr->insecure) + return 0; + ++ /* If the track script starts "scr->script[0] == '<' && ++ script->scr->script[strspn(script->scr->script + 1, " \t") + 1] == '/') ++ return 0; ++ + ns.name = script->scr->script; + ns.uid = script->scr->uid; + ns.gid = script->scr->gid; +-- +2.21.0 + diff --git a/SPECS/keepalived.spec b/SPECS/keepalived.spec index aa55882..d997f0a 100644 --- a/SPECS/keepalived.spec +++ b/SPECS/keepalived.spec @@ -9,7 +9,7 @@ Name: keepalived Summary: Load balancer and high availability service Version: 1.3.5 -Release: 8%{?dist}.5 +Release: 16%{?dist} License: GPLv2+ URL: http://www.keepalived.org/ Group: System Environment/Daemons @@ -25,6 +25,8 @@ Patch4: bz1508435-no-segfault-ip_vs-load.patch Patch5: bz1508435-remove-ipset-handling.patch Patch6: bz1477587-exclude-mismatch-vips.patch Patch7: bz1652694-fix-buffer-overflow-http-status.patch +patch8: bz1654301-fix-improper-pathname-validation.patch +patch9: bz1667292-fix-vrrp_script-misc_script.patch patch10: bz1678480-add-child_wait_time.patch patch11: bz1678480-migrate-failed-checkers-reload.patch patch12: bz1678480-implment-checker-comparison.patch @@ -74,6 +76,8 @@ Keepalived also implements the Virtual Router Redundancy Protocol %patch5 -p1 %patch6 -p1 %patch7 -p1 +%patch8 -p1 +%patch9 -p1 %patch10 -p1 %patch11 -p1 %patch12 -p1 @@ -141,20 +145,29 @@ Keepalived also implements the Virtual Router Redundancy Protocol %{_mandir}/man8/keepalived.8* %changelog -* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-8.5 -- Rework previous checker comparison patch (#1716588) +* Fri Jun 14 2019 Ryan O'Hara - 1.3.5-16 +- Rework previous misc_script/vrrp_script patch (#1667292) -* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-8.4 -- Make checker variables non global (#1716588) +* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-15 +- Rework previous checker comparison patch (#1715308) -* Mon Jun 03 2019 Ryan O'Hara - 1.3.5-8.3 -- Fix comparison of checkers on reload (#1716588) +* Fri May 31 2019 Ryan O'Hara - 1.3.5-14 +- Make checker variables non global (#1715308) -* Wed Apr 03 2019 Ryan O'Hara - 1.3.5-8.2 +* Fri May 31 2019 Ryan O'Hara - 1.3.5-13 +- Fix comparison of checkers on reload (#1715308) + +* Wed Apr 03 2019 Ryan O'Hara - 1.3.5-12 - Fix build errors (#1678480) -* Tue Apr 02 2019 Ryan O'Hara - 1.3.5-8.1 -- Fix problems with health checks & real servers after reload/restart (#1695653) +* Tue Apr 02 2019 Ryan O'Hara - 1.3.5-11 +- Fix problems with health checks & real servers after reload/restart (#1678480) + +* Fri Jan 25 2019 Ryan O'Hara - 1.3.5-10 +- Fix vrrp_script and check_misc scripts of type " - 1.3.5-9 +- Fix improper pathname validation (#1654301) * Thu Dec 13 2018 Ryan O'Hara - 1.3.5-8 - Fixed patch that was incorrectly removed (#1652694)