Module Name: src Committed By: bouyer Date: Mon Jan 6 19:12:23 UTC 2014
Modified Files: src/etc [netbsd-6-1]: ntp.conf src/external/bsd/ntp/dist/ntpd [netbsd-6-1]: ntp_request.c Log Message: etc/ntp.conf 1.16, 1.17, 1.18 via patch external/bsd/ntp/dist/ntpd/ntp_request.c patch Patch from ntp 4.2.7p404 to prevent an amplifier and DoS attack. Add several "restrict" lines to the default ntp.conf and improve comments [spz, ticket #1010] To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.14.16.1 src/etc/ntp.conf cvs rdiff -u -r1.7 -r1.7.16.1 src/external/bsd/ntp/dist/ntpd/ntp_request.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/etc/ntp.conf diff -u src/etc/ntp.conf:1.14 src/etc/ntp.conf:1.14.16.1 --- src/etc/ntp.conf:1.14 Mon Jan 16 22:20:45 2012 +++ src/etc/ntp.conf Mon Jan 6 19:12:23 2014 @@ -1,4 +1,4 @@ -# $NetBSD: ntp.conf,v 1.14 2012/01/16 22:20:45 christos Exp $ +# $NetBSD: ntp.conf,v 1.14.16.1 2014/01/06 19:12:23 bouyer Exp $ # # NetBSD default Network Time Protocol (NTP) configuration file for ntpd @@ -23,7 +23,8 @@ driftfile /var/db/ntp.drift logconfig -syncstatus -# This will help minimize disruptions due to network congestion. Don't +# Refuse to set the local clock if there are too few good peers or servers. +# This may help minimize disruptions due to network congestion. Don't # do this if you configure only one server! tos minsane 2 @@ -32,22 +33,59 @@ tos minsane 2 # mdnstries 0 +# Access control restrictions. +# See /usr/share/doc/html/ntp/accopt.html for syntax. +# See <http://support.ntp.org/bin/view/Support/AccessRestrictions> for advice. +# Last match wins. +# +# Some of the more common keywords are: +# ignore Deny packets of all kinds. +# kod Send "kiss-o'-death" packets if clients exceed rate +# limits. +# nomodify Deny attempts to modify the state of the server via +# ntpq or ntpdc queries. +# noquery Deny all ntpq and ntpdc queries. Does not affect time +# synchronisation. +# nopeer Prevent establishing an new peer association. +# Does not affect preconfigured peer associations. +# Does not affect client/server time synchronisation. +# noserve Deny all time synchronisation. Does not affect ntpq or +# ntpdc queries. +# notrap Deny the trap subset of the ntpdc control message protocol. +# notrust Deny packets that are not cryptographically authenticated. +# +# By default, either deny everything, or allow client/server time exchange +# but deny configuration changes, queries, and peer associations that were not +# explicitly configured. +# (Uncomment one of the following "restrict default" lines.) +# +#restrict default ignore +restrict default kod nopeer noquery + +# Fewer restrictions for the local subnet. +# (Uncomment and adjust as appropriate.) +# +#restrict 192.0.2.0 mask 255.255.255.0 kod nomodify notrap nopeer +#restrict 2001:db8:: mask ffff:ffff:: kod nomodify notrap nopeer + +# No restrictions for localhost. +# +restrict 127.0.0.1 +restrict ::1 + # Hereafter should be "server" or "peer" statements to configure other -# hosts to exchange NTP packets with. Peers should be selected in such -# a way that the network path to them is symmetric (that is, the series -# of links and routers used to get to the peer is the same one that the -# peer uses to get back. NTP assumes such symmetry in its network delay -# calculation. NTP will apply an incorrect adjustment to timestamps -# received from the peer if the path is not symmetric. This can result -# in clock skew (your system clock being maintained consistently wrong -# by a certain amount). -# -# The best way to select symmetric peers is to make sure that the -# network path to them is as short as possible (this reduces the chance -# that there is more than one network path between you and your peer). -# You can measure these distances with the traceroute(8) program. The -# best place to start looking for NTP peers for your system is within -# your own network, or at your Internet Service Provider (ISP). +# hosts to exchange NTP packets with. +# +# See <http://support.ntp.org/bin/view/Support/DesigningYourNTPNetwork> +# and <http://support.ntp.org/bin/view/Support/SelectingOffsiteNTPServers> +# for advice. +# +# Peers should be selected in such a way that the network path to them +# is short, uncongested, and symmetric (that is, the series of links +# and routers used to get to the peer is the same one that the peer +# uses to get back). The best place to start looking for NTP peers for +# your system is within your own network, or at your Internet Service +# Provider (ISP). # # Ideally, you should select at least three other systems to talk NTP # with, for an "what I tell you three times is true" effect. @@ -55,22 +93,27 @@ mdnstries 0 #peer an.ntp.peer.goes.here #server an.ntp.server.goes.here +#restrict an.ntp.server.goes.here nomodify notrap -# Public servers from the pool.ntp.org project. Volunteer's servers -# are dynamically assigned to the CNAMES below via DNS round-robin. +# The pool.ntp.org project coordinates public time servers provided by +# volunteers. See <http://www.pool.ntp.org>. The *.netbsd.pool.ntp.org +# servers are intended to be used by default on NetBSD hosts, but +# servers that are closer to you are likely to be better. Consider +# using servers specific to your country, a nearby country, or your +# continent. +# # The pool.ntp.org project needs more volunteers! The only criteria to # join are a nailed-up connection and a static IP address. For details, # see the web page: # -# http://www.pool.ntp.org/join.html +# http://www.pool.ntp.org/join.html # -# Depending on the vagaries of DNS can occasionally pull in the same -# server twice. The following CNAMES are guaranteed to be disjoint, at -# least over some short interval. The following servers are allocated -# to the NetBSD project. - -server 0.netbsd.pool.ntp.org -server 1.netbsd.pool.ntp.org -server 2.netbsd.pool.ntp.org -server 3.netbsd.pool.ntp.org +server 0.netbsd.pool.ntp.org +restrict 0.netbsd.pool.ntp.org nomodify notrap +server 1.netbsd.pool.ntp.org +restrict 1.netbsd.pool.ntp.org nomodify notrap +server 2.netbsd.pool.ntp.org +restrict 2.netbsd.pool.ntp.org nomodify notrap +server 3.netbsd.pool.ntp.org +restrict 3.netbsd.pool.ntp.org nomodify notrap Index: src/external/bsd/ntp/dist/ntpd/ntp_request.c diff -u src/external/bsd/ntp/dist/ntpd/ntp_request.c:1.7 src/external/bsd/ntp/dist/ntpd/ntp_request.c:1.7.16.1 --- src/external/bsd/ntp/dist/ntpd/ntp_request.c:1.7 Wed Feb 1 22:48:15 2012 +++ src/external/bsd/ntp/dist/ntpd/ntp_request.c Mon Jan 6 19:12:22 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ntp_request.c,v 1.7 2012/02/01 22:48:15 kardel Exp $ */ +/* $NetBSD: ntp_request.c,v 1.7.16.1 2014/01/06 19:12:22 bouyer Exp $ */ /* * ntp_request.c - respond to information requests @@ -88,8 +88,7 @@ static void do_resaddflags (sockaddr_u * static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *); static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int); -static void mon_getlist_0 (sockaddr_u *, struct interface *, struct req_pkt *); -static void mon_getlist_1 (sockaddr_u *, struct interface *, struct req_pkt *); +static void mon_getlist (sockaddr_u *, struct interface *, struct req_pkt *); static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *); static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *); static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *); @@ -149,8 +148,8 @@ static struct req_proc ntp_codes[] = { sizeof(struct conf_restrict), do_ressubflags }, { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict), sizeof(struct conf_restrict), do_unrestrict }, - { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist_0 }, - { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist_1 }, + { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist }, + { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist }, { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats }, { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer), sizeof(struct conf_unpeer), reset_peer }, @@ -614,6 +613,9 @@ process_private( "process_private: failed auth mod_okay %d\n", mod_okay); #endif + if (!mod_okay) { + sys_restricted++; + } req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); return; } @@ -825,34 +827,42 @@ peer_info ( struct req_pkt *inpkt ) { - register struct info_peer_list *ipl; + struct info_peer_list ipl; register struct peer *pp; register struct info_peer *ip; register int items; + size_t item_sz; + char * datap; register int i, j; sockaddr_u addr; extern struct peer *sys_peer; l_fp ltmp; items = INFO_NITEMS(inpkt->err_nitems); - ipl = (struct info_peer_list *) inpkt->data; - + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->data; + if (item_sz != sizeof(ipl)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_peer)); while (items-- > 0 && ip != 0) { + memset(&ipl,0,sizeof(ipl)); + memcpy(&ipl, datap, item_sz); ZERO_SOCK(&addr); - NSRCPORT(&addr) = ipl->port; - if (client_v6_capable && ipl->v6_flag) { + NSRCPORT(&addr) = ipl.port; + if (client_v6_capable && ipl.v6_flag) { AF(&addr) = AF_INET6; - SOCK_ADDR6(&addr) = ipl->addr6; + SOCK_ADDR6(&addr) = ipl.addr6; } else { AF(&addr) = AF_INET; - NSRCADR(&addr) = ipl->addr; + NSRCADR(&addr) = ipl.addr; } #ifdef ISC_PLATFORM_HAVESALEN addr.sa.sa_len = SOCKLEN(&addr); #endif - ipl++; + datap += item_sz; pp = findexistingpeer(&addr, NULL, -1, 0); if (NULL == pp) continue; @@ -958,10 +968,12 @@ peer_stats ( struct req_pkt *inpkt ) { - register struct info_peer_list *ipl; + struct info_peer_list ipl; register struct peer *pp; register struct info_peer_stats *ip; register int items; + size_t item_sz; + char * datap; sockaddr_u addr; extern struct peer *sys_peer; @@ -970,27 +982,33 @@ peer_stats ( printf("peer_stats: called\n"); #endif items = INFO_NITEMS(inpkt->err_nitems); - ipl = (struct info_peer_list *) inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->data; + if (item_sz > sizeof(ipl)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_peer_stats)); while (items-- > 0 && ip != 0) { + memset(&ipl,0,sizeof(ipl)); + memcpy(&ipl, datap, item_sz); memset((char *)&addr, 0, sizeof(addr)); - NSRCPORT(&addr) = ipl->port; - if (client_v6_capable && ipl->v6_flag) { + NSRCPORT(&addr) = ipl.port; + if (client_v6_capable && ipl.v6_flag) { AF(&addr) = AF_INET6; - SOCK_ADDR6(&addr) = ipl->addr6; + SOCK_ADDR6(&addr) = ipl.addr6; } else { AF(&addr) = AF_INET; - NSRCADR(&addr) = ipl->addr; + NSRCADR(&addr) = ipl.addr; } #ifdef ISC_PLATFORM_HAVESALEN addr.sa.sa_len = SOCKLEN(&addr); #endif DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", - stoa(&addr), ipl->port, NSRCPORT(&addr))); + stoa(&addr), ipl.port, NSRCPORT(&addr))); - ipl = (struct info_peer_list *)((char *)ipl + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; pp = findexistingpeer(&addr, NULL, -1, 0); if (NULL == pp) @@ -1326,10 +1344,10 @@ do_conf( struct req_pkt *inpkt ) { - static u_long soonest_ifrescan_time = 0; int items; + size_t item_sz; + char * datap; u_int fl; - struct conf_peer *cp; struct conf_peer temp_cp; sockaddr_u peeraddr; @@ -1339,42 +1357,16 @@ do_conf( * very picky here. */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_peer *)inpkt->data; - memset(&temp_cp, 0, sizeof(struct conf_peer)); - memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); - -#if 0 /* paranoid checking - these are done in newpeer() */ - fl = 0; - while (items-- > 0 && !fl) { - if (((temp_cp.version) > NTP_VERSION) - || ((temp_cp.version) < NTP_OLDVERSION)) - fl = 1; - if (temp_cp.hmode != MODE_ACTIVE - && temp_cp.hmode != MODE_CLIENT - && temp_cp.hmode != MODE_BROADCAST) - fl = 1; - if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST | - CONF_FLAG_IBURST | CONF_FLAG_SKEY)) - fl = 1; - cp = (struct conf_peer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); - } - - if (fl) { + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->data; + if (item_sz > sizeof(temp_cp)) { req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } -#endif /* end paranoid checking */ - - /* - * Looks okay, try it out - */ - items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_peer *)inpkt->data; while (items-- > 0) { memset(&temp_cp, 0, sizeof(struct conf_peer)); - memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); + memcpy(&temp_cp, datap, item_sz); ZERO_SOCK(&peeraddr); fl = 0; @@ -1418,24 +1410,7 @@ do_conf( return; } - /* - * ntp_intres.c uses REQ_CONFIG/doconf() to add each - * server after its name is resolved. If we have been - * disconnected from the network, it may notice the - * network has returned and add the first server while - * the relevant interface is still disabled, awaiting - * the next interface rescan. To get things moving - * more quickly, trigger an interface scan now, except - * if we have done so in the last half minute. - */ - if (soonest_ifrescan_time < current_time) { - soonest_ifrescan_time = current_time + 30; - timer_interfacetimeout(current_time); - DPRINTF(1, ("do_conf triggering interface rescan\n")); - } - - cp = (struct conf_peer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -1540,9 +1515,10 @@ do_unconf( struct req_pkt *inpkt ) { - register struct conf_unpeer *cp; struct conf_unpeer temp_cp; register int items; + size_t item_sz; + char * datap; register struct peer *peer; sockaddr_u peeraddr; int bad, found; @@ -1554,13 +1530,18 @@ do_unconf( * an error. */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->data; + if (item_sz > sizeof(temp_cp)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } bad = 0; while (items-- > 0 && !bad) { memset(&temp_cp, 0, sizeof(temp_cp)); + memcpy(&temp_cp, datap, item_sz); ZERO_SOCK(&peeraddr); - memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); if (client_v6_capable && temp_cp.v6_flag) { AF(&peeraddr) = AF_INET6; SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; @@ -1586,8 +1567,7 @@ do_unconf( } if (!found) bad = 1; - cp = (struct conf_unpeer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } if (bad) { @@ -1600,12 +1580,12 @@ do_unconf( */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + datap = inpkt->data; while (items-- > 0) { memset(&temp_cp, 0, sizeof(temp_cp)); + memcpy(&temp_cp, datap, item_sz); memset(&peeraddr, 0, sizeof(peeraddr)); - memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); if (client_v6_capable && temp_cp.v6_flag) { AF(&peeraddr) = AF_INET6; SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; @@ -1633,8 +1613,7 @@ do_unconf( peer_clear(peer, "GONE"); unpeer(peer); - cp = (struct conf_unpeer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -1868,8 +1847,10 @@ do_restrict( int op ) { - register struct conf_restrict *cr; + struct conf_restrict cr; register int items; + size_t item_sz; + char * datap; sockaddr_u matchaddr; sockaddr_u matchmask; int bad; @@ -1880,26 +1861,31 @@ do_restrict( * about it. Note we are very picky here. */ items = INFO_NITEMS(inpkt->err_nitems); - cr = (struct conf_restrict *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->data; + if (item_sz > sizeof(cr)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } bad = 0; - cr->flags = ntohs(cr->flags); - cr->mflags = ntohs(cr->mflags); while (items-- > 0 && !bad) { - if (cr->mflags & ~(RESM_NTPONLY)) + memcpy(&cr, datap, item_sz); + cr.flags = ntohs(cr.flags); + cr.mflags = ntohs(cr.mflags); + if (cr.mflags & ~(RESM_NTPONLY)) bad |= 1; - if (cr->flags & ~(RES_ALLFLAGS)) + if (cr.flags & ~(RES_ALLFLAGS)) bad |= 2; - if (cr->mask != htonl(INADDR_ANY)) { - if (client_v6_capable && cr->v6_flag != 0) { - if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6)) + if (cr.mask != htonl(INADDR_ANY)) { + if (client_v6_capable && cr.v6_flag != 0) { + if (IN6_IS_ADDR_UNSPECIFIED(&cr.addr6)) bad |= 4; } else - if (cr->addr == htonl(INADDR_ANY)) + if (cr.addr == htonl(INADDR_ANY)) bad |= 8; } - cr = (struct conf_restrict *)((char *)cr + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } if (bad) { @@ -1911,26 +1897,28 @@ do_restrict( /* * Looks okay, try it out */ - items = INFO_NITEMS(inpkt->err_nitems); - cr = (struct conf_restrict *)inpkt->data; ZERO_SOCK(&matchaddr); ZERO_SOCK(&matchmask); + datap = inpkt->data; while (items-- > 0) { - if (client_v6_capable && cr->v6_flag) { + memcpy(&cr, datap, item_sz); + cr.flags = ntohs(cr.flags); + cr.mflags = ntohs(cr.mflags); + if (client_v6_capable && cr.v6_flag) { AF(&matchaddr) = AF_INET6; AF(&matchmask) = AF_INET6; - SOCK_ADDR6(&matchaddr) = cr->addr6; - SOCK_ADDR6(&matchmask) = cr->mask6; + SOCK_ADDR6(&matchaddr) = cr.addr6; + SOCK_ADDR6(&matchmask) = cr.mask6; } else { AF(&matchaddr) = AF_INET; AF(&matchmask) = AF_INET; - NSRCADR(&matchaddr) = cr->addr; - NSRCADR(&matchmask) = cr->mask; + NSRCADR(&matchaddr) = cr.addr; + NSRCADR(&matchmask) = cr.mask; } - hack_restrict(op, &matchaddr, &matchmask, cr->mflags, - cr->flags); - cr++; + hack_restrict(op, &matchaddr, &matchmask, cr.mflags, + cr.flags); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -1941,106 +1929,13 @@ do_restrict( * mon_getlist - return monitor data */ static void -mon_getlist_0( - sockaddr_u *srcadr, - struct interface *inter, - 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(); -} - -/* - * mon_getlist - return monitor data - */ -static void -mon_getlist_1( +mon_getlist( sockaddr_u *srcadr, struct interface *inter, 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); } /* @@ -2110,8 +2005,10 @@ reset_peer( struct req_pkt *inpkt ) { - struct conf_unpeer *cp; + struct conf_unpeer cp; int items; + size_t item_sz; + char * datap; struct peer *peer; sockaddr_u peeraddr; int bad; @@ -2122,17 +2019,24 @@ reset_peer( */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->data; + if (item_sz > sizeof(cp)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } bad = 0; while (items-- > 0 && !bad) { + memset(&cp,0,sizeof(cp)); + memcpy(&cp, datap, item_sz); ZERO_SOCK(&peeraddr); - if (client_v6_capable && cp->v6_flag) { + if (client_v6_capable && cp.v6_flag) { AF(&peeraddr) = AF_INET6; - SOCK_ADDR6(&peeraddr) = cp->peeraddr6; + SOCK_ADDR6(&peeraddr) = cp.peeraddr6; } else { AF(&peeraddr) = AF_INET; - NSRCADR(&peeraddr) = cp->peeraddr; + NSRCADR(&peeraddr) = cp.peeraddr; } #ifdef ISC_PLATFORM_HAVESALEN @@ -2141,8 +2045,7 @@ reset_peer( peer = findexistingpeer(&peeraddr, NULL, -1, 0); if (NULL == peer) bad++; - cp = (struct conf_unpeer *)((char *)cp + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } if (bad) { @@ -2154,16 +2057,17 @@ reset_peer( * Now do it in earnest. */ - items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + datap = inpkt->data; while (items-- > 0) { + memset(&cp,0,sizeof(cp)); + memcpy(&cp, datap, item_sz); ZERO_SOCK(&peeraddr); - if (client_v6_capable && cp->v6_flag) { + if (client_v6_capable && cp.v6_flag) { AF(&peeraddr) = AF_INET6; - SOCK_ADDR6(&peeraddr) = cp->peeraddr6; + SOCK_ADDR6(&peeraddr) = cp.peeraddr6; } else { AF(&peeraddr) = AF_INET; - NSRCADR(&peeraddr) = cp->peeraddr; + NSRCADR(&peeraddr) = cp.peeraddr; } SET_PORT(&peeraddr, 123); #ifdef ISC_PLATFORM_HAVESALEN @@ -2174,8 +2078,7 @@ reset_peer( peer_reset(peer); peer = findexistingpeer(&peeraddr, peer, -1, 0); } - cp = (struct conf_unpeer *)((char *)cp + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -2887,7 +2790,7 @@ fill_info_if_stats(void *data, interface ifs->unmask.addr = SOCK_ADDR4(&ep->mask); } ifs->v6_flag = htonl(ifs->v6_flag); - strncpy(ifs->name, ep->name, sizeof(ifs->name)); + strlcpy(ifs->name, ep->name, sizeof(ifs->name)); ifs->family = htons(ep->family); ifs->flags = htonl(ep->flags); ifs->last_ttl = htonl(ep->last_ttl);