ntp: fix CVE-2013-5211 Upstream-status: Backport The monlist feature in ntp_request.c in ntpd in NTP before 4.2.7p26 allows remote attackers to cause a denial of service (traffic amplification) via forged (1) REQ_MON_GETLIST or (2) REQ_MON_GETLIST_1 requests, as exploited in the wild in December 2013. Signed-off-by: Zhang Xiao --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -1912,44 +1912,11 @@ mon_getlist_0( struct req_pkt *inpkt ) { - register struct info_monitor *im; - register struct mon_data *md; - extern struct mon_data mon_mru_list; - extern int mon_enabled; - #ifdef DEBUG if (debug > 2) printf("wants monitor 0 list\n"); #endif - if (!mon_enabled) { - req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); - return; - } - im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, - v6sizeof(struct info_monitor)); - for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; - md = md->mru_next) { - im->lasttime = htonl((u_int32)((current_time - - md->firsttime) / md->count)); - im->firsttime = htonl((u_int32)(current_time - md->lasttime)); - im->restr = htonl((u_int32)md->flags); - im->count = htonl((u_int32)(md->count)); - if (IS_IPV6(&md->rmtadr)) { - if (!client_v6_capable) - continue; - im->addr6 = SOCK_ADDR6(&md->rmtadr); - im->v6_flag = 1; - } else { - im->addr = NSRCADR(&md->rmtadr); - if (client_v6_capable) - im->v6_flag = 0; - } - im->port = md->rmtport; - im->mode = md->mode; - im->version = md->version; - im = (struct info_monitor *)more_pkt(); - } - flush_pkt(); + req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); } /* @@ -1962,50 +1929,7 @@ mon_getlist_1( struct req_pkt *inpkt ) { - register struct info_monitor_1 *im; - register struct mon_data *md; - extern struct mon_data mon_mru_list; - extern int mon_enabled; - - if (!mon_enabled) { - req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); - return; - } - im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, - v6sizeof(struct info_monitor_1)); - for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; - md = md->mru_next) { - im->lasttime = htonl((u_int32)((current_time - - md->firsttime) / md->count)); - im->firsttime = htonl((u_int32)(current_time - md->lasttime)); - im->restr = htonl((u_int32)md->flags); - im->count = htonl((u_int32)md->count); - if (IS_IPV6(&md->rmtadr)) { - if (!client_v6_capable) - continue; - im->addr6 = SOCK_ADDR6(&md->rmtadr); - im->v6_flag = 1; - im->daddr6 = SOCK_ADDR6(&md->interface->sin); - } else { - im->addr = NSRCADR(&md->rmtadr); - if (client_v6_capable) - im->v6_flag = 0; - if (MDF_BCAST == md->cast_flags) - im->daddr = NSRCADR(&md->interface->bcast); - else if (md->cast_flags) { - im->daddr = NSRCADR(&md->interface->sin); - if (!im->daddr) - im->daddr = NSRCADR(&md->interface->bcast); - } else - im->daddr = 4; - } - im->flags = htonl(md->cast_flags); - im->port = md->rmtport; - im->mode = md->mode; - im->version = md->version; - im = (struct info_monitor_1 *)more_pkt(); - } - flush_pkt(); + req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); } /*