Skip to content

Commit 0f41bca

Browse files
AasthaGuptaTrott
authored andcommitted
src: fix freeing unintialized pointer bug in ParseSoaReply
ares_expand_name doesn't guarantee that pointer variable is initialized if return code is ARES_EBADNAME or ARES_ENOMEM. But current usage of the function in the codebase thinks otherwise. There seems to be an assumption that pointer is always initialized even though it is a local variable and we create a unique pointer soon after calling ares_expand_name. This could potentially crash the program with an invalid free pointer. I was able to crash it by poisoning the memory and some manual hooks. By moving the unique_ptr after checking the return code we can fix the problem. As the underlying function guarantees that pointer is initialized when the status is ARES_SUCCESS. PR-URL: #35502 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent ee5f849 commit 0f41bca

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

src/cares_wrap.cc

+10-8
Original file line numberDiff line numberDiff line change
@@ -1060,29 +1060,31 @@ int ParseSoaReply(Environment* env,
10601060
// Can't use ares_parse_soa_reply() here which can only parse single record
10611061
const unsigned int ancount = cares_get_16bit(buf + 6);
10621062
unsigned char* ptr = buf + NS_HFIXEDSZ;
1063-
char* name_temp;
1063+
char* name_temp = nullptr;
10641064
long temp_len; // NOLINT(runtime/int)
10651065
int status = ares_expand_name(ptr, buf, len, &name_temp, &temp_len);
1066-
const ares_unique_ptr name(name_temp);
10671066
if (status != ARES_SUCCESS) {
10681067
// returns EBADRESP in case of invalid input
10691068
return status == ARES_EBADNAME ? ARES_EBADRESP : status;
10701069
}
10711070

1071+
const ares_unique_ptr name(name_temp);
1072+
10721073
if (ptr + temp_len + NS_QFIXEDSZ > buf + len) {
10731074
return ARES_EBADRESP;
10741075
}
10751076
ptr += temp_len + NS_QFIXEDSZ;
10761077

10771078
for (unsigned int i = 0; i < ancount; i++) {
1078-
char* rr_name_temp;
1079+
char* rr_name_temp = nullptr;
10791080
long rr_temp_len; // NOLINT(runtime/int)
10801081
int status2 = ares_expand_name(ptr, buf, len, &rr_name_temp, &rr_temp_len);
1081-
const ares_unique_ptr rr_name(rr_name_temp);
10821082

10831083
if (status2 != ARES_SUCCESS)
10841084
return status2 == ARES_EBADNAME ? ARES_EBADRESP : status2;
10851085

1086+
const ares_unique_ptr rr_name(rr_name_temp);
1087+
10861088
ptr += rr_temp_len;
10871089
if (ptr + NS_RRFIXEDSZ > buf + len) {
10881090
return ARES_EBADRESP;
@@ -1094,27 +1096,27 @@ int ParseSoaReply(Environment* env,
10941096

10951097
// only need SOA
10961098
if (rr_type == ns_t_soa) {
1097-
char* nsname_temp;
1099+
char* nsname_temp = nullptr;
10981100
long nsname_temp_len; // NOLINT(runtime/int)
10991101

11001102
int status3 = ares_expand_name(ptr, buf, len,
11011103
&nsname_temp,
11021104
&nsname_temp_len);
1103-
const ares_unique_ptr nsname(nsname_temp);
11041105
if (status3 != ARES_SUCCESS) {
11051106
return status3 == ARES_EBADNAME ? ARES_EBADRESP : status3;
11061107
}
1108+
const ares_unique_ptr nsname(nsname_temp);
11071109
ptr += nsname_temp_len;
11081110

1109-
char* hostmaster_temp;
1111+
char* hostmaster_temp = nullptr;
11101112
long hostmaster_temp_len; // NOLINT(runtime/int)
11111113
int status4 = ares_expand_name(ptr, buf, len,
11121114
&hostmaster_temp,
11131115
&hostmaster_temp_len);
1114-
const ares_unique_ptr hostmaster(hostmaster_temp);
11151116
if (status4 != ARES_SUCCESS) {
11161117
return status4 == ARES_EBADNAME ? ARES_EBADRESP : status4;
11171118
}
1119+
const ares_unique_ptr hostmaster(hostmaster_temp);
11181120
ptr += hostmaster_temp_len;
11191121

11201122
if (ptr + 5 * 4 > buf + len) {

0 commit comments

Comments
 (0)