diff -up ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2016-1548 ntp-4.2.6p5/ntpd/ntp_proto.c --- ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2016-1548 2016-04-28 08:37:42.513561354 +0200 +++ ntp-4.2.6p5/ntpd/ntp_proto.c 2016-04-28 09:30:59.450347729 +0200 @@ -306,6 +306,7 @@ receive( int authlen; /* offset of MAC field */ int is_authentic = 0; /* cryptosum ok */ int retcode = AM_NOMATCH; /* match code */ + int xleave_mismatch = 0; /* mismatch in xleave mode */ keyid_t skeyid = 0; /* key IDs */ u_int32 opcode = 0; /* extension field opcode */ sockaddr_u *dstadr_sin; /* active runway */ @@ -1067,9 +1068,8 @@ receive( } /* - * Check for bogus packet in basic mode. If found, switch to - * interleaved mode and resynchronize, but only after confirming - * the packet is not bogus in symmetric interleaved mode. + * Check for bogus packet in basic mode. If found, check if it's not + * a valid packet in symmetric interleaved mode. */ } else if (peer->flip == 0) { if (L_ISZERO(&p_org) || !L_ISEQU(&p_org, &peer->aorg)) { @@ -1077,8 +1077,7 @@ receive( peer->flash |= TEST2; /* bogus */ if (!L_ISZERO(&peer->dst) && L_ISEQU(&p_org, &peer->dst)) { - peer->flip = 1; - report_event(PEVNT_XLEAVE, peer, NULL); + xleave_mismatch = 1; } } else { L_CLR(&peer->aorg); @@ -1152,6 +1151,16 @@ receive( } /* + * If the packet is bogus in basic mode but not in symmetric + * interleaved mode and it passed the authentication check, + * enable the mode and resynchronize. + */ + if (xleave_mismatch && hismode == MODE_ACTIVE) { + peer->flip = 1; + report_event(PEVNT_XLEAVE, peer, NULL); + } + + /* * Update the state variables. */ if (peer->flip == 0) { @@ -1715,5 +1723,12 @@ clock_update( sys_rootdelay = peer->delay + peer->rootdelay; sys_reftime = peer->dst; + + /* Randomize the fraction part of the reference time to not reveal + peer->dst to NTP clients as it could be used in a DoS attack + enabling the symmetric interleaved mode with spoofed packets */ + ntp_crypto_random_buf(&sys_reftime.l_uf, sizeof (sys_reftime.l_uf)); + if (L_ISHIS(&sys_reftime, &peer->dst)) + sys_reftime.l_ui--; #ifdef DEBUG if (debug)