Commit 6e156834 authored by Ondřej Surý's avatar Ondřej Surý

Merge branch '2124-fix-assertion-failure-in-dns-message' into 'main'

Resolve "Bind 9.16.6 Assertion failure message.c:4733: REQUIRE(msg->state == (-1)) failed"

Closes #2124

See merge request isc-projects/bind9!4194
parents e6f2f79f 6179a388
5510. [bug] Implement the attach/detach semantics for dns_message_t
to fix a data race in accessing already destroyed
fctx->rmessage. [GL #2124]
5509. [bug] filter-aaaa: named crashed upon shutdown if it was in
the process of recursing for A RRsets. [GL #1040]
......
......@@ -1681,7 +1681,7 @@ destroy_lookup(dig_lookup_t *lookup) {
isc_mem_free(mctx, ptr);
}
if (lookup->sendmsg != NULL) {
dns_message_destroy(&lookup->sendmsg);
dns_message_detach(&lookup->sendmsg);
}
if (lookup->querysig != NULL) {
debug("freeing buffer %p", lookup->querysig);
......@@ -2106,9 +2106,7 @@ setup_lookup(dig_lookup_t *lookup) {
debug("setup_lookup(%p)", lookup);
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
&lookup->sendmsg);
check_result(result, "dns_message_create");
dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &lookup->sendmsg);
if (lookup->new_search) {
debug("resetting lookup counter.");
......@@ -3776,8 +3774,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
goto udp_mismatch;
}
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
check_result(result, "dns_message_create");
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
if (tsigkey != NULL) {
if (l->querysig == NULL) {
......@@ -3817,7 +3814,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
hex_dump(&b);
}
query->waiting_connect = false;
dns_message_destroy(&msg);
dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
......@@ -3839,7 +3836,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
dighost_warning("Warning: Opcode mismatch: expected %s, got %s",
expect, got);
dns_message_destroy(&msg);
dns_message_detach(&msg);
if (l->tcp_mode) {
isc_event_free(&event);
clear_query(query);
......@@ -3891,7 +3888,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
}
if (!match) {
dns_message_destroy(&msg);
dns_message_detach(&msg);
if (l->tcp_mode) {
isc_event_free(&event);
clear_query(query);
......@@ -3917,7 +3914,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
if (l->trace && l->trace_root) {
n->rdtype = l->qrdtype;
}
dns_message_destroy(&msg);
dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
......@@ -3936,7 +3933,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
if (l->trace && l->trace_root) {
n->rdtype = l->qrdtype;
}
dns_message_destroy(&msg);
dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
......@@ -3960,7 +3957,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
if (l->trace && l->trace_root) {
n->rdtype = l->qrdtype;
}
dns_message_destroy(&msg);
dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
......@@ -4001,7 +3998,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
query->servname);
clear_query(query);
check_next_lookup(l);
dns_message_destroy(&msg);
dns_message_detach(&msg);
isc_event_free(&event);
UNLOCK_LOOKUP;
return;
......@@ -4134,7 +4131,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
if (l->doing_xfr) {
if (query != l->xfr_q) {
dns_message_destroy(&msg);
dns_message_detach(&msg);
isc_event_free(&event);
query->waiting_connect = false;
UNLOCK_LOOKUP;
......@@ -4144,7 +4141,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
docancel = check_for_more_data(query, msg, sevent);
}
if (docancel) {
dns_message_destroy(&msg);
dns_message_detach(&msg);
clear_query(query);
cancel_lookup(l);
check_next_lookup(l);
......@@ -4160,14 +4157,14 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
if (!query->lookup->ns_search_only ||
query->lookup->trace_root || docancel) {
dns_message_destroy(&msg);
dns_message_detach(&msg);
cancel_lookup(l);
}
clear_query(query);
check_next_lookup(l);
}
if (msg != NULL) {
dns_message_destroy(&msg);
dns_message_detach(&msg);
}
isc_event_free(&event);
UNLOCK_LOOKUP;
......
......@@ -935,7 +935,7 @@ flush_lookup_list(void) {
isc_mem_free(mctx, sp);
}
if (l->sendmsg != NULL) {
dns_message_destroy(&l->sendmsg);
dns_message_detach(&l->sendmsg);
}
lp = l;
l = ISC_LIST_NEXT(l, link);
......
......@@ -350,16 +350,12 @@ nsu_strsep(char **stringp, const char *delim) {
static void
reset_system(void) {
isc_result_t result;
ddebug("reset_system()");
/* If the update message is still around, destroy it */
if (updatemsg != NULL) {
dns_message_reset(updatemsg, DNS_MESSAGE_INTENTRENDER);
} else {
result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER,
&updatemsg);
check_result(result, "dns_message_create");
dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &updatemsg);
}
updatemsg->opcode = dns_opcode_update;
if (usegsstsig) {
......@@ -720,7 +716,7 @@ doshutdown(void) {
}
if (updatemsg != NULL) {
dns_message_destroy(&updatemsg);
dns_message_detach(&updatemsg);
}
if (is_dst_up) {
......@@ -2413,8 +2409,7 @@ update_completed(isc_task_t *task, isc_event_t *event) {
}
LOCK(&answer_lock);
result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &answer);
check_result(result, "dns_message_create");
dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &answer);
result = dns_request_getresponse(request, answer,
DNS_MESSAGEPARSE_PRESERVEORDER);
switch (result) {
......@@ -2580,7 +2575,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
if (shuttingdown) {
dns_request_destroy(&request);
dns_message_destroy(&soaquery);
dns_message_detach(&soaquery);
isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t));
isc_event_free(&event);
maybeshutdown();
......@@ -2606,12 +2601,11 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
reqev = NULL;
ddebug("About to create rcvmsg");
result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
check_result(result, "dns_message_create");
dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
result = dns_request_getresponse(request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
if (result == DNS_R_TSIGERRORSET && servers != NULL) {
dns_message_destroy(&rcvmsg);
dns_message_detach(&rcvmsg);
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t));
......@@ -2650,9 +2644,9 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(userzone, namebuf, sizeof(namebuf));
error("specified zone '%s' does not exist (NXDOMAIN)", namebuf);
dns_message_destroy(&rcvmsg);
dns_message_detach(&rcvmsg);
dns_request_destroy(&request);
dns_message_destroy(&soaquery);
dns_message_detach(&soaquery);
ddebug("Out of recvsoa");
done_update();
seenerror = true;
......@@ -2786,11 +2780,11 @@ lookforsoa:
setzoneclass(dns_rdataclass_none);
#endif /* HAVE_GSSAPI */
dns_message_destroy(&soaquery);
dns_message_detach(&soaquery);
dns_request_destroy(&request);
out:
dns_message_destroy(&rcvmsg);
dns_message_detach(&rcvmsg);
ddebug("Out of recvsoa");
return;
......@@ -2977,11 +2971,7 @@ start_gssrequest(dns_name_t *master) {
keyname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
rmsg = NULL;
result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &rmsg);
if (result != ISC_R_SUCCESS) {
fatal("dns_message_create failed: %s",
isc_result_totext(result));
}
dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &rmsg);
/* Build first request. */
context = GSS_C_NO_CONTEXT;
......@@ -3003,7 +2993,7 @@ start_gssrequest(dns_name_t *master) {
failure:
if (rmsg != NULL) {
dns_message_destroy(&rmsg);
dns_message_detach(&rmsg);
}
if (err_message != NULL) {
isc_mem_free(gmctx, err_message);
......@@ -3078,7 +3068,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
if (shuttingdown) {
dns_request_destroy(&request);
dns_message_destroy(&tsigquery);
dns_message_detach(&tsigquery);
isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t));
isc_event_free(&event);
maybeshutdown();
......@@ -3089,7 +3079,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
if (!next_master("recvgss", addr, eresult)) {
dns_message_destroy(&tsigquery);
dns_message_detach(&tsigquery);
failed_gssrequest();
} else {
dns_message_renderreset(tsigquery);
......@@ -3107,8 +3097,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
reqev = NULL;
ddebug("recvgss creating rcvmsg");
result = dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
check_result(result, "dns_message_create");
dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
result = dns_request_getresponse(request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
......@@ -3149,7 +3138,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
&err_message);
switch (result) {
case DNS_R_CONTINUE:
dns_message_destroy(&rcvmsg);
dns_message_detach(&rcvmsg);
dns_request_destroy(&request);
send_gssrequest(kserver, tsigquery, &request, context);
ddebug("Out of recvgss");
......@@ -3196,9 +3185,9 @@ recvgss(isc_task_t *task, isc_event_t *event) {
done:
dns_request_destroy(&request);
dns_message_destroy(&tsigquery);
dns_message_detach(&tsigquery);
dns_message_destroy(&rcvmsg);
dns_message_detach(&rcvmsg);
ddebug("Out of recvgss");
}
#endif /* HAVE_GSSAPI */
......@@ -3217,7 +3206,7 @@ start_update(void) {
LOCK(&answer_lock);
if (answer != NULL) {
dns_message_destroy(&answer);
dns_message_detach(&answer);
}
UNLOCK(&answer_lock);
......@@ -3233,8 +3222,7 @@ start_update(void) {
return;
}
result = dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &soaquery);
check_result(result, "dns_message_create");
dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &soaquery);
if (default_servers) {
soaquery->flags |= DNS_MESSAGEFLAG_RD;
......@@ -3262,7 +3250,7 @@ start_update(void) {
dns_message_puttempname(soaquery, &name);
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(soaquery, &rdataset);
dns_message_destroy(&soaquery);
dns_message_detach(&soaquery);
done_update();
return;
}
......@@ -3300,7 +3288,7 @@ cleanup(void) {
LOCK(&answer_lock);
if (answer != NULL) {
dns_message_destroy(&answer);
dns_message_detach(&answer);
}
UNLOCK(&answer_lock);
......
......@@ -87,8 +87,7 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
query = reqev->ev_arg;
response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(reqev->request, response,
DNS_MESSAGEPARSE_PRESERVEORDER);
......@@ -114,8 +113,8 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
(char *)isc_buffer_base(&outbuf));
fflush(stdout);
dns_message_destroy(&query);
dns_message_destroy(&response);
dns_message_detach(&query);
dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
......@@ -152,8 +151,7 @@ sendquery(isc_task_t *task) {
CHECK("dns_name_fromtext", result);
message = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
message->opcode = dns_opcode_query;
message->flags |= DNS_MESSAGEFLAG_RD;
......
......@@ -88,8 +88,7 @@ recvquery(isc_task_t *task, isc_event_t *event) {
query = reqev->ev_arg;
response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(reqev->request, response,
DNS_MESSAGEPARSE_PRESERVEORDER);
......@@ -118,8 +117,8 @@ recvquery(isc_task_t *task, isc_event_t *event) {
result = dst_key_tofile(tsigkey->key, type, "");
CHECK("dst_key_tofile", result);
dns_message_destroy(&query);
dns_message_destroy(&response);
dns_message_detach(&query);
dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
isc_app_shutdown();
......@@ -176,8 +175,7 @@ sendquery(isc_task_t *task, isc_event_t *event) {
CHECK("dns_tsigkey_create", result);
query = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
result = dns_tkey_builddhquery(query, ourkey,
dns_fixedname_name(&ownername),
......
......@@ -79,8 +79,7 @@ recvquery(isc_task_t *task, isc_event_t *event) {
query = reqev->ev_arg;
response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
result = dns_request_getresponse(reqev->request, response,
DNS_MESSAGEPARSE_PRESERVEORDER);
......@@ -96,8 +95,8 @@ recvquery(isc_task_t *task, isc_event_t *event) {
result = dns_tkey_processdeleteresponse(query, response, ring);
CHECK("dns_tkey_processdhresponse", result);
dns_message_destroy(&query);
dns_message_destroy(&response);
dns_message_detach(&query);
dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
isc_app_shutdown();
......@@ -121,8 +120,7 @@ sendquery(isc_task_t *task, isc_event_t *event) {
isc_sockaddr_fromin(&address, &inaddr, port);
query = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query);
result = dns_tkey_builddeletequery(query, tsigkey);
CHECK("dns_tkey_builddeletequery", result);
......
......@@ -277,8 +277,7 @@ process_message(isc_buffer_t *source) {
int i;
message = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
CHECKRESULT(result, "dns_message_create failed");
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
result = dns_message_parse(message, source, parseflags);
if (result == DNS_R_RECOVERABLE) {
......@@ -341,16 +340,14 @@ process_message(isc_buffer_t *source) {
dns_compress_invalidate(&cctx);
message->from_to_wire = DNS_MESSAGE_INTENTPARSE;
dns_message_destroy(&message);
dns_message_detach(&message);
printf("Message rendered.\n");
if (printmemstats) {
isc_mem_stats(mctx, stdout);
}
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
&message);
CHECKRESULT(result, "dns_message_create failed");
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
result = dns_message_parse(message, &buffer, parseflags);
CHECKRESULT(result, "dns_message_parse failed");
......@@ -358,5 +355,5 @@ process_message(isc_buffer_t *source) {
result = printmessage(message);
CHECKRESULT(result, "printmessage() failed");
}
dns_message_destroy(&message);
dns_message_detach(&message);
}
......@@ -417,7 +417,7 @@ cleanup:
dns_dt_close(&handle);
}
if (message != NULL) {
dns_message_destroy(&message);
dns_message_detach(&message);
}
if (b != NULL) {
isc_buffer_free(&b);
......
......@@ -210,8 +210,7 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
}
}
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
parseflags |= DNS_MESSAGEPARSE_PRESERVEORDER;
if (besteffort) {
......@@ -534,10 +533,10 @@ cleanup:
dns_master_styledestroy(&style, mctx);
}
if (query != NULL) {
dns_message_destroy(&query);
dns_message_detach(&query);
}
if (response != NULL) {
dns_message_destroy(&response);
dns_message_detach(&response);
}
dns_request_destroy(&reqev->request);
isc_event_free(&event);
......@@ -594,8 +593,7 @@ sendquery(struct query *query, isc_task_t *task) {
CHECK("dns_name_fromtext", result);
message = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
CHECK("dns_message_create", result);
dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
message->opcode = dns_opcode_query;
if (query->recurse) {
......
@@
statement S;
expression V;
@@
- V =
dns_message_create(...);
- if (V != ISC_R_SUCCESS) S
@@
statement S1, S2;
expression V;
@@
- V =
dns_message_create(...);
- if (V == ISC_R_SUCCESS)
S1
- else S2
@@
expression V;
@@
- V =
dns_message_create(...);
- check_result(V, ...);
@@
@@
- CHECK(
dns_message_create(...)
- )
;
@@
@@
- DO(...,
dns_message_create(...)
- )
;
@@
@@
- RETERR(
dns_message_create(...)
- )
;
@@
expression V;
@@
- V =
dns_message_create(...);
- assert_int_equal(V, ISC_R_SUCCESS);
@@
expression V;
@@
- V =
dns_message_create(...);
- CHECK(..., V);
@@
expression V;
statement S;
@@
- V =
dns_message_create(...);
- if (ISC_UNLIKELY(V != ISC_R_SUCCESS)) S
@@
expression V;
@@
- V =
dns_message_create(...);
- RUNTIME_CHECK(V == ISC_R_SUCCESS);
@@
expression M;
@@
- dns_message_destroy(M);
+ dns_message_detach(M);
......@@ -50,3 +50,6 @@ Bug Fixes
- `named` would report invalid memory size when running in an environment
that doesn't properly report number of available memory pages or pagesize.
[GL #2166]
- `named` would exit with assertion failure REQUIRE(msg->state == (-1)) in
message.c due to a possible data race. [GL #2124]
......@@ -47,10 +47,7 @@ parse_message(isc_buffer_t *input, dns_message_t **messagep) {
isc_result_t result;
dns_message_t *message = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
if (result != ISC_R_SUCCESS) {
return (result);
}
dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
result = dns_message_parse(message, input, DNS_MESSAGEPARSE_BESTEFFORT);
if (result == DNS_R_RECOVERABLE) {
......@@ -60,7 +57,7 @@ parse_message(isc_buffer_t *input, dns_message_t **messagep) {
if (result == ISC_R_SUCCESS && messagep != NULL) {
*messagep = message;
} else {
dns_message_destroy(&message);
dns_message_detach(&message);
}
return (result);
......@@ -128,7 +125,7 @@ render_message(dns_message_t **messagep) {
message->from_to_wire = DNS_MESSAGE_INTENTPARSE;
dns_message_destroy(messagep);