diff -up ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2016-4956 ntp-4.2.6p5/ntpd/ntp_proto.c --- ntp-4.2.6p5/ntpd/ntp_proto.c.cve-2016-4956 2016-05-26 16:47:45.732665246 +0200 +++ ntp-4.2.6p5/ntpd/ntp_proto.c 2016-05-26 17:04:39.501397570 +0200 @@ -1077,13 +1077,8 @@ receive( * interleaved broadcast. so restart the protocol. */ } else if (hismode == MODE_BROADCAST) { - if (!L_ISZERO(&p_org) && !(peer->flags & FLAG_XB)) { - peer->flags |= FLAG_XB; - peer->aorg = p_xmt; - peer->borg = rbufp->recv_time; - report_event(PEVNT_XLEAVE, peer, NULL); - return; - } + if (!L_ISZERO(&p_org) == !(peer->flags & FLAG_XB)) + xleave_mismatch = 1; /* * Check for bogus packet in basic mode. If found, check if it's not @@ -1175,11 +1170,25 @@ 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. + * enable the mode and resynchronize. Also, handle switch in the + * broadcast interleaved mode. */ - if (xleave_mismatch && hismode == MODE_ACTIVE) { - peer->flip = 1; - report_event(PEVNT_XLEAVE, peer, NULL); + if (xleave_mismatch) { + if (hismode == MODE_ACTIVE) { + peer->flip = 1; + report_event(PEVNT_XLEAVE, peer, NULL); + } else if (hismode == MODE_BROADCAST) { + if (!L_ISZERO(&p_org)) { + peer->flags |= FLAG_XB; + peer->aorg = p_xmt; + peer->borg = rbufp->recv_time; + report_event(PEVNT_XLEAVE, peer, NULL); + } else { + peer->flags &= ~FLAG_XB; + report_event(PEVNT_XERR, peer, NULL); + } + return; + } } /*