diff options
| -rw-r--r-- | meta-networking/recipes-support/chrony/chrony/CVE-2020-14367.patch | 204 | ||||
| -rw-r--r-- | meta-networking/recipes-support/chrony/chrony_3.5.bb | 1 |
2 files changed, 205 insertions, 0 deletions
diff --git a/meta-networking/recipes-support/chrony/chrony/CVE-2020-14367.patch b/meta-networking/recipes-support/chrony/chrony/CVE-2020-14367.patch new file mode 100644 index 0000000000..79df1007e0 --- /dev/null +++ b/meta-networking/recipes-support/chrony/chrony/CVE-2020-14367.patch | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | From f00fed20092b6a42283f29c6ee1f58244d74b545 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Miroslav Lichvar <mlichvar@redhat.com> | ||
| 3 | Date: Thu, 6 Aug 2020 09:31:11 +0200 | ||
| 4 | Subject: main: create new file when writing pidfile | ||
| 5 | |||
| 6 | When writing the pidfile, open the file with the O_CREAT|O_EXCL flags | ||
| 7 | to avoid following a symlink and writing the PID to an unexpected file, | ||
| 8 | when chronyd still has the root privileges. | ||
| 9 | |||
| 10 | The Linux open(2) man page warns about O_EXCL not working as expected on | ||
| 11 | NFS versions before 3 and Linux versions before 2.6. Saving pidfiles on | ||
| 12 | a distributed filesystem like NFS is not generally expected, but if | ||
| 13 | there is a reason to do that, these old kernel and NFS versions are not | ||
| 14 | considered to be supported for saving files by chronyd. | ||
| 15 | |||
| 16 | This is a minimal backport specific to this issue of the following | ||
| 17 | commits: | ||
| 18 | - commit 2fc8edacb810 ("use PATH_MAX") | ||
| 19 | - commit f4c6a00b2a11 ("logging: call exit() in LOG_Message()") | ||
| 20 | - commit 7a4c396bba8f ("util: add functions for common file operations") | ||
| 21 | - commit e18903a6b563 ("switch to new util file functions") | ||
| 22 | |||
| 23 | Reported-by: Matthias Gerstner <mgerstner@suse.de> | ||
| 24 | |||
| 25 | Upstream-Status: Backport [https://git.tuxfamily.org/chrony/chrony.git/commit/?id=f00fed20092b6a42283f29c6ee1f58244d74b545] | ||
| 26 | CVE: CVE-2020-14367 | ||
| 27 | Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com> | ||
| 28 | |||
| 29 | diff --git a/logging.c b/logging.c | ||
| 30 | index d2296e0..fd7f900 100644 | ||
| 31 | --- a/logging.c | ||
| 32 | +++ b/logging.c | ||
| 33 | @@ -171,6 +171,7 @@ void LOG_Message(LOG_Severity severity, | ||
| 34 | system_log = 0; | ||
| 35 | log_message(1, severity, buf); | ||
| 36 | } | ||
| 37 | + exit(1); | ||
| 38 | break; | ||
| 39 | default: | ||
| 40 | assert(0); | ||
| 41 | diff --git a/main.c b/main.c | ||
| 42 | index 6ccf32e..8edb2e1 100644 | ||
| 43 | --- a/main.c | ||
| 44 | +++ b/main.c | ||
| 45 | @@ -281,13 +281,9 @@ write_pidfile(void) | ||
| 46 | if (!pidfile[0]) | ||
| 47 | return; | ||
| 48 | |||
| 49 | - out = fopen(pidfile, "w"); | ||
| 50 | - if (!out) { | ||
| 51 | - LOG_FATAL("Could not open %s : %s", pidfile, strerror(errno)); | ||
| 52 | - } else { | ||
| 53 | - fprintf(out, "%d\n", (int)getpid()); | ||
| 54 | - fclose(out); | ||
| 55 | - } | ||
| 56 | + out = UTI_OpenFile(NULL, pidfile, NULL, 'W', 0644); | ||
| 57 | + fprintf(out, "%d\n", (int)getpid()); | ||
| 58 | + fclose(out); | ||
| 59 | } | ||
| 60 | |||
| 61 | /* ================================================== */ | ||
| 62 | diff --git a/sysincl.h b/sysincl.h | ||
| 63 | index 296c5e6..873a3bd 100644 | ||
| 64 | --- a/sysincl.h | ||
| 65 | +++ b/sysincl.h | ||
| 66 | @@ -37,6 +37,7 @@ | ||
| 67 | #include <glob.h> | ||
| 68 | #include <grp.h> | ||
| 69 | #include <inttypes.h> | ||
| 70 | +#include <limits.h> | ||
| 71 | #include <math.h> | ||
| 72 | #include <netinet/in.h> | ||
| 73 | #include <pwd.h> | ||
| 74 | diff --git a/util.c b/util.c | ||
| 75 | index e7e3442..83b3b20 100644 | ||
| 76 | --- a/util.c | ||
| 77 | +++ b/util.c | ||
| 78 | @@ -1179,6 +1179,101 @@ UTI_CheckDirPermissions(const char *path, mode_t perm, uid_t uid, gid_t gid) | ||
| 79 | |||
| 80 | /* ================================================== */ | ||
| 81 | |||
| 82 | +static int | ||
| 83 | +join_path(const char *basedir, const char *name, const char *suffix, | ||
| 84 | + char *buffer, size_t length, LOG_Severity severity) | ||
| 85 | +{ | ||
| 86 | + const char *sep; | ||
| 87 | + | ||
| 88 | + if (!basedir) { | ||
| 89 | + basedir = ""; | ||
| 90 | + sep = ""; | ||
| 91 | + } else { | ||
| 92 | + sep = "/"; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + if (!suffix) | ||
| 96 | + suffix = ""; | ||
| 97 | + | ||
| 98 | + if (snprintf(buffer, length, "%s%s%s%s", basedir, sep, name, suffix) >= length) { | ||
| 99 | + LOG(severity, "File path %s%s%s%s too long", basedir, sep, name, suffix); | ||
| 100 | + return 0; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + return 1; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +/* ================================================== */ | ||
| 107 | + | ||
| 108 | +FILE * | ||
| 109 | +UTI_OpenFile(const char *basedir, const char *name, const char *suffix, | ||
| 110 | + char mode, mode_t perm) | ||
| 111 | +{ | ||
| 112 | + const char *file_mode; | ||
| 113 | + char path[PATH_MAX]; | ||
| 114 | + LOG_Severity severity; | ||
| 115 | + int fd, flags; | ||
| 116 | + FILE *file; | ||
| 117 | + | ||
| 118 | + severity = mode >= 'A' && mode <= 'Z' ? LOGS_FATAL : LOGS_ERR; | ||
| 119 | + | ||
| 120 | + if (!join_path(basedir, name, suffix, path, sizeof (path), severity)) | ||
| 121 | + return NULL; | ||
| 122 | + | ||
| 123 | + switch (mode) { | ||
| 124 | + case 'r': | ||
| 125 | + case 'R': | ||
| 126 | + flags = O_RDONLY; | ||
| 127 | + file_mode = "r"; | ||
| 128 | + if (severity != LOGS_FATAL) | ||
| 129 | + severity = LOGS_DEBUG; | ||
| 130 | + break; | ||
| 131 | + case 'w': | ||
| 132 | + case 'W': | ||
| 133 | + flags = O_WRONLY | O_CREAT | O_EXCL; | ||
| 134 | + file_mode = "w"; | ||
| 135 | + break; | ||
| 136 | + case 'a': | ||
| 137 | + case 'A': | ||
| 138 | + flags = O_WRONLY | O_CREAT | O_APPEND; | ||
| 139 | + file_mode = "a"; | ||
| 140 | + break; | ||
| 141 | + default: | ||
| 142 | + assert(0); | ||
| 143 | + return NULL; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | +try_again: | ||
| 147 | + fd = open(path, flags, perm); | ||
| 148 | + if (fd < 0) { | ||
| 149 | + if (errno == EEXIST) { | ||
| 150 | + if (unlink(path) < 0) { | ||
| 151 | + LOG(severity, "Could not remove %s : %s", path, strerror(errno)); | ||
| 152 | + return NULL; | ||
| 153 | + } | ||
| 154 | + DEBUG_LOG("Removed %s", path); | ||
| 155 | + goto try_again; | ||
| 156 | + } | ||
| 157 | + LOG(severity, "Could not open %s : %s", path, strerror(errno)); | ||
| 158 | + return NULL; | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + UTI_FdSetCloexec(fd); | ||
| 162 | + | ||
| 163 | + file = fdopen(fd, file_mode); | ||
| 164 | + if (!file) { | ||
| 165 | + LOG(severity, "Could not open %s : %s", path, strerror(errno)); | ||
| 166 | + close(fd); | ||
| 167 | + return NULL; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + DEBUG_LOG("Opened %s fd=%d mode=%c", path, fd, mode); | ||
| 171 | + | ||
| 172 | + return file; | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +/* ================================================== */ | ||
| 176 | + | ||
| 177 | void | ||
| 178 | UTI_DropRoot(uid_t uid, gid_t gid) | ||
| 179 | { | ||
| 180 | diff --git a/util.h b/util.h | ||
| 181 | index e3d6767..a2481cc 100644 | ||
| 182 | --- a/util.h | ||
| 183 | +++ b/util.h | ||
| 184 | @@ -176,6 +176,17 @@ extern int UTI_CreateDirAndParents(const char *path, mode_t mode, uid_t uid, gid | ||
| 185 | permissions and its uid/gid must match the specified values. */ | ||
| 186 | extern int UTI_CheckDirPermissions(const char *path, mode_t perm, uid_t uid, gid_t gid); | ||
| 187 | |||
| 188 | +/* Open a file. The full path of the file is constructed from the basedir | ||
| 189 | + (may be NULL), '/' (if basedir is not NULL), name, and suffix (may be NULL). | ||
| 190 | + Created files have specified permissions (umasked). Returns NULL on error. | ||
| 191 | + The following modes are supported (if the mode is an uppercase character, | ||
| 192 | + errors are fatal): | ||
| 193 | + r/R - open an existing file for reading | ||
| 194 | + w/W - open a new file for writing (remove existing file) | ||
| 195 | + a/A - open an existing file for appending (create if does not exist) */ | ||
| 196 | +extern FILE *UTI_OpenFile(const char *basedir, const char *name, const char *suffix, | ||
| 197 | + char mode, mode_t perm); | ||
| 198 | + | ||
| 199 | /* Set process user/group IDs and drop supplementary groups */ | ||
| 200 | extern void UTI_DropRoot(uid_t uid, gid_t gid); | ||
| 201 | |||
| 202 | -- | ||
| 203 | cgit v0.10.2 | ||
| 204 | |||
diff --git a/meta-networking/recipes-support/chrony/chrony_3.5.bb b/meta-networking/recipes-support/chrony/chrony_3.5.bb index 7c6356d264..182ce13ccf 100644 --- a/meta-networking/recipes-support/chrony/chrony_3.5.bb +++ b/meta-networking/recipes-support/chrony/chrony_3.5.bb | |||
| @@ -34,6 +34,7 @@ SRC_URI = "https://download.tuxfamily.org/chrony/chrony-${PV}.tar.gz \ | |||
| 34 | file://chrony.conf \ | 34 | file://chrony.conf \ |
| 35 | file://chronyd \ | 35 | file://chronyd \ |
| 36 | file://arm_eabi.patch \ | 36 | file://arm_eabi.patch \ |
| 37 | file://CVE-2020-14367.patch \ | ||
| 37 | " | 38 | " |
| 38 | 39 | ||
| 39 | SRC_URI_append_libc-musl = " \ | 40 | SRC_URI_append_libc-musl = " \ |
