aboutsummaryrefslogtreecommitdiffstats
path: root/meta-networking
diff options
context:
space:
mode:
authorHitendra Prajapati <hprajapati@mvista.com>2023-07-04 12:18:24 +0530
committerArmin Kuster <akuster808@gmail.com>2023-07-14 07:08:54 -0400
commitfbe2d05a159aa95f81de89bd0ae6401f036d31d6 (patch)
tree31baf23c43bafb0bb9d5d24576e703b70eef7113 /meta-networking
parent7ca27d5cf3ec147ec933a8660b252cf57d107a27 (diff)
downloadmeta-openembedded-fbe2d05a159aa95f81de89bd0ae6401f036d31d6.tar.gz
ntp: backport patch for 5 CVEs CVE-2023-26551/2/3/4/5
Upstream-Status: Backport from https://archive.ntp.org/ntp4/ntp-4.2/ntp-4.2.8p15-3806-3807.patch 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. Backport fixes for: CVE: CVE-2023-26551 CVE: CVE-2023-26552 CVE: CVE-2023-26553 CVE: CVE-2023-26554 CVE: CVE-2023-26555 Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
Diffstat (limited to 'meta-networking')
-rw-r--r--meta-networking/recipes-support/ntp/ntp/CVE-2023-2655x.patch340
-rw-r--r--meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb10
2 files changed, 349 insertions, 1 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 100644
index 0000000000..734c6f197b
--- /dev/null
+++ b/meta-networking/recipes-support/ntp/ntp/CVE-2023-2655x.patch
@@ -0,0 +1,340 @@
+ntp: backport patch for 5 CVEs CVE-2023-26551/2/3/4/5
+
+Upstream-Status: Backport [https://archive.ntp.org/ntp4/ntp-4.2/ntp-4.2.8p15-3806-3807.patch]
+CVE: CVE-2023-26551
+CVE: CVE-2023-26552
+CVE: CVE-2023-26553
+CVE: CVE-2023-26554
+CVE: CVE-2023-26555
+
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ include/ntp_fp.h | 4 +-
+ libntp/mstolfp.c | 108 +++++++++++++++------------------------
+ ntpd/refclock_palisade.c | 50 +++++++++++++++---
+ tests/libntp/strtolfp.c | 33 +++++++-----
+ 4 files changed, 104 insertions(+), 91 deletions(-)
+
+diff --git a/include/ntp_fp.h b/include/ntp_fp.h
+index afd1f82..fe6e390 100644
+--- a/include/ntp_fp.h
++++ b/include/ntp_fp.h
+@@ -195,9 +195,9 @@ typedef u_int32 u_fp;
+ do { \
+ int32 add_f = (int32)(f); \
+ if (add_f >= 0) \
+- M_ADD((r_i), (r_f), 0, (uint32)( add_f)); \
++ M_ADD((r_i), (r_f), 0, (u_int32)( add_f)); \
+ else \
+- M_SUB((r_i), (r_f), 0, (uint32)(-add_f)); \
++ M_SUB((r_i), (r_f), 0, (u_int32)(-add_f)); \
+ } while(0)
+
+ #define M_ISNEG(v_i) /* v < 0 */ \
+diff --git a/libntp/mstolfp.c b/libntp/mstolfp.c
+index 3dfc4ef..a906d76 100644
+--- a/libntp/mstolfp.c
++++ b/libntp/mstolfp.c
+@@ -14,86 +14,58 @@ mstolfp(
+ l_fp *lfp
+ )
+ {
+- register const char *cp;
+- register char *bp;
+- register const char *cpdec;
+- char buf[100];
++ int ch, neg = 0;
++ u_int32 q, r;
+
+ /*
+ * We understand numbers of the form:
+ *
+ * [spaces][-|+][digits][.][digits][spaces|\n|\0]
+ *
+- * This is one enormous hack. Since I didn't feel like
+- * rewriting the decoding routine for milliseconds, what
+- * is essentially done here is to make a copy of the string
+- * with the decimal moved over three places so the seconds
+- * decoding routine can be used.
++ * This is kinda hack. We use 'atolfp' to do the basic parsing
++ * (after some initial checks) and then divide the result by
++ * 1000. The original implementation avoided that by
++ * hacking up the input string to move the decimal point, but
++ * that needed string manipulations prone to buffer overruns.
++ * To avoid that trouble we do the conversion first and adjust
++ * the result.
+ */
+- bp = buf;
+- cp = str;
+- while (isspace((unsigned char)*cp))
+- cp++;
+
+- if (*cp == '-' || *cp == '+') {
+- *bp++ = *cp++;
+- }
+-
+- if (*cp != '.' && !isdigit((unsigned char)*cp))
+- return 0;
+-
++ while (isspace(ch = *(const unsigned char*)str))
++ ++str;
+
+- /*
+- * Search forward for the decimal point or the end of the string.
+- */
+- cpdec = cp;
+- while (isdigit((unsigned char)*cpdec))
+- cpdec++;
+-
+- /*
+- * Found something. If we have more than three digits copy the
+- * excess over, else insert a leading 0.
+- */
+- if ((cpdec - cp) > 3) {
+- do {
+- *bp++ = (char)*cp++;
+- } while ((cpdec - cp) > 3);
+- } else {
+- *bp++ = '0';
++ switch (ch) {
++ case '-': neg = TRUE;
++ case '+': ++str;
++ default : break;
+ }
+
+- /*
+- * Stick the decimal in. If we've got less than three digits in
+- * front of the millisecond decimal we insert the appropriate number
+- * of zeros.
+- */
+- *bp++ = '.';
+- if ((cpdec - cp) < 3) {
+- size_t i = 3 - (cpdec - cp);
+- do {
+- *bp++ = '0';
+- } while (--i > 0);
+- }
++ if (!isdigit(ch = *(const unsigned char*)str) && (ch != '.'))
++ return 0;
++ if (!atolfp(str, lfp))
++ return 0;
+
+- /*
+- * Copy the remainder up to the millisecond decimal. If cpdec
+- * is pointing at a decimal point, copy in the trailing number too.
++ /* now do a chained/overlapping division by 1000 to get from
++ * seconds to msec. 1000 is small enough to go with temporary
++ * 32bit accus for Q and R.
+ */
+- while (cp < cpdec)
+- *bp++ = (char)*cp++;
+-
+- if (*cp == '.') {
+- cp++;
+- while (isdigit((unsigned char)*cp))
+- *bp++ = (char)*cp++;
+- }
+- *bp = '\0';
++ q = lfp->l_ui / 1000u;
++ r = lfp->l_ui - (q * 1000u);
++ lfp->l_ui = q;
+
+- /*
+- * Check to make sure the string is properly terminated. If
+- * so, give the buffer to the decoding routine.
+- */
+- if (*cp != '\0' && !isspace((unsigned char)*cp))
+- return 0;
+- return atolfp(buf, lfp);
++ r = (r << 16) | (lfp->l_uf >> 16);
++ q = r / 1000u;
++ r = ((r - q * 1000) << 16) | (lfp->l_uf & 0x0FFFFu);
++ lfp->l_uf = q << 16;
++ q = r / 1000;
++ lfp->l_uf |= q;
++ r -= q * 1000u;
++
++ /* fix sign */
++ if (neg)
++ L_NEG(lfp);
++ /* round */
++ if (r >= 500)
++ L_ADDF(lfp, (neg ? -1 : 1));
++ return 1;
+ }
+diff --git a/ntpd/refclock_palisade.c b/ntpd/refclock_palisade.c
+index cb68255..15c21d8 100644
+--- a/ntpd/refclock_palisade.c
++++ b/ntpd/refclock_palisade.c
+@@ -1225,9 +1225,9 @@ palisade_poll (
+ return; /* using synchronous packet input */
+
+ if(up->type == CLK_PRAECIS) {
+- if(write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0)
++ if (write(peer->procptr->io.fd,"SPSTAT\r\n",8) < 0) {
+ msyslog(LOG_ERR, "Palisade(%d) write: %m:",unit);
+- else {
++ } else {
+ praecis_msg = 1;
+ return;
+ }
+@@ -1249,20 +1249,53 @@ praecis_parse (
+
+ pp = peer->procptr;
+
+- memcpy(buf+p,rbufp->recv_space.X_recv_buffer, rbufp->recv_length);
++ if (p + rbufp->recv_length >= sizeof buf) {
++ struct palisade_unit *up;
++ up = pp->unitptr;
++
++ /*
++ * We COULD see if there is a \r\n in the incoming
++ * buffer before it overflows, and then process the
++ * current line.
++ *
++ * Similarly, if we already have a hunk of data that
++ * we're now flushing, that will cause the line of
++ * data we're in the process of collecting to be garbage.
++ *
++ * Since we now check for this overflow and log when it
++ * happens, we're now in a better place to easily see
++ * what's going on and perhaps better choices can be made.
++ */
++
++ /* Do we need to log the size of the overflow? */
++ msyslog(LOG_ERR, "Palisade(%d) praecis_parse(): input buffer overflow",
++ up->unit);
++
++ p = 0;
++ praecis_msg = 0;
++
++ refclock_report(peer, CEVNT_BADREPLY);
++
++ return;
++ }
++
++ memcpy(buf+p, rbufp->recv_buffer, rbufp->recv_length);
+ p += rbufp->recv_length;
+
+- if(buf[p-2] == '\r' && buf[p-1] == '\n') {
++ if ( p >= 2
++ && buf[p-2] == '\r'
++ && buf[p-1] == '\n') {
+ buf[p-2] = '\0';
+ record_clock_stats(&peer->srcadr, buf);
+
+ p = 0;
+ praecis_msg = 0;
+
+- if (HW_poll(pp) < 0)
++ if (HW_poll(pp) < 0) {
+ refclock_report(peer, CEVNT_FAULT);
+-
++ }
+ }
++ return;
+ }
+
+ static void
+@@ -1407,7 +1440,10 @@ HW_poll (
+
+ /* Edge trigger */
+ if (up->type == CLK_ACUTIME)
+- write (pp->io.fd, "", 1);
++ if (write (pp->io.fd, "", 1) != 1)
++ msyslog(LOG_WARNING,
++ "Palisade(%d) HW_poll: failed to send trigger: %m",
++ up->unit);
+
+ if (ioctl(pp->io.fd, TIOCMSET, &x) < 0) {
+ #ifdef DEBUG
+diff --git a/tests/libntp/strtolfp.c b/tests/libntp/strtolfp.c
+index 6855d9b..9090159 100644
+--- a/tests/libntp/strtolfp.c
++++ b/tests/libntp/strtolfp.c
+@@ -26,6 +26,13 @@ setUp(void)
+ return;
+ }
+
++static const char* fmtLFP(const l_fp *e, const l_fp *a)
++{
++ static char buf[100];
++ snprintf(buf, sizeof(buf), "e=$%08x.%08x, a=$%08x.%08x",
++ e->l_ui, e->l_uf, a->l_ui, a->l_uf);
++ return buf;
++}
+
+ void test_PositiveInteger(void) {
+ const char *str = "500";
+@@ -37,8 +44,8 @@ void test_PositiveInteger(void) {
+ TEST_ASSERT_TRUE(atolfp(str, &actual));
+ TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms));
+
+- TEST_ASSERT_TRUE(IsEqual(expected, actual));
+- TEST_ASSERT_TRUE(IsEqual(expected, actual_ms));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms));
+ }
+
+ void test_NegativeInteger(void) {
+@@ -54,8 +61,8 @@ void test_NegativeInteger(void) {
+ TEST_ASSERT_TRUE(atolfp(str, &actual));
+ TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms));
+
+- TEST_ASSERT_TRUE(IsEqual(expected, actual));
+- TEST_ASSERT_TRUE(IsEqual(expected, actual_ms));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms));
+ }
+
+ void test_PositiveFraction(void) {
+@@ -68,8 +75,8 @@ void test_PositiveFraction(void) {
+ TEST_ASSERT_TRUE(atolfp(str, &actual));
+ TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms));
+
+- TEST_ASSERT_TRUE(IsEqual(expected, actual));
+- TEST_ASSERT_TRUE(IsEqual(expected, actual_ms));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms));
+ }
+
+ void test_NegativeFraction(void) {
+@@ -85,8 +92,8 @@ void test_NegativeFraction(void) {
+ TEST_ASSERT_TRUE(atolfp(str, &actual));
+ TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms));
+
+- TEST_ASSERT_TRUE(IsEqual(expected, actual));
+- TEST_ASSERT_TRUE(IsEqual(expected, actual_ms));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms));
+ }
+
+ void test_PositiveMsFraction(void) {
+@@ -100,9 +107,8 @@ void test_PositiveMsFraction(void) {
+ TEST_ASSERT_TRUE(atolfp(str, &actual));
+ TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms));
+
+- TEST_ASSERT_TRUE(IsEqual(expected, actual));
+- TEST_ASSERT_TRUE(IsEqual(expected, actual_ms));
+-
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms));
+ }
+
+ void test_NegativeMsFraction(void) {
+@@ -118,9 +124,8 @@ void test_NegativeMsFraction(void) {
+ TEST_ASSERT_TRUE(atolfp(str, &actual));
+ TEST_ASSERT_TRUE(mstolfp(str_ms, &actual_ms));
+
+- TEST_ASSERT_TRUE(IsEqual(expected, actual));
+- TEST_ASSERT_TRUE(IsEqual(expected, actual_ms));
+-
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual), fmtLFP(&expected, &actual));
++ TEST_ASSERT_TRUE_MESSAGE(IsEqual(expected, actual_ms), fmtLFP(&expected, &actual_ms));
+ }
+
+ void test_InvalidChars(void) {
+--
+2.25.1
+
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 7e168825e0..1a223db6fa 100644
--- a/meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb
+++ b/meta-networking/recipes-support/ntp/ntp_4.2.8p15.bb
@@ -22,8 +22,8 @@ SRC_URI = "http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-${PV}.tar.g
file://sntp.service \
file://sntp \
file://ntpd.list \
+ file://CVE-2023-2655x.patch \
"
-
SRC_URI[sha256sum] = "f65840deab68614d5d7ceb2d0bb9304ff70dcdedd09abb79754a87536b849c19"
inherit autotools update-rc.d useradd systemd pkgconfig
@@ -61,6 +61,14 @@ PACKAGECONFIG[debug] = "--enable-debugging,--disable-debugging"
PACKAGECONFIG[mdns] = "ac_cv_header_dns_sd_h=yes,ac_cv_header_dns_sd_h=no,mdns"
PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
+do_configure_append() {
+ # tests are generated but also checked-in to source control
+ # when CVE-2023-2655x.patch changes timestamp of test source file, Makefile detects it and tries to regenerate it
+ # however it fails because of missing ruby interpretter; adding ruby-native as dependency fixes it
+ # since the regenerated file is identical to the one from source control, touch the generated file instead of adding heavy dependency
+ touch ${S}/tests/libntp/run-strtolfp.c
+}
+
do_install_append() {
install -d ${D}${sysconfdir}/init.d
install -m 644 ${WORKDIR}/ntp.conf ${D}${sysconfdir}