diff options
| author | Peter Marko <peter.marko@siemens.com> | 2023-06-28 22:06:37 +0200 |
|---|---|---|
| committer | Armin Kuster <akuster808@gmail.com> | 2023-07-02 11:19:14 -0400 |
| commit | 3c3755a3da1aa93501664f2893fa110e66ce7b6e (patch) | |
| tree | fc33aa0385a025011fcc596510a11ab310289216 /meta-networking | |
| parent | d434faf6c959f0298e930a12ab3e0968e1b9d04c (diff) | |
| download | meta-openembedded-3c3755a3da1aa93501664f2893fa110e66ce7b6e.tar.gz | |
ntp: backport patch for 5 CVEs CVE-2023-26551/2/3/4/5
Patch taken from https://archive.ntp.org/ntp4/ntp-4.2/ntp-4.2.8p15-3806-3807.patch
It is linked as official patch for p15 in:
- https://www.ntp.org/support/securitynotice/ntpbug3807/
- https://www.ntp.org/support/securitynotice/ntpbug3806/
Small adaptation to build is needed because of how tests are built.
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Diffstat (limited to 'meta-networking')
| -rwxr-xr-x | meta-networking/recipes-support/ntp/ntp/CVE-2023-2655x.patch | 323 | ||||
| -rw-r--r-- | meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb | 9 |
2 files changed, 332 insertions, 0 deletions
diff --git a/meta-networking/recipes-support/ntp/ntp/CVE-2023-2655x.patch b/meta-networking/recipes-support/ntp/ntp/CVE-2023-2655x.patch new file mode 100755 index 0000000000..fbd0ec151a --- /dev/null +++ b/meta-networking/recipes-support/ntp/ntp/CVE-2023-2655x.patch | |||
| @@ -0,0 +1,323 @@ | |||
| 1 | CVE: CVE-2023-26551 | ||
| 2 | CVE: CVE-2023-26552 | ||
| 3 | CVE: CVE-2023-26553 | ||
| 4 | CVE: CVE-2023-26554 | ||
| 5 | CVE: CVE-2023-26555 | ||
| 6 | Upstream-Status: Backport [https://archive.ntp.org/ntp4/ntp-4.2/ntp-4.2.8p15-3806-3807.patch] | ||
| 7 | |||
| 8 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 9 | --- include/ntp_fp.h 2019-06-03 23:41:14.000000000 -0500 | ||
| 10 | +++ ../ntp-stable-p16-sec/include/ntp_fp.h 2023-04-17 03:17:01.655121000 -0500 | ||
| 11 | @@ -195,9 +195,9 @@ | ||
| 12 | do { \ | ||
| 13 | int32 add_f = (int32)(f); \ | ||
| 14 | if (add_f >= 0) \ | ||
| 15 | - M_ADD((r_i), (r_f), 0, (uint32)( add_f)); \ | ||
| 16 | + M_ADD((r_i), (r_f), 0, (u_int32)( add_f)); \ | ||
| 17 | else \ | ||
| 18 | - M_SUB((r_i), (r_f), 0, (uint32)(-add_f)); \ | ||
| 19 | + M_SUB((r_i), (r_f), 0, (u_int32)(-add_f)); \ | ||
| 20 | } while(0) | ||
| 21 | |||
| 22 | #define M_ISNEG(v_i) /* v < 0 */ \ | ||
| 23 | --- libntp/mstolfp.c 2019-06-03 23:41:14.000000000 -0500 | ||
| 24 | +++ ../ntp-stable-p16-sec/libntp/mstolfp.c 2023-04-17 03:07:38.598581000 -0500 | ||
| 25 | @@ -14,86 +14,58 @@ | ||
| 26 | l_fp *lfp | ||
| 27 | ) | ||
| 28 | { | ||
| 29 | - register const char *cp; | ||
| 30 | - register char *bp; | ||
| 31 | - register const char *cpdec; | ||
| 32 | - char buf[100]; | ||
| 33 | + int ch, neg = 0; | ||
| 34 | + u_int32 q, r; | ||
| 35 | |||
| 36 | /* | ||
| 37 | * We understand numbers of the form: | ||
| 38 | * | ||
| 39 | * [spaces][-|+][digits][.][digits][spaces|\n|\0] | ||
| 40 | * | ||
| 41 | - * This is one enormous hack. Since I didn't feel like | ||
| 42 | - * rewriting the decoding routine for milliseconds, what | ||
| 43 | - * is essentially done here is to make a copy of the string | ||
| 44 | - * with the decimal moved over three places so the seconds | ||
| 45 | - * decoding routine can be used. | ||
| 46 | + * This is kinda hack. We use 'atolfp' to do the basic parsing | ||
| 47 | + * (after some initial checks) and then divide the result by | ||
| 48 | + * 1000. The original implementation avoided that by | ||
| 49 | + * hacking up the input string to move the decimal point, but | ||
| 50 | + * that needed string manipulations prone to buffer overruns. | ||
| 51 | + * To avoid that trouble we do the conversion first and adjust | ||
| 52 | + * the result. | ||
| 53 | */ | ||
| 54 | - bp = buf; | ||
| 55 | - cp = str; | ||
| 56 | - while (isspace((unsigned char)*cp)) | ||
| 57 | - cp++; | ||
| 58 | |||
| 59 | - if (*cp == '-' || *cp == '+') { | ||
| 60 | - *bp++ = *cp++; | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - if (*cp != '.' && !isdigit((unsigned char)*cp)) | ||
| 64 | - return 0; | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - /* | ||
| 68 | - * Search forward for the decimal point or the end of the string. | ||
| 69 | - */ | ||
| 70 | - cpdec = cp; | ||
| 71 | - while (isdigit((unsigned char)*cpdec)) | ||
| 72 | - cpdec++; | ||
| 73 | - | ||
| 74 | - /* | ||
| 75 | - * Found something. If we have more than three digits copy the | ||
| 76 | - * excess over, else insert a leading 0. | ||
| 77 | - */ | ||
| 78 | - if ((cpdec - cp) > 3) { | ||
| 79 | - do { | ||
| 80 | - *bp++ = (char)*cp++; | ||
| 81 | - } while ((cpdec - cp) > 3); | ||
| 82 | - } else { | ||
| 83 | - *bp++ = '0'; | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | - /* | ||
| 87 | - * Stick the decimal in. If we've got less than three digits in | ||
| 88 | - * front of the millisecond decimal we insert the appropriate number | ||
| 89 | - * of zeros. | ||
| 90 | - */ | ||
| 91 | - *bp++ = '.'; | ||
| 92 | - if ((cpdec - cp) < 3) { | ||
| 93 | - size_t i = 3 - (cpdec - cp); | ||
| 94 | - do { | ||
| 95 | - *bp++ = '0'; | ||
| 96 | - } while (--i > 0); | ||
| 97 | - } | ||
| 98 | - | ||
| 99 | - /* | ||
| 100 | - * Copy the remainder up to the millisecond decimal. If cpdec | ||
| 101 | - * is pointing at a decimal point, copy in the trailing number too. | ||
| 102 | - */ | ||
| 103 | - while (cp < cpdec) | ||
| 104 | - *bp++ = (char)*cp++; | ||
| 105 | + while (isspace(ch = *(const unsigned char*)str)) | ||
| 106 | + ++str; | ||
| 107 | |||
| 108 | - if (*cp == '.') { | ||
| 109 | - cp++; | ||
| 110 | - while (isdigit((unsigned char)*cp)) | ||
| 111 | - *bp++ = (char)*cp++; | ||
| 112 | + switch (ch) { | ||
| 113 | + case '-': neg = TRUE; | ||
| 114 | + case '+': ++str; | ||
| 115 | + default : break; | ||
| 116 | } | ||
| 117 | - *bp = '\0'; | ||
| 118 | - | ||
| 119 | - /* | ||
| 120 | - * Check to make sure the string is properly terminated. If | ||
| 121 | - * so, give the buffer to the decoding routine. | ||
| 122 | - */ | ||
| 123 | - if (*cp != '\0' && !isspace((unsigned char)*cp)) | ||
| 124 | - return 0; | ||
| 125 | - return atolfp(buf, lfp); | ||
| 126 | + | ||
| 127 | + if (!isdigit(ch = *(const unsigned char*)str) && (ch != '.')) | ||
| 128 | + return 0; | ||
| 129 | + if (!atolfp(str, lfp)) | ||
| 130 | + return 0; | ||
| 131 | + | ||
| 132 | + /* now do a chained/overlapping division by 1000 to get from | ||
| 133 | + * seconds to msec. 1000 is small enough to go with temporary | ||
| 134 | + * 32bit accus for Q and R. | ||
| 135 | + */ | ||
| 136 | + q = lfp->l_ui / 1000u; | ||
| 137 | + r = lfp->l_ui - (q * 1000u); | ||
| 138 | + lfp->l_ui = q; | ||
| 139 | + | ||
| 140 | + r = (r << 16) | (lfp->l_uf >> 16); | ||
| 141 | + q = r / 1000u; | ||
| 142 | + r = ((r - q * 1000) << 16) | (lfp->l_uf & 0x0FFFFu); | ||
| 143 | + lfp->l_uf = q << 16; | ||
| 144 | + q = r / 1000; | ||
| 145 | + lfp->l_uf |= q; | ||
| 146 | + r -= q * 1000u; | ||
| 147 | + | ||
| 148 | + /* fix sign */ | ||
| 149 | + if (neg) | ||
| 150 | + L_NEG(lfp); | ||
| 151 | + /* round */ | ||
| 152 | + if (r >= 500) | ||
| 153 | + L_ADDF(lfp, (neg ? -1 : 1)); | ||
| 154 | + return 1; | ||
| 155 | } | ||
| 156 | --- ntpd/refclock_palisade.c 2020-04-11 04:31:33.000000000 -0500 | ||
| 157 | +++ ../ntp-stable-p16-sec/ntpd/refclock_palisade.c 2023-04-15 18:09:29.787588000 -0500 | ||
| 158 | @@ -1225,9 +1225,9 @@ | ||
| 159 | return; /* using synchronous packet input */ | ||
| 160 | |||
| 161 | if(up->type == CLK_PRAECIS) { | ||
| 162 | - if(write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0) | ||
| 163 | + if (write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0) { | ||
| 164 | msyslog(LOG_ERR, "Palisade(%d) write: %m:",unit); | ||
| 165 | - else { | ||
| 166 | + } else { | ||
| 167 | praecis_msg = 1; | ||
| 168 | return; | ||
| 169 | } | ||
| 170 | @@ -1249,20 +1249,53 @@ | ||
| 171 | |||
| 172 | pp = peer->procptr; | ||
| 173 | |||
| 174 | - memcpy(buf+p,rbufp->recv_space.X_recv_buffer, rbufp->recv_length); | ||
| 175 | + if (p + rbufp->recv_length >= sizeof buf) { | ||
| 176 | + struct palisade_unit *up; | ||
| 177 | + up = pp->unitptr; | ||
| 178 | + | ||
| 179 | + /* | ||
| 180 | + * We COULD see if there is a \r\n in the incoming | ||
| 181 | + * buffer before it overflows, and then process the | ||
| 182 | + * current line. | ||
| 183 | + * | ||
| 184 | + * Similarly, if we already have a hunk of data that | ||
| 185 | + * we're now flushing, that will cause the line of | ||
| 186 | + * data we're in the process of collecting to be garbage. | ||
| 187 | + * | ||
| 188 | + * Since we now check for this overflow and log when it | ||
| 189 | + * happens, we're now in a better place to easily see | ||
| 190 | + * what's going on and perhaps better choices can be made. | ||
| 191 | + */ | ||
| 192 | + | ||
| 193 | + /* Do we need to log the size of the overflow? */ | ||
| 194 | + msyslog(LOG_ERR, "Palisade(%d) praecis_parse(): input buffer overflow", | ||
| 195 | + up->unit); | ||
| 196 | + | ||
| 197 | + p = 0; | ||
| 198 | + praecis_msg = 0; | ||
| 199 | + | ||
| 200 | + refclock_report(peer, CEVNT_BADREPLY); | ||
| 201 | + | ||
| 202 | + return; | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + memcpy(buf+p, rbufp->recv_buffer, rbufp->recv_length); | ||
| 206 | p += rbufp->recv_length; | ||
| 207 | |||
| 208 | - if(buf[p-2] == '\r' && buf[p-1] == '\n') { | ||
| 209 | + if ( p >= 2 | ||
| 210 | + && buf[p-2] == '\r' | ||
| 211 | + && buf[p-1] == '\n') { | ||
| 212 | buf[p-2] = '\0'; | ||
| 213 | record_clock_stats(&peer->srcadr, buf); | ||
| 214 | |||
| 215 | p = 0; | ||
| 216 | praecis_msg = 0; | ||
| 217 | |||
| 218 | - if (HW_poll(pp) < 0) | ||
| 219 | + if (HW_poll(pp) < 0) { | ||
| 220 | refclock_report(peer, CEVNT_FAULT); | ||
| 221 | - | ||
| 222 | + } | ||
| 223 | } | ||
| 224 | + return; | ||
| 225 | } | ||
| 226 | |||
| 227 | static void | ||
| 228 | @@ -1407,7 +1440,10 @@ | ||
| 229 | |||
| 230 | /* Edge trigger */ | ||
| 231 | if (up->type == CLK_ACUTIME) | ||
| 232 | - write (pp->io.fd, "", 1); | ||
| 233 | + if (write (pp->io.fd, "", 1) != 1) | ||
| 234 | + msyslog(LOG_WARNING, | ||
| 235 | + "Palisade(%d) HW_poll: failed to send trigger: %m", | ||
| 236 | + up->unit); | ||
| 237 | |||
| 238 | if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) { | ||
| 239 | #ifdef DEBUG | ||
| 240 | --- tests/libntp/strtolfp.c 2020-05-22 01:33:24.000000000 -0500 | ||
| 241 | +++ ../ntp-stable-p16-sec/tests/libntp/strtolfp.c 2023-04-16 03:28:16.967582000 -0500 | ||
| 242 | @@ -26,6 +26,13 @@ | ||
| 243 | return; | ||
| 244 | } | ||
| 245 | |||
| 246 | +static const char* fmtLFP(const l_fp *e, const l_fp *a) | ||
| 247 | +{ | ||
| 248 | + static char buf[100]; | ||
| 249 | + snprintf(buf, sizeof(buf), "e=$%08x.%08x, a=$%08x.%08x", | ||
| 250 | + e->l_ui, e->l_uf, a->l_ui, a->l_uf); | ||
| 251 | + return buf; | ||
| 252 | +} | ||
| 253 | |||
| 254 | void test_PositiveInteger(void) { | ||
| 255 | const char *str = "500"; | ||
| 256 | @@ -37,8 +44,8 @@ | ||
| 257 | TEST_ASSERT_TRUE(atolfp(str, &actual)); | ||
| 258 | TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms)); | ||
| 259 | |||
| 260 | - TEST_ASSERT_TRUE(IsEqual(expected, actual)); | ||
| 261 | - TEST_ASSERT_TRUE(IsEqual(expected, actual_ms)); | ||
| 262 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual)); | ||
| 263 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms)); | ||
| 264 | } | ||
| 265 | |||
| 266 | void test_NegativeInteger(void) { | ||
| 267 | @@ -54,8 +61,8 @@ | ||
| 268 | TEST_ASSERT_TRUE(atolfp(str, &actual)); | ||
| 269 | TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms)); | ||
| 270 | |||
| 271 | - TEST_ASSERT_TRUE(IsEqual(expected, actual)); | ||
| 272 | - TEST_ASSERT_TRUE(IsEqual(expected, actual_ms)); | ||
| 273 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual)); | ||
| 274 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms)); | ||
| 275 | } | ||
| 276 | |||
| 277 | void test_PositiveFraction(void) { | ||
| 278 | @@ -68,8 +75,8 @@ | ||
| 279 | TEST_ASSERT_TRUE(atolfp(str, &actual)); | ||
| 280 | TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms)); | ||
| 281 | |||
| 282 | - TEST_ASSERT_TRUE(IsEqual(expected, actual)); | ||
| 283 | - TEST_ASSERT_TRUE(IsEqual(expected, actual_ms)); | ||
| 284 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual)); | ||
| 285 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms)); | ||
| 286 | } | ||
| 287 | |||
| 288 | void test_NegativeFraction(void) { | ||
| 289 | @@ -85,8 +92,8 @@ | ||
| 290 | TEST_ASSERT_TRUE(atolfp(str, &actual)); | ||
| 291 | TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms)); | ||
| 292 | |||
| 293 | - TEST_ASSERT_TRUE(IsEqual(expected, actual)); | ||
| 294 | - TEST_ASSERT_TRUE(IsEqual(expected, actual_ms)); | ||
| 295 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual)); | ||
| 296 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms)); | ||
| 297 | } | ||
| 298 | |||
| 299 | void test_PositiveMsFraction(void) { | ||
| 300 | @@ -100,9 +107,8 @@ | ||
| 301 | TEST_ASSERT_TRUE(atolfp(str, &actual)); | ||
| 302 | TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms)); | ||
| 303 | |||
| 304 | - TEST_ASSERT_TRUE(IsEqual(expected, actual)); | ||
| 305 | - TEST_ASSERT_TRUE(IsEqual(expected, actual_ms)); | ||
| 306 | - | ||
| 307 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual)); | ||
| 308 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms)); | ||
| 309 | } | ||
| 310 | |||
| 311 | void test_NegativeMsFraction(void) { | ||
| 312 | @@ -118,9 +124,8 @@ | ||
| 313 | TEST_ASSERT_TRUE(atolfp(str, &actual)); | ||
| 314 | TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms)); | ||
| 315 | |||
| 316 | - TEST_ASSERT_TRUE(IsEqual(expected, actual)); | ||
| 317 | - TEST_ASSERT_TRUE(IsEqual(expected, actual_ms)); | ||
| 318 | - | ||
| 319 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual)); | ||
| 320 | + TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms)); | ||
| 321 | } | ||
| 322 | |||
| 323 | void test_InvalidChars(void) { | ||
diff --git a/meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb b/meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb index 91e4945a17..7861a5e3e6 100644 --- a/meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb +++ b/meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb | |||
| @@ -24,6 +24,7 @@ SRC_URI = "http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-${PV}.tar.g | |||
| 24 | file://sntp.service \ | 24 | file://sntp.service \ |
| 25 | file://sntp \ | 25 | file://sntp \ |
| 26 | file://ntpd.list \ | 26 | file://ntpd.list \ |
| 27 | file://CVE-2023-2655x.patch;striplevel=0 \ | ||
| 27 | " | 28 | " |
| 28 | 29 | ||
| 29 | SRC_URI[sha256sum] = "f65840deab68614d5d7ceb2d0bb9304ff70dcdedd09abb79754a87536b849c19" | 30 | SRC_URI[sha256sum] = "f65840deab68614d5d7ceb2d0bb9304ff70dcdedd09abb79754a87536b849c19" |
| @@ -92,6 +93,14 @@ PACKAGECONFIG[debug] = "--enable-debugging,--disable-debugging" | |||
| 92 | PACKAGECONFIG[mdns] = "ac_cv_header_dns_sd_h=yes,ac_cv_header_dns_sd_h=no,mdns" | 93 | PACKAGECONFIG[mdns] = "ac_cv_header_dns_sd_h=yes,ac_cv_header_dns_sd_h=no,mdns" |
| 93 | PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6," | 94 | PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6," |
| 94 | 95 | ||
| 96 | do_configure:append() { | ||
| 97 | # tests are generated but also checked-in to source control | ||
| 98 | # when CVE-2023-2655x.patch changes timestamp of test source file, Makefile detects it and tries to regenerate it | ||
| 99 | # however it fails because of missing ruby interpretter; adding ruby-native as dependency fixes it | ||
| 100 | # since the regenerated file is identical to the one from source control, touch the generated file instead of adding heavy dependency | ||
| 101 | touch ${S}/tests/libntp/run-strtolfp.c | ||
| 102 | } | ||
| 103 | |||
| 95 | do_install:append() { | 104 | do_install:append() { |
| 96 | install -d ${D}${sysconfdir}/init.d | 105 | install -d ${D}${sysconfdir}/init.d |
| 97 | install -m 644 ${WORKDIR}/ntp.conf ${D}${sysconfdir} | 106 | install -m 644 ${WORKDIR}/ntp.conf ${D}${sysconfdir} |
