Subversion Repositories

?revision_form?Rev ?revision_input??revision_submit??revision_endform?

Rev 29 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 29 Rev 36
1
#! /bin/sh /usr/share/dpatch/dpatch-run
1
#! /bin/sh /usr/share/dpatch/dpatch-run
2
## 50_permanent_include_errors.dpatch by Shevek <shevek@anarres.org>, edited by Magnus Holmgren
2
## 50_permanent_include_errors.dpatch by Shevek <shevek@anarres.org>, edited by Magnus Holmgren
3
##
3
##
4
## DP: Fix CVE-2008-2469 - buffer overflows handling DNS responses.
4
## DP: Fix CVE-2008-2469 - buffer overflows handling DNS responses.
5
5
6
@DPATCH@
6
@DPATCH@
7
7
8
--- libspf2/src/libspf2/spf_dns_resolv.c.orig	2008-09-20 19:36:57.000000000 +0200
8
--- libspf2/src/libspf2/spf_dns_resolv.c.orig	2008-09-20 19:36:57.000000000 +0200
9
+++ libspf2/src/libspf2/spf_dns_resolv.c	2008-09-20 19:39:08.000000000 +0200
9
+++ libspf2/src/libspf2/spf_dns_resolv.c	2008-09-20 19:39:08.000000000 +0200
10
@@ -110,7 +110,8 @@
10
@@ -110,7 +110,8 @@
11
     int		nrec;
11
     int		nrec;
12
     int		cnt;
12
     int		cnt;
13
 
13
 
14
-    u_char	response[2048];
14
-    u_char	response[2048];
15
+	u_char	*responsebuf;
15
+	u_char	*responsebuf;
16
+	size_t	 responselen;
16
+	size_t	 responselen;
17
 
17
 
18
     int		dns_len;
18
     int		dns_len;
19
 
19
 
20
@@ -127,11 +128,13 @@
20
@@ -127,11 +128,13 @@
21
     char	name_buf[ NS_MAXDNAME ];
21
     char	name_buf[ NS_MAXDNAME ];
22
     int		prio;
22
     int		prio;
23
 
23
 
24
-    int		rdlen;
24
-    int		rdlen;
25
-    const u_char	*rdata, *rdata_end;
25
-    const u_char	*rdata, *rdata_end;
26
+	size_t	rdlen;
26
+	size_t	rdlen;
27
+	const u_char	*rdata;
27
+	const u_char	*rdata;
28
 
28
 
29
+#if HAVE_DECL_RES_NINIT
29
+#if HAVE_DECL_RES_NINIT
30
 	void				*res_spec;
30
 	void				*res_spec;
31
 	struct __res_state	*res_state;
31
 	struct __res_state	*res_state;
32
+#endif
32
+#endif
33
 
33
 
34
 	SPF_ASSERT_NOTNULL(spf_dns_server);
34
 	SPF_ASSERT_NOTNULL(spf_dns_server);
35
 
35
 
36
@@ -140,10 +143,12 @@
36
@@ -140,10 +143,12 @@
37
 	SPF_ASSERT_NOTNULL(spfhook);
37
 	SPF_ASSERT_NOTNULL(spfhook);
38
 #endif
38
 #endif
39
 
39
 
40
+#if HAVE_DECL_RES_NINIT
40
+#if HAVE_DECL_RES_NINIT
41
 	res_spec = pthread_getspecific(res_state_key);
41
 	res_spec = pthread_getspecific(res_state_key);
42
 	if (res_spec == NULL) {
42
 	if (res_spec == NULL) {
43
 		res_state = (struct __res_state *)
43
 		res_state = (struct __res_state *)
44
 						malloc(sizeof(struct __res_state));
44
 						malloc(sizeof(struct __res_state));
45
+		memset(res_state, 0, sizeof(struct __res_state));
45
+		memset(res_state, 0, sizeof(struct __res_state));
46
 		if (res_ninit(res_state) != 0) {
46
 		if (res_ninit(res_state) != 0) {
47
 			SPF_error("Failed to call res_ninit()");
47
 			SPF_error("Failed to call res_ninit()");
48
 		}
48
 		}
49
@@ -152,20 +157,45 @@
49
@@ -152,20 +157,45 @@
50
 	else {
50
 	else {
51
 		res_state = (struct __res_state *)res_spec;
51
 		res_state = (struct __res_state *)res_spec;
52
 	}
52
 	}
53
+#endif
53
+#endif
54
+
54
+
55
+	responselen = 2048;
55
+	responselen = 2048;
56
+	responsebuf = (u_char *)malloc(responselen);
56
+	responsebuf = (u_char *)malloc(responselen);
57
+	memset(responsebuf, 0, responselen);
57
+	memset(responsebuf, 0, responselen);
58
+
58
+
59
+	/*
59
+	/*
60
+	 * Retry the lookup until our response buffer is big enough.
60
+	 * Retry the lookup until our response buffer is big enough.
61
+	 *
61
+	 *
62
+	 * This loop repeats until either we fail a lookup or we succeed.
62
+	 * This loop repeats until either we fail a lookup or we succeed.
63
+	 * The size of the response buffer is monotonic increasing, so eventually we
63
+	 * The size of the response buffer is monotonic increasing, so eventually we
64
+	 * must either succeed, or we try to malloc more RAM than we can.
64
+	 * must either succeed, or we try to malloc more RAM than we can.
65
+	 *
65
+	 *
66
+	 * The Linux man pages do not describe res_nquery adequately. Solaris says:
66
+	 * The Linux man pages do not describe res_nquery adequately. Solaris says:
67
+	 *
67
+	 *
68
+	 * The res_nquery() and res_query() routines return a length that may be bigger
68
+	 * The res_nquery() and res_query() routines return a length that may be bigger
69
+	 * than anslen. In that case, retry the query with a larger buf. The answer to the
69
+	 * than anslen. In that case, retry the query with a larger buf. The answer to the
70
+	 * second query may be larger still], so it is recommended that you supply a buf
70
+	 * second query may be larger still], so it is recommended that you supply a buf
71
+	 * larger than the answer returned by the previous query. answer must be large
71
+	 * larger than the answer returned by the previous query. answer must be large
72
+	 * enough to receive a maximum UDP response from the server or parts of the answer
72
+	 * enough to receive a maximum UDP response from the server or parts of the answer
73
+	 * will be silently discarded. The default maximum UDP response size is 512 bytes.
73
+	 * will be silently discarded. The default maximum UDP response size is 512 bytes.
74
+	 */
74
+	 */
75
+	for (;;) {
75
+	for (;;) {
76
 
76
 
77
     /*
77
     /*
78
      * try resolving the name
78
      * try resolving the name
79
      */
79
      */
80
 #if HAVE_DECL_RES_NINIT
80
 #if HAVE_DECL_RES_NINIT
81
 	dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
81
 	dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
82
-			 response, sizeof(response));
82
-			 response, sizeof(response));
83
+				 responsebuf, responselen);
83
+				 responsebuf, responselen);
84
 #else
84
 #else
85
     dns_len = res_query(domain, ns_c_in, rr_type,
85
     dns_len = res_query(domain, ns_c_in, rr_type,
86
-			 response, sizeof(response));
86
-			 response, sizeof(response));
87
+				 responsebuf, responselen);
87
+				 responsebuf, responselen);
88
 #endif
88
 #endif
89
 
89
 
90
 	if ( dns_len < 0 ) {
90
 	if ( dns_len < 0 ) {
91
+			/* We failed to perform a lookup. */
91
+			/* We failed to perform a lookup. */
92
 		/* This block returns unconditionally. */
92
 		/* This block returns unconditionally. */
93
+			free(responsebuf);
93
+			free(responsebuf);
94
 		if ( spf_dns_server->debug )
94
 		if ( spf_dns_server->debug )
95
 			SPF_debugf( "query failed: err = %d  %s (%d): %s",
95
 			SPF_debugf( "query failed: err = %d  %s (%d): %s",
96
 				dns_len, hstrerror( SPF_h_errno ), SPF_h_errno,
96
 				dns_len, hstrerror( SPF_h_errno ), SPF_h_errno,
97
@@ -178,6 +208,25 @@
97
@@ -178,6 +208,25 @@
98
 		return SPF_dns_rr_new_init(spf_dns_server,
98
 		return SPF_dns_rr_new_init(spf_dns_server,
99
 						domain, rr_type, 0, SPF_h_errno);
99
 						domain, rr_type, 0, SPF_h_errno);
100
 	}
100
 	}
101
+		else if (dns_len > responselen) {
101
+		else if (dns_len > responselen) {
102
+			/* We managed a lookup but our buffer was too small. */
102
+			/* We managed a lookup but our buffer was too small. */
103
+			responselen = dns_len + (dns_len >> 1);
103
+			responselen = dns_len + (dns_len >> 1);
104
+#if 0
104
+#if 0
105
+			/* Sanity-trap - we should never hit this. */
105
+			/* Sanity-trap - we should never hit this. */
106
+			if (responselen > 1048576) {	/* One megabyte. */
106
+			if (responselen > 1048576) {	/* One megabyte. */
107
+				free(responsebuf);
107
+				free(responsebuf);
108
+				return SPF_dns_rr_new_init(spf_dns_server,
108
+				return SPF_dns_rr_new_init(spf_dns_server,
109
+								domain, rr_type, 0, SPF_h_errno);
109
+								domain, rr_type, 0, SPF_h_errno);
110
+			}
110
+			}
111
+#endif
111
+#endif
112
+			responsebuf = realloc(responsebuf, responselen);
112
+			responsebuf = realloc(responsebuf, responselen);
113
+		}
113
+		}
114
+		else {
114
+		else {
115
+			/* We managed a lookup, and our buffer was large enough. */
115
+			/* We managed a lookup, and our buffer was large enough. */
116
+			responselen = dns_len;
116
+			responselen = dns_len;
117
+			break;
117
+			break;
118
+		}
118
+		}
119
+	}
119
+	}
120
 
120
 
121
     /*
121
     /*
122
      * initialize stuff
122
      * initialize stuff
123
@@ -185,12 +234,13 @@
123
@@ -185,12 +234,13 @@
124
 	spfrr = SPF_dns_rr_new_init(spf_dns_server,
124
 	spfrr = SPF_dns_rr_new_init(spf_dns_server,
125
 					domain, rr_type, 0, NETDB_SUCCESS);
125
 					domain, rr_type, 0, NETDB_SUCCESS);
126
 
126
 
127
-    err = ns_initparse( response, dns_len, &ns_handle );
127
-    err = ns_initparse( response, dns_len, &ns_handle );
128
+	err = ns_initparse(responsebuf, responselen, &ns_handle);
128
+	err = ns_initparse(responsebuf, responselen, &ns_handle);
129
 
129
 
130
 	if ( err < 0 ) {	/* 0 or -1 */
130
 	if ( err < 0 ) {	/* 0 or -1 */
131
 		if ( spf_dns_server->debug )
131
 		if ( spf_dns_server->debug )
132
 			SPF_debugf( "ns_initparse failed: err = %d  %s (%d)",
132
 			SPF_debugf( "ns_initparse failed: err = %d  %s (%d)",
133
 				err, strerror( errno ), errno );
133
 				err, strerror( errno ), errno );
134
+		free(responsebuf);
134
+		free(responsebuf);
135
 		return spfrr;
135
 		return spfrr;
136
     }
136
     }
137
 
137
 
138
@@ -226,6 +276,7 @@
138
@@ -226,6 +276,7 @@
139
 			if ( spf_dns_server->debug > 1 )
139
 			if ( spf_dns_server->debug > 1 )
140
 				SPF_debugf( "ns_parserr failed: err = %d  %s (%d)",
140
 				SPF_debugf( "ns_parserr failed: err = %d  %s (%d)",
141
 					err, strerror( errno ), errno );
141
 					err, strerror( errno ), errno );
142
+				free(responsebuf);
142
+				free(responsebuf);
143
 			return spfrr;
143
 			return spfrr;
144
 			}
144
 			}
145
 
145
 
146
@@ -257,8 +308,8 @@
146
@@ -257,8 +308,8 @@
147
 				break;
147
 				break;
148
 
148
 
149
 			case ns_t_ns:
149
 			case ns_t_ns:
150
-				err = ns_name_uncompress( response,
150
-				err = ns_name_uncompress( response,
151
-							  response + sizeof( response ),
151
-							  response + sizeof( response ),
152
+				err = ns_name_uncompress( responsebuf,
152
+				err = ns_name_uncompress( responsebuf,
153
+							  responsebuf + responselen,
153
+							  responsebuf + responselen,
154
 							  rdata,
154
 							  rdata,
155
 							  name_buf, sizeof( name_buf ) );
155
 							  name_buf, sizeof( name_buf ) );
156
 				if ( err < 0 )		/* 0 or -1 */
156
 				if ( err < 0 )		/* 0 or -1 */
157
@@ -271,8 +322,8 @@
157
@@ -271,8 +322,8 @@
158
 				break;
158
 				break;
159
 
159
 
160
 			case ns_t_cname:
160
 			case ns_t_cname:
161
-				err = ns_name_uncompress( response,
161
-				err = ns_name_uncompress( response,
162
-							  response + sizeof( response ),
162
-							  response + sizeof( response ),
163
+				err = ns_name_uncompress( responsebuf,
163
+				err = ns_name_uncompress( responsebuf,
164
+							  responsebuf + responselen,
164
+							  responsebuf + responselen,
165
 							  rdata,
165
 							  rdata,
166
 							  name_buf, sizeof( name_buf ) );
166
 							  name_buf, sizeof( name_buf ) );
167
 				if ( err < 0 )		/* 0 or -1 */
167
 				if ( err < 0 )		/* 0 or -1 */
168
@@ -286,8 +337,8 @@
168
@@ -286,8 +337,8 @@
169
 
169
 
170
 			case ns_t_mx:
170
 			case ns_t_mx:
171
 				prio = ns_get16( rdata );
171
 				prio = ns_get16( rdata );
172
-				err = ns_name_uncompress( response,
172
-				err = ns_name_uncompress( response,
173
-							  response + sizeof( response ),
173
-							  response + sizeof( response ),
174
+				err = ns_name_uncompress( responsebuf,
174
+				err = ns_name_uncompress( responsebuf,
175
+							  responsebuf + sizeof( responselen ),
175
+							  responsebuf + sizeof( responselen ),
176
 							  rdata + NS_INT16SZ,
176
 							  rdata + NS_INT16SZ,
177
 							  name_buf, sizeof( name_buf ) );
177
 							  name_buf, sizeof( name_buf ) );
178
 				if ( err < 0 )		/* 0 or -1 */
178
 				if ( err < 0 )		/* 0 or -1 */
179
@@ -300,14 +351,13 @@
179
@@ -300,14 +351,13 @@
180
 				break;
180
 				break;
181
 
181
 
182
 			case ns_t_txt:
182
 			case ns_t_txt:
183
-				rdata_end = rdata + rdlen;
183
-				rdata_end = rdata + rdlen;
184
 				SPF_debugf( "TXT: (%d) \"%.*s\"",
184
 				SPF_debugf( "TXT: (%d) \"%.*s\"",
185
 					rdlen, rdlen-1, rdata+1 );
185
 					rdlen, rdlen-1, rdata+1 );
186
 				break;
186
 				break;
187
 
187
 
188
 			case ns_t_ptr:
188
 			case ns_t_ptr:
189
-				err = ns_name_uncompress( response,
189
-				err = ns_name_uncompress( response,
190
-							  response + sizeof( response ),
190
-							  response + sizeof( response ),
191
+				err = ns_name_uncompress( responsebuf,
191
+				err = ns_name_uncompress( responsebuf,
192
+							  responsebuf + responselen,
192
+							  responsebuf + responselen,
193
 							  rdata,
193
 							  rdata,
194
 							  name_buf, sizeof( name_buf ) );
194
 							  name_buf, sizeof( name_buf ) );
195
 				if ( err < 0 )		/* 0 or -1 */
195
 				if ( err < 0 )		/* 0 or -1 */
196
@@ -341,18 +391,21 @@
196
@@ -341,18 +391,21 @@
197
 			{
197
 			{
198
 			case ns_t_a:
198
 			case ns_t_a:
199
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
199
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
200
-							sizeof( spfrr->rr[cnt]->a ) ) != SPF_E_SUCCESS )
200
-							sizeof( spfrr->rr[cnt]->a ) ) != SPF_E_SUCCESS )
201
+								sizeof(spfrr->rr[cnt]->a)) != SPF_E_SUCCESS) {
201
+								sizeof(spfrr->rr[cnt]->a)) != SPF_E_SUCCESS) {
202
+						free(responsebuf);
202
+						free(responsebuf);
203
 				return spfrr;
203
 				return spfrr;
204
-			memmove( &spfrr->rr[cnt]->a, rdata, sizeof( spfrr->rr[cnt]->a ) );
204
-			memmove( &spfrr->rr[cnt]->a, rdata, sizeof( spfrr->rr[cnt]->a ) );
205
+					}
205
+					}
206
+					memcpy(&spfrr->rr[cnt]->a, rdata, sizeof(spfrr->rr[cnt]->a));
206
+					memcpy(&spfrr->rr[cnt]->a, rdata, sizeof(spfrr->rr[cnt]->a));
207
 			cnt++;
207
 			cnt++;
208
 			break;
208
 			break;
209
 
209
 
210
 			case ns_t_aaaa:
210
 			case ns_t_aaaa:
211
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
211
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
212
-							sizeof( spfrr->rr[cnt]->aaaa ) ) != SPF_E_SUCCESS )
212
-							sizeof( spfrr->rr[cnt]->aaaa ) ) != SPF_E_SUCCESS )
213
+								sizeof(spfrr->rr[cnt]->aaaa)) != SPF_E_SUCCESS) {
213
+								sizeof(spfrr->rr[cnt]->aaaa)) != SPF_E_SUCCESS) {
214
+						free(responsebuf);
214
+						free(responsebuf);
215
 				return spfrr;
215
 				return spfrr;
216
-			memmove( &spfrr->rr[cnt]->aaaa, rdata, sizeof( spfrr->rr[cnt]->aaaa ) );
216
-			memmove( &spfrr->rr[cnt]->aaaa, rdata, sizeof( spfrr->rr[cnt]->aaaa ) );
217
-
217
-
218
+					}
218
+					}
219
+					memcpy(&spfrr->rr[cnt]->aaaa, rdata, sizeof(spfrr->rr[cnt]->aaaa));
219
+					memcpy(&spfrr->rr[cnt]->aaaa, rdata, sizeof(spfrr->rr[cnt]->aaaa));
220
 			cnt++;
220
 			cnt++;
221
 			break;
221
 			break;
222
 
222
 
223
@@ -364,8 +417,8 @@
223
@@ -364,8 +417,8 @@
224
 			break;
224
 			break;
225
 
225
 
226
 			case ns_t_mx:
226
 			case ns_t_mx:
227
-			err = ns_name_uncompress( response,
227
-			err = ns_name_uncompress( response,
228
-						  response + sizeof( response ),
228
-						  response + sizeof( response ),
229
+					err = ns_name_uncompress(responsebuf,
229
+					err = ns_name_uncompress(responsebuf,
230
+									responsebuf + responselen,
230
+									responsebuf + responselen,
231
 						  rdata + NS_INT16SZ,
231
 						  rdata + NS_INT16SZ,
232
 						  name_buf, sizeof( name_buf ) );
232
 						  name_buf, sizeof( name_buf ) );
233
 			if ( err < 0 )		/* 0 or -1 */
233
 			if ( err < 0 )		/* 0 or -1 */
234
@@ -373,12 +426,15 @@
234
@@ -373,12 +426,15 @@
235
 				if ( spf_dns_server->debug > 1 )
235
 				if ( spf_dns_server->debug > 1 )
236
 				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
236
 				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
237
 					err, strerror( errno ), errno );
237
 					err, strerror( errno ), errno );
238
+						free(responsebuf);
238
+						free(responsebuf);
239
 				return spfrr;
239
 				return spfrr;
240
 			}
240
 			}
241
 
241
 
242
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
242
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
243
-							strlen( name_buf ) + 1 ) != SPF_E_SUCCESS )
243
-							strlen( name_buf ) + 1 ) != SPF_E_SUCCESS )
244
+									strlen(name_buf) + 1 ) != SPF_E_SUCCESS) {
244
+									strlen(name_buf) + 1 ) != SPF_E_SUCCESS) {
245
+						free(responsebuf);
245
+						free(responsebuf);
246
 				return spfrr;
246
 				return spfrr;
247
+					}
247
+					}
248
 			strcpy( spfrr->rr[cnt]->mx, name_buf );
248
 			strcpy( spfrr->rr[cnt]->mx, name_buf );
249
 
249
 
250
 			cnt++;
250
 			cnt++;
251
@@ -390,8 +446,12 @@
251
@@ -390,8 +446,12 @@
252
 				u_char *src, *dst;
252
 				u_char *src, *dst;
253
 				size_t len;
253
 				size_t len;
254
 
254
 
255
-				if ( SPF_dns_rr_buf_realloc( spfrr, cnt, rdlen ) != SPF_E_SUCCESS )
255
-				if ( SPF_dns_rr_buf_realloc( spfrr, cnt, rdlen ) != SPF_E_SUCCESS )
256
+						/* Just rdlen is enough because there is at least one
256
+						/* Just rdlen is enough because there is at least one
257
+						 * length byte. */
257
+						 * length byte. */
258
+						if (SPF_dns_rr_buf_realloc(spfrr, cnt, rdlen) != SPF_E_SUCCESS) {
258
+						if (SPF_dns_rr_buf_realloc(spfrr, cnt, rdlen) != SPF_E_SUCCESS) {
259
+							free(responsebuf);
259
+							free(responsebuf);
260
 				return spfrr;
260
 				return spfrr;
261
+						}
261
+						}
262
 
262
 
263
 				dst = (u_char *)(spfrr->rr[cnt]->txt);
263
 				dst = (u_char *)(spfrr->rr[cnt]->txt);
264
 				len = 0;
264
 				len = 0;
265
@@ -400,15 +460,22 @@
265
@@ -400,15 +460,22 @@
266
 				{
266
 				{
267
 				len = *src;
267
 				len = *src;
268
 				src++;
268
 				src++;
269
+							rdlen--;
269
+							rdlen--;
270
+
270
+
271
+							/* Avoid buffer overrun if len is junk. */
271
+							/* Avoid buffer overrun if len is junk. */
272
+							if (len > rdlen)
272
+							if (len > rdlen)
273
+								len = rdlen;
273
+								len = rdlen;
274
 				memcpy( dst, src, len );
274
 				memcpy( dst, src, len );
275
 				dst += len;
275
 				dst += len;
276
 				src += len;
276
 				src += len;
277
-				rdlen -= len + 1;
277
-				rdlen -= len + 1;
278
+							rdlen -= len;
278
+							rdlen -= len;
279
 				}
279
 				}
280
 				*dst = '\0';
280
 				*dst = '\0';
281
 			} else {
281
 			} else {
282
-				if ( SPF_dns_rr_buf_realloc( spfrr, cnt, 1 ) != SPF_E_SUCCESS )
282
-				if ( SPF_dns_rr_buf_realloc( spfrr, cnt, 1 ) != SPF_E_SUCCESS )
283
+						if (SPF_dns_rr_buf_realloc(spfrr, cnt, 1) != SPF_E_SUCCESS) {
283
+						if (SPF_dns_rr_buf_realloc(spfrr, cnt, 1) != SPF_E_SUCCESS) {
284
+							free(responsebuf);
284
+							free(responsebuf);
285
 				return spfrr;
285
 				return spfrr;
286
+						}
286
+						}
287
 				spfrr->rr[cnt]->txt[0] = '\0';
287
 				spfrr->rr[cnt]->txt[0] = '\0';
288
 			}
288
 			}
289
 
289
 
290
@@ -416,8 +483,8 @@
290
@@ -416,8 +483,8 @@
291
 			break;
291
 			break;
292
 
292
 
293
 			case ns_t_ptr:
293
 			case ns_t_ptr:
294
-			err = ns_name_uncompress( response,
294
-			err = ns_name_uncompress( response,
295
-						  response + sizeof( response ),
295
-						  response + sizeof( response ),
296
+					err = ns_name_uncompress(responsebuf,
296
+					err = ns_name_uncompress(responsebuf,
297
+									responsebuf + responselen,
297
+									responsebuf + responselen,
298
 						  rdata,
298
 						  rdata,
299
 						  name_buf, sizeof( name_buf ) );
299
 						  name_buf, sizeof( name_buf ) );
300
 			if ( err < 0 )		/* 0 or -1 */
300
 			if ( err < 0 )		/* 0 or -1 */
301
@@ -425,12 +492,15 @@
301
@@ -425,12 +492,15 @@
302
 				if ( spf_dns_server->debug > 1 )
302
 				if ( spf_dns_server->debug > 1 )
303
 				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
303
 				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
304
 					err, strerror( errno ), errno );
304
 					err, strerror( errno ), errno );
305
+						free(responsebuf);
305
+						free(responsebuf);
306
 				return spfrr;
306
 				return spfrr;
307
 			}
307
 			}
308
 
308
 
309
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
309
 			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
310
-							strlen( name_buf ) + 1 ) != SPF_E_SUCCESS )
310
-							strlen( name_buf ) + 1 ) != SPF_E_SUCCESS )
311
+									strlen(name_buf) + 1) != SPF_E_SUCCESS) {
311
+									strlen(name_buf) + 1) != SPF_E_SUCCESS) {
312
+						free(responsebuf);
312
+						free(responsebuf);
313
 				return spfrr;
313
 				return spfrr;
314
+					}
314
+					}
315
 			strcpy( spfrr->rr[cnt]->ptr, name_buf );
315
 			strcpy( spfrr->rr[cnt]->ptr, name_buf );
316
 
316
 
317
 			cnt++;
317
 			cnt++;
318
@@ -447,6 +517,7 @@
318
@@ -447,6 +517,7 @@
319
     if ( spfrr->num_rr == 0 )
319
     if ( spfrr->num_rr == 0 )
320
 		spfrr->herrno = NO_DATA;
320
 		spfrr->herrno = NO_DATA;
321
 
321
 
322
+	free(responsebuf);
322
+	free(responsebuf);
323
     return spfrr;
323
     return spfrr;
324
 }
324
 }
325
 
325