Skip to content

Commit

Permalink
DNS: zero out res_state
Browse files Browse the repository at this point in the history
This is needed to avoid segfault on some OS.
Also free the state resources on error.
  • Loading branch information
gaborcsardi committed Oct 25, 2024
1 parent d1f95ea commit 3f3a2ba
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ SEXP r_nsl(SEXP hostname, SEXP server, SEXP class, SEXP type) {

struct __res_state state;
res_state statep = &state;
memset(statep, 0, sizeof(state));
ret = res_ninit(statep);

Check warning on line 314 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L312-L314

Added lines #L312 - L314 were not covered by tests
if (ret) R_THROW_SYSTEM_ERROR("Failed to initialize resolver library");

Expand All @@ -328,10 +329,16 @@ SEXP r_nsl(SEXP hostname, SEXP server, SEXP class, SEXP type) {
INTEGER(type)[0],
answer,
sizeof answer);
if (ret == -1) R_THROW_SYSTEM_ERROR("DNS query failed");
if (ret == -1) {
res_nclose(statep);
R_THROW_SYSTEM_ERROR("DNS query failed");

Check warning on line 334 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L332-L334

Added lines #L332 - L334 were not covered by tests
}

ret = ns_initparse(answer, ret, &msg);
if (ret == -1) R_THROW_SYSTEM_ERROR("Cannot parse DNS answer");
if (ret == -1) {
res_nclose(statep);
R_THROW_SYSTEM_ERROR("Cannot parse DNS answer");

Check warning on line 340 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L338-L340

Added lines #L338 - L340 were not covered by tests
}

LOGICAL(VECTOR_ELT(result, 1))[0] = ns_msg_getflag(msg, ns_f_aa);
LOGICAL(VECTOR_ELT(result, 1))[1] = ns_msg_getflag(msg, ns_f_tc);
Expand Down Expand Up @@ -361,7 +368,10 @@ SEXP r_nsl(SEXP hostname, SEXP server, SEXP class, SEXP type) {
SEXP rawdata;

ret = ns_parserr(&msg, ns_s_an, i, &rec);
if (ret == -1) R_THROW_SYSTEM_ERROR("Cannot parse DNS record");
if (ret == -1) {
res_nclose(statep);
R_THROW_SYSTEM_ERROR("Cannot parse DNS record");

Check warning on line 373 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L371-L373

Added lines #L371 - L373 were not covered by tests
}
class = ns_rr_class(rec);
type = ns_rr_type(rec);
data = ns_rr_rdata(rec);
Expand Down Expand Up @@ -406,7 +416,10 @@ SEXP r_nsl(SEXP hostname, SEXP server, SEXP class, SEXP type) {
int len, j;
ret = xxns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
data, buf, sizeof buf);
if (ret < 0) R_THROW_SYSTEM_ERROR("Cannot parse SOA DNS record");
if (ret < 0) {
res_nclose(statep);
R_THROW_SYSTEM_ERROR("Cannot parse SOA DNS record");

Check warning on line 421 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L419-L421

Added lines #L419 - L421 were not covered by tests
}

data += ret; len = strlen(buf2); buf2 += len; bufsize -= len;
if (bufsize > 2) {
Expand All @@ -415,14 +428,18 @@ SEXP r_nsl(SEXP hostname, SEXP server, SEXP class, SEXP type) {

ret = xxns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
data, buf2, bufsize);
if (ret < 0) R_THROW_SYSTEM_ERROR("Cannot parse SOA DNS record");
if (ret < 0) {
res_nclose(statep);
R_THROW_SYSTEM_ERROR("Cannot parse SOA DNS record");

Check warning on line 433 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L431-L433

Added lines #L431 - L433 were not covered by tests
}

data += ret; len = strlen(buf2); buf2 += len; bufsize -= len;
if (bufsize > 2) {
*buf2 = '.'; buf2++; bufsize--; *buf2 = ' '; buf2++; bufsize--;
}

if (ns_msg_end(msg) - data < 5*NS_INT32SZ) {
res_nclose(statep);

Check warning on line 442 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L442

Added line #L442 was not covered by tests
R_THROW_ERROR("Cannot parse SOA DNS record");
}
for (j = 0; j < 5; j++) NS_GET32(soa[j], data);
Expand All @@ -440,6 +457,7 @@ SEXP r_nsl(SEXP hostname, SEXP server, SEXP class, SEXP type) {
}

if (ret < 0) {
res_nclose(statep);

Check warning on line 460 in src/dns.c

View check run for this annotation

Codecov / codecov/patch

src/dns.c#L460

Added line #L460 was not covered by tests
R_THROW_SYSTEM_ERROR("Cannot parse NS/PTR/CNAME DNS record");
}

Expand Down

0 comments on commit 3f3a2ba

Please sign in to comment.