]>
Commit | Line | Data |
---|---|---|
c3afb9c6 MF |
1 | From fa78573778cb23337f67f5d0c9de723169919047 Mon Sep 17 00:00:00 2001 |
2 | From: Simon Kelley <simon@thekelleys.org.uk> | |
3 | Date: Fri, 22 Jul 2016 20:56:01 +0100 | |
4 | Subject: [PATCH] Zero packet buffers before building output, to reduce risk | |
5 | of information leakage. | |
6 | ||
7 | --- | |
8 | src/auth.c | 5 +++++ | |
9 | src/dnsmasq.h | 1 + | |
10 | src/outpacket.c | 10 ++++++++++ | |
11 | src/radv.c | 2 +- | |
12 | src/rfc1035.c | 5 +++++ | |
13 | src/rfc3315.c | 6 +++--- | |
14 | src/slaac.c | 2 +- | |
15 | src/tftp.c | 5 ++++- | |
16 | 8 files changed, 30 insertions(+), 6 deletions(-) | |
17 | ||
18 | diff --git a/src/auth.c b/src/auth.c | |
19 | index 198572d..3c5c37f 100644 | |
20 | --- a/src/auth.c | |
21 | +++ b/src/auth.c | |
22 | @@ -101,6 +101,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n | |
23 | struct all_addr addr; | |
24 | struct cname *a; | |
25 | ||
26 | + /* Clear buffer beyond request to avoid risk of | |
27 | + information disclosure. */ | |
28 | + memset(((char *)header) + qlen, 0, | |
29 | + (limit - ((char *)header)) - qlen); | |
30 | + | |
31 | if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY ) | |
32 | return 0; | |
33 | ||
34 | diff --git a/src/dnsmasq.h b/src/dnsmasq.h | |
35 | index be27ae0..2bda5d0 100644 | |
36 | --- a/src/dnsmasq.h | |
37 | +++ b/src/dnsmasq.h | |
38 | @@ -1471,6 +1471,7 @@ void log_relay(int family, struct dhcp_relay *relay); | |
39 | /* outpacket.c */ | |
40 | #ifdef HAVE_DHCP6 | |
41 | void end_opt6(int container); | |
42 | +void reset_counter(void); | |
43 | int save_counter(int newval); | |
44 | void *expand(size_t headroom); | |
45 | int new_opt6(int opt); | |
46 | diff --git a/src/outpacket.c b/src/outpacket.c | |
47 | index a414efa..2caacd9 100644 | |
48 | --- a/src/outpacket.c | |
49 | +++ b/src/outpacket.c | |
50 | @@ -29,9 +29,19 @@ void end_opt6(int container) | |
51 | PUTSHORT(len, p); | |
52 | } | |
53 | ||
54 | +void reset_counter(void) | |
55 | +{ | |
56 | + /* Clear out buffer when starting from begining */ | |
57 | + if (daemon->outpacket.iov_base) | |
58 | + memset(daemon->outpacket.iov_base, 0, daemon->outpacket.iov_len); | |
59 | + | |
60 | + save_counter(0); | |
61 | +} | |
62 | + | |
63 | int save_counter(int newval) | |
64 | { | |
65 | int ret = outpacket_counter; | |
66 | + | |
67 | if (newval != -1) | |
68 | outpacket_counter = newval; | |
69 | ||
70 | diff --git a/src/radv.c b/src/radv.c | |
71 | index faa0f6d..39c9217 100644 | |
72 | --- a/src/radv.c | |
73 | +++ b/src/radv.c | |
74 | @@ -261,7 +261,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad | |
75 | parm.adv_interval = calc_interval(ra_param); | |
76 | parm.prio = calc_prio(ra_param); | |
77 | ||
78 | - save_counter(0); | |
79 | + reset_counter(); | |
80 | ||
81 | if (!(ra = expand(sizeof(struct ra_packet)))) | |
82 | return; | |
83 | diff --git a/src/rfc1035.c b/src/rfc1035.c | |
84 | index 24d08c1..9e730a9 100644 | |
85 | --- a/src/rfc1035.c | |
86 | +++ b/src/rfc1035.c | |
87 | @@ -1209,6 +1209,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
88 | int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1; | |
89 | struct mx_srv_record *rec; | |
90 | size_t len; | |
91 | + | |
92 | + /* Clear buffer beyond request to avoid risk of | |
93 | + information disclosure. */ | |
94 | + memset(((char *)header) + qlen, 0, | |
95 | + (limit - ((char *)header)) - qlen); | |
96 | ||
97 | if (ntohs(header->ancount) != 0 || | |
98 | ntohs(header->nscount) != 0 || | |
99 | diff --git a/src/rfc3315.c b/src/rfc3315.c | |
100 | index 3f4d69c..e1271a1 100644 | |
101 | --- a/src/rfc3315.c | |
102 | +++ b/src/rfc3315.c | |
103 | @@ -89,7 +89,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if | |
104 | for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) | |
105 | vendor->netid.next = &vendor->netid; | |
106 | ||
107 | - save_counter(0); | |
108 | + reset_counter(); | |
109 | state.context = context; | |
110 | state.interface = interface; | |
111 | state.iface_name = iface_name; | |
112 | @@ -2084,7 +2084,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, | |
113 | if (hopcount > 32) | |
114 | return; | |
115 | ||
116 | - save_counter(0); | |
117 | + reset_counter(); | |
118 | ||
119 | if ((header = put_opt6(NULL, 34))) | |
120 | { | |
121 | @@ -2161,7 +2161,7 @@ unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival | |
122 | (!relay->interface || wildcard_match(relay->interface, arrival_interface))) | |
123 | break; | |
124 | ||
125 | - save_counter(0); | |
126 | + reset_counter(); | |
127 | ||
128 | if (relay) | |
129 | { | |
130 | diff --git a/src/slaac.c b/src/slaac.c | |
131 | index 07b8ba4..bd6c9b4 100644 | |
132 | --- a/src/slaac.c | |
133 | +++ b/src/slaac.c | |
134 | @@ -146,7 +146,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases) | |
135 | struct ping_packet *ping; | |
136 | struct sockaddr_in6 addr; | |
137 | ||
138 | - save_counter(0); | |
139 | + reset_counter(); | |
140 | ||
141 | if (!(ping = expand(sizeof(struct ping_packet)))) | |
142 | continue; | |
143 | diff --git a/src/tftp.c b/src/tftp.c | |
144 | index 3e1b5c5..618c406 100644 | |
145 | --- a/src/tftp.c | |
146 | +++ b/src/tftp.c | |
147 | @@ -662,8 +662,9 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file) | |
148 | ssize_t len, ret = 4; | |
149 | char *errstr = strerror(errno); | |
150 | ||
151 | + memset(packet, 0, daemon->packet_buff_sz); | |
152 | sanitise(file); | |
153 | - | |
154 | + | |
155 | mess->op = htons(OP_ERR); | |
156 | mess->err = htons(err); | |
157 | len = snprintf(mess->message, MAXMESSAGE, message, file, errstr); | |
158 | @@ -684,6 +685,8 @@ static ssize_t tftp_err_oops(char *packet, char *file) | |
159 | /* return -1 for error, zero for done. */ | |
160 | static ssize_t get_block(char *packet, struct tftp_transfer *transfer) | |
161 | { | |
162 | + memset(packet, 0, daemon->packet_buff_sz); | |
163 | + | |
164 | if (transfer->block == 0) | |
165 | { | |
166 | /* send OACK */ | |
167 | -- | |
168 | 1.7.10.4 | |
169 |