Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 242254
Collapse All | Expand All

(-)libspf2/src/libspf2/spf_dns_resolv.c.orig (-29 / +100 lines)
Lines 110-116 Link Here
110
    int		nrec;
110
    int		nrec;
111
    int		cnt;
111
    int		cnt;
112
112
113
    u_char	response[2048];
113
	u_char	*responsebuf;
114
	size_t	 responselen;
114
115
115
    int		dns_len;
116
    int		dns_len;
116
117
Lines 127-137 Link Here
127
    char	name_buf[ NS_MAXDNAME ];
128
    char	name_buf[ NS_MAXDNAME ];
128
    int		prio;
129
    int		prio;
129
130
130
    int		rdlen;
131
	size_t	rdlen;
131
    const u_char	*rdata, *rdata_end;
132
	const u_char	*rdata;
132
133
134
#if HAVE_DECL_RES_NINIT
133
	void				*res_spec;
135
	void				*res_spec;
134
	struct __res_state	*res_state;
136
	struct __res_state	*res_state;
137
#endif
135
138
136
	SPF_ASSERT_NOTNULL(spf_dns_server);
139
	SPF_ASSERT_NOTNULL(spf_dns_server);
137
140
Lines 140-149 Link Here
140
	SPF_ASSERT_NOTNULL(spfhook);
143
	SPF_ASSERT_NOTNULL(spfhook);
141
#endif
144
#endif
142
145
146
#if HAVE_DECL_RES_NINIT
143
	res_spec = pthread_getspecific(res_state_key);
147
	res_spec = pthread_getspecific(res_state_key);
144
	if (res_spec == NULL) {
148
	if (res_spec == NULL) {
145
		res_state = (struct __res_state *)
149
		res_state = (struct __res_state *)
146
						malloc(sizeof(struct __res_state));
150
						malloc(sizeof(struct __res_state));
151
		memset(res_state, 0, sizeof(struct __res_state));
147
		if (res_ninit(res_state) != 0) {
152
		if (res_ninit(res_state) != 0) {
148
			SPF_error("Failed to call res_ninit()");
153
			SPF_error("Failed to call res_ninit()");
149
		}
154
		}
Lines 152-171 Link Here
152
	else {
157
	else {
153
		res_state = (struct __res_state *)res_spec;
158
		res_state = (struct __res_state *)res_spec;
154
	}
159
	}
160
#endif
161
162
	responselen = 2048;
163
	responsebuf = (u_char *)malloc(responselen);
164
	memset(responsebuf, 0, responselen);
165
166
	/*
167
	 * Retry the lookup until our response buffer is big enough.
168
	 *
169
	 * This loop repeats until either we fail a lookup or we succeed.
170
	 * The size of the response buffer is monotonic increasing, so eventually we
171
	 * must either succeed, or we try to malloc more RAM than we can.
172
	 *
173
	 * The Linux man pages do not describe res_nquery adequately. Solaris says:
174
	 *
175
	 * The res_nquery() and res_query() routines return a length that may be bigger
176
	 * than anslen. In that case, retry the query with a larger buf. The answer to the
177
	 * second query may be larger still], so it is recommended that you supply a buf
178
	 * larger than the answer returned by the previous query. answer must be large
179
	 * enough to receive a maximum UDP response from the server or parts of the answer
180
	 * will be silently discarded. The default maximum UDP response size is 512 bytes.
181
	 */
182
	for (;;) {
155
183
156
    /*
184
    /*
157
     * try resolving the name
185
     * try resolving the name
158
     */
186
     */
159
#if HAVE_DECL_RES_NINIT
187
#if HAVE_DECL_RES_NINIT
160
	dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
188
	dns_len = res_nquery(res_state, domain, ns_c_in, rr_type,
161
			 response, sizeof(response));
189
				 responsebuf, responselen);
162
#else
190
#else
163
    dns_len = res_query(domain, ns_c_in, rr_type,
191
    dns_len = res_query(domain, ns_c_in, rr_type,
164
			 response, sizeof(response));
192
				 responsebuf, responselen);
165
#endif
193
#endif
166
194
167
	if ( dns_len < 0 ) {
195
	if ( dns_len < 0 ) {
196
			/* We failed to perform a lookup. */
168
		/* This block returns unconditionally. */
197
		/* This block returns unconditionally. */
198
			free(responsebuf);
169
		if ( spf_dns_server->debug )
199
		if ( spf_dns_server->debug )
170
			SPF_debugf( "query failed: err = %d  %s (%d): %s",
200
			SPF_debugf( "query failed: err = %d  %s (%d): %s",
171
				dns_len, hstrerror( SPF_h_errno ), SPF_h_errno,
201
				dns_len, hstrerror( SPF_h_errno ), SPF_h_errno,
Lines 178-183 Link Here
178
		return SPF_dns_rr_new_init(spf_dns_server,
208
		return SPF_dns_rr_new_init(spf_dns_server,
179
						domain, rr_type, 0, SPF_h_errno);
209
						domain, rr_type, 0, SPF_h_errno);
180
	}
210
	}
211
		else if (dns_len > responselen) {
212
			/* We managed a lookup but our buffer was too small. */
213
			responselen = dns_len + (dns_len >> 1);
214
#if 0
215
			/* Sanity-trap - we should never hit this. */
216
			if (responselen > 1048576) {	/* One megabyte. */
217
				free(responsebuf);
218
				return SPF_dns_rr_new_init(spf_dns_server,
219
								domain, rr_type, 0, SPF_h_errno);
220
			}
221
#endif
222
			responsebuf = realloc(responsebuf, responselen);
223
		}
224
		else {
225
			/* We managed a lookup, and our buffer was large enough. */
226
			responselen = dns_len;
227
			break;
228
		}
229
	}
181
230
182
    /*
231
    /*
183
     * initialize stuff
232
     * initialize stuff
Lines 185-196 Link Here
185
	spfrr = SPF_dns_rr_new_init(spf_dns_server,
234
	spfrr = SPF_dns_rr_new_init(spf_dns_server,
186
					domain, rr_type, 0, NETDB_SUCCESS);
235
					domain, rr_type, 0, NETDB_SUCCESS);
187
236
188
    err = ns_initparse( response, dns_len, &ns_handle );
237
	err = ns_initparse(responsebuf, responselen, &ns_handle);
189
238
190
	if ( err < 0 ) {	/* 0 or -1 */
239
	if ( err < 0 ) {	/* 0 or -1 */
191
		if ( spf_dns_server->debug )
240
		if ( spf_dns_server->debug )
192
			SPF_debugf( "ns_initparse failed: err = %d  %s (%d)",
241
			SPF_debugf( "ns_initparse failed: err = %d  %s (%d)",
193
				err, strerror( errno ), errno );
242
				err, strerror( errno ), errno );
243
		free(responsebuf);
194
		return spfrr;
244
		return spfrr;
195
    }
245
    }
196
246
Lines 226-231 Link Here
226
			if ( spf_dns_server->debug > 1 )
276
			if ( spf_dns_server->debug > 1 )
227
				SPF_debugf( "ns_parserr failed: err = %d  %s (%d)",
277
				SPF_debugf( "ns_parserr failed: err = %d  %s (%d)",
228
					err, strerror( errno ), errno );
278
					err, strerror( errno ), errno );
279
				free(responsebuf);
229
			return spfrr;
280
			return spfrr;
230
			}
281
			}
231
282
Lines 257-264 Link Here
257
				break;
308
				break;
258
309
259
			case ns_t_ns:
310
			case ns_t_ns:
260
				err = ns_name_uncompress( response,
311
				err = ns_name_uncompress( responsebuf,
261
							  response + sizeof( response ),
312
							  responsebuf + responselen,
262
							  rdata,
313
							  rdata,
263
							  name_buf, sizeof( name_buf ) );
314
							  name_buf, sizeof( name_buf ) );
264
				if ( err < 0 )		/* 0 or -1 */
315
				if ( err < 0 )		/* 0 or -1 */
Lines 271-278 Link Here
271
				break;
322
				break;
272
323
273
			case ns_t_cname:
324
			case ns_t_cname:
274
				err = ns_name_uncompress( response,
325
				err = ns_name_uncompress( responsebuf,
275
							  response + sizeof( response ),
326
							  responsebuf + responselen,
276
							  rdata,
327
							  rdata,
277
							  name_buf, sizeof( name_buf ) );
328
							  name_buf, sizeof( name_buf ) );
278
				if ( err < 0 )		/* 0 or -1 */
329
				if ( err < 0 )		/* 0 or -1 */
Lines 286-293 Link Here
286
337
287
			case ns_t_mx:
338
			case ns_t_mx:
288
				prio = ns_get16( rdata );
339
				prio = ns_get16( rdata );
289
				err = ns_name_uncompress( response,
340
				err = ns_name_uncompress( responsebuf,
290
							  response + sizeof( response ),
341
							  responsebuf + sizeof( responselen ),
291
							  rdata + NS_INT16SZ,
342
							  rdata + NS_INT16SZ,
292
							  name_buf, sizeof( name_buf ) );
343
							  name_buf, sizeof( name_buf ) );
293
				if ( err < 0 )		/* 0 or -1 */
344
				if ( err < 0 )		/* 0 or -1 */
Lines 300-313 Link Here
300
				break;
351
				break;
301
352
302
			case ns_t_txt:
353
			case ns_t_txt:
303
				rdata_end = rdata + rdlen;
304
				SPF_debugf( "TXT: (%d) \"%.*s\"",
354
				SPF_debugf( "TXT: (%d) \"%.*s\"",
305
					rdlen, rdlen-1, rdata+1 );
355
					rdlen, rdlen-1, rdata+1 );
306
				break;
356
				break;
307
357
308
			case ns_t_ptr:
358
			case ns_t_ptr:
309
				err = ns_name_uncompress( response,
359
				err = ns_name_uncompress( responsebuf,
310
							  response + sizeof( response ),
360
							  responsebuf + responselen,
311
							  rdata,
361
							  rdata,
312
							  name_buf, sizeof( name_buf ) );
362
							  name_buf, sizeof( name_buf ) );
313
				if ( err < 0 )		/* 0 or -1 */
363
				if ( err < 0 )		/* 0 or -1 */
Lines 341-358 Link Here
341
			{
391
			{
342
			case ns_t_a:
392
			case ns_t_a:
343
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
393
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
344
							sizeof( spfrr->rr[cnt]->a ) ) != SPF_E_SUCCESS )
394
								sizeof(spfrr->rr[cnt]->a)) != SPF_E_SUCCESS) {
395
						free(responsebuf);
345
				return spfrr;
396
				return spfrr;
346
			memmove( &spfrr->rr[cnt]->a, rdata, sizeof( spfrr->rr[cnt]->a ) );
397
					}
398
					memcpy(&spfrr->rr[cnt]->a, rdata, sizeof(spfrr->rr[cnt]->a));
347
			cnt++;
399
			cnt++;
348
			break;
400
			break;
349
401
350
			case ns_t_aaaa:
402
			case ns_t_aaaa:
351
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
403
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
352
							sizeof( spfrr->rr[cnt]->aaaa ) ) != SPF_E_SUCCESS )
404
								sizeof(spfrr->rr[cnt]->aaaa)) != SPF_E_SUCCESS) {
405
						free(responsebuf);
353
				return spfrr;
406
				return spfrr;
354
			memmove( &spfrr->rr[cnt]->aaaa, rdata, sizeof( spfrr->rr[cnt]->aaaa ) );
407
					}
355
408
					memcpy(&spfrr->rr[cnt]->aaaa, rdata, sizeof(spfrr->rr[cnt]->aaaa));
356
			cnt++;
409
			cnt++;
357
			break;
410
			break;
358
411
Lines 364-371 Link Here
364
			break;
417
			break;
365
418
366
			case ns_t_mx:
419
			case ns_t_mx:
367
			err = ns_name_uncompress( response,
420
					err = ns_name_uncompress(responsebuf,
368
						  response + sizeof( response ),
421
									responsebuf + responselen,
369
						  rdata + NS_INT16SZ,
422
						  rdata + NS_INT16SZ,
370
						  name_buf, sizeof( name_buf ) );
423
						  name_buf, sizeof( name_buf ) );
371
			if ( err < 0 )		/* 0 or -1 */
424
			if ( err < 0 )		/* 0 or -1 */
Lines 373-384 Link Here
373
				if ( spf_dns_server->debug > 1 )
426
				if ( spf_dns_server->debug > 1 )
374
				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
427
				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
375
					err, strerror( errno ), errno );
428
					err, strerror( errno ), errno );
429
						free(responsebuf);
376
				return spfrr;
430
				return spfrr;
377
			}
431
			}
378
432
379
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
433
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
380
							strlen( name_buf ) + 1 ) != SPF_E_SUCCESS )
434
									strlen(name_buf) + 1 ) != SPF_E_SUCCESS) {
435
						free(responsebuf);
381
				return spfrr;
436
				return spfrr;
437
					}
382
			strcpy( spfrr->rr[cnt]->mx, name_buf );
438
			strcpy( spfrr->rr[cnt]->mx, name_buf );
383
439
384
			cnt++;
440
			cnt++;
Lines 390-397 Link Here
390
				u_char *src, *dst;
446
				u_char *src, *dst;
391
				size_t len;
447
				size_t len;
392
448
393
				if ( SPF_dns_rr_buf_realloc( spfrr, cnt, rdlen ) != SPF_E_SUCCESS )
449
						/* Just rdlen is enough because there is at least one
450
						 * length byte. */
451
						if (SPF_dns_rr_buf_realloc(spfrr, cnt, rdlen) != SPF_E_SUCCESS) {
452
							free(responsebuf);
394
				return spfrr;
453
				return spfrr;
454
						}
395
455
396
				dst = (u_char *)(spfrr->rr[cnt]->txt);
456
				dst = (u_char *)(spfrr->rr[cnt]->txt);
397
				len = 0;
457
				len = 0;
Lines 400-414 Link Here
400
				{
460
				{
401
				len = *src;
461
				len = *src;
402
				src++;
462
				src++;
463
							rdlen--;
464
465
							/* Avoid buffer overrun if len is junk. */
466
							if (len > rdlen)
467
								len = rdlen;
403
				memcpy( dst, src, len );
468
				memcpy( dst, src, len );
404
				dst += len;
469
				dst += len;
405
				src += len;
470
				src += len;
406
				rdlen -= len + 1;
471
							rdlen -= len;
407
				}
472
				}
408
				*dst = '\0';
473
				*dst = '\0';
409
			} else {
474
			} else {
410
				if ( SPF_dns_rr_buf_realloc( spfrr, cnt, 1 ) != SPF_E_SUCCESS )
475
						if (SPF_dns_rr_buf_realloc(spfrr, cnt, 1) != SPF_E_SUCCESS) {
476
							free(responsebuf);
411
				return spfrr;
477
				return spfrr;
478
						}
412
				spfrr->rr[cnt]->txt[0] = '\0';
479
				spfrr->rr[cnt]->txt[0] = '\0';
413
			}
480
			}
414
481
Lines 416-423 Link Here
416
			break;
483
			break;
417
484
418
			case ns_t_ptr:
485
			case ns_t_ptr:
419
			err = ns_name_uncompress( response,
486
					err = ns_name_uncompress(responsebuf,
420
						  response + sizeof( response ),
487
									responsebuf + responselen,
421
						  rdata,
488
						  rdata,
422
						  name_buf, sizeof( name_buf ) );
489
						  name_buf, sizeof( name_buf ) );
423
			if ( err < 0 )		/* 0 or -1 */
490
			if ( err < 0 )		/* 0 or -1 */
Lines 425-436 Link Here
425
				if ( spf_dns_server->debug > 1 )
492
				if ( spf_dns_server->debug > 1 )
426
				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
493
				SPF_debugf( "ns_name_uncompress failed: err = %d  %s (%d)",
427
					err, strerror( errno ), errno );
494
					err, strerror( errno ), errno );
495
						free(responsebuf);
428
				return spfrr;
496
				return spfrr;
429
			}
497
			}
430
498
431
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
499
			if ( SPF_dns_rr_buf_realloc( spfrr, cnt,
432
							strlen( name_buf ) + 1 ) != SPF_E_SUCCESS )
500
									strlen(name_buf) + 1) != SPF_E_SUCCESS) {
501
						free(responsebuf);
433
				return spfrr;
502
				return spfrr;
503
					}
434
			strcpy( spfrr->rr[cnt]->ptr, name_buf );
504
			strcpy( spfrr->rr[cnt]->ptr, name_buf );
435
505
436
			cnt++;
506
			cnt++;
Lines 447-452 Link Here
447
    if ( spfrr->num_rr == 0 )
517
    if ( spfrr->num_rr == 0 )
448
		spfrr->herrno = NO_DATA;
518
		spfrr->herrno = NO_DATA;
449
519
520
	free(responsebuf);
450
    return spfrr;
521
    return spfrr;
451
}
522
}
452
523

Return to bug 242254