Commit fa785737 authored by Simon Kelley's avatar Simon Kelley

Zero packet buffers before building output, to reduce risk of information leakage.

parent cd2ddb99
...@@ -101,6 +101,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n ...@@ -101,6 +101,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
struct all_addr addr; struct all_addr addr;
struct cname *a; struct cname *a;
/* Clear buffer beyond request to avoid risk of
information disclosure. */
memset(((char *)header) + qlen, 0,
(limit - ((char *)header)) - qlen);
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY ) if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
return 0; return 0;
......
...@@ -1471,6 +1471,7 @@ void log_relay(int family, struct dhcp_relay *relay); ...@@ -1471,6 +1471,7 @@ void log_relay(int family, struct dhcp_relay *relay);
/* outpacket.c */ /* outpacket.c */
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
void end_opt6(int container); void end_opt6(int container);
void reset_counter(void);
int save_counter(int newval); int save_counter(int newval);
void *expand(size_t headroom); void *expand(size_t headroom);
int new_opt6(int opt); int new_opt6(int opt);
......
...@@ -29,9 +29,19 @@ void end_opt6(int container) ...@@ -29,9 +29,19 @@ void end_opt6(int container)
PUTSHORT(len, p); PUTSHORT(len, p);
} }
void reset_counter(void)
{
/* Clear out buffer when starting from begining */
if (daemon->outpacket.iov_base)
memset(daemon->outpacket.iov_base, 0, daemon->outpacket.iov_len);
save_counter(0);
}
int save_counter(int newval) int save_counter(int newval)
{ {
int ret = outpacket_counter; int ret = outpacket_counter;
if (newval != -1) if (newval != -1)
outpacket_counter = newval; outpacket_counter = newval;
......
...@@ -261,7 +261,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad ...@@ -261,7 +261,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
parm.adv_interval = calc_interval(ra_param); parm.adv_interval = calc_interval(ra_param);
parm.prio = calc_prio(ra_param); parm.prio = calc_prio(ra_param);
save_counter(0); reset_counter();
if (!(ra = expand(sizeof(struct ra_packet)))) if (!(ra = expand(sizeof(struct ra_packet))))
return; return;
......
...@@ -1210,6 +1210,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, ...@@ -1210,6 +1210,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
struct mx_srv_record *rec; struct mx_srv_record *rec;
size_t len; size_t len;
/* Clear buffer beyond request to avoid risk of
information disclosure. */
memset(((char *)header) + qlen, 0,
(limit - ((char *)header)) - qlen);
if (ntohs(header->ancount) != 0 || if (ntohs(header->ancount) != 0 ||
ntohs(header->nscount) != 0 || ntohs(header->nscount) != 0 ||
ntohs(header->qdcount) == 0 || ntohs(header->qdcount) == 0 ||
......
...@@ -89,7 +89,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if ...@@ -89,7 +89,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
vendor->netid.next = &vendor->netid; vendor->netid.next = &vendor->netid;
save_counter(0); reset_counter();
state.context = context; state.context = context;
state.interface = interface; state.interface = interface;
state.iface_name = iface_name; state.iface_name = iface_name;
...@@ -2084,7 +2084,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, ...@@ -2084,7 +2084,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
if (hopcount > 32) if (hopcount > 32)
return; return;
save_counter(0); reset_counter();
if ((header = put_opt6(NULL, 34))) if ((header = put_opt6(NULL, 34)))
{ {
...@@ -2161,7 +2161,7 @@ unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival ...@@ -2161,7 +2161,7 @@ unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival
(!relay->interface || wildcard_match(relay->interface, arrival_interface))) (!relay->interface || wildcard_match(relay->interface, arrival_interface)))
break; break;
save_counter(0); reset_counter();
if (relay) if (relay)
{ {
......
...@@ -146,7 +146,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases) ...@@ -146,7 +146,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
struct ping_packet *ping; struct ping_packet *ping;
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
save_counter(0); reset_counter();
if (!(ping = expand(sizeof(struct ping_packet)))) if (!(ping = expand(sizeof(struct ping_packet))))
continue; continue;
......
...@@ -662,6 +662,7 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file) ...@@ -662,6 +662,7 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
ssize_t len, ret = 4; ssize_t len, ret = 4;
char *errstr = strerror(errno); char *errstr = strerror(errno);
memset(packet, 0, daemon->packet_buff_sz);
sanitise(file); sanitise(file);
mess->op = htons(OP_ERR); mess->op = htons(OP_ERR);
...@@ -684,6 +685,8 @@ static ssize_t tftp_err_oops(char *packet, char *file) ...@@ -684,6 +685,8 @@ static ssize_t tftp_err_oops(char *packet, char *file)
/* return -1 for error, zero for done. */ /* return -1 for error, zero for done. */
static ssize_t get_block(char *packet, struct tftp_transfer *transfer) static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
{ {
memset(packet, 0, daemon->packet_buff_sz);
if (transfer->block == 0) if (transfer->block == 0)
{ {
/* send OACK */ /* send OACK */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment