From: W.C.A. Wijngaards Date: Fri, 15 Mar 2024 12:39:49 +0000 (+0100) Subject: - Fix that addrinfo is not kept around but copied and freed, so that X-Git-Tag: release-1.20.0rc1~64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2993437eaaf0328feb2cd90cf04582506e93d3cc;p=thirdparty%2Funbound.git - Fix that addrinfo is not kept around but copied and freed, so that log-destaddr uses a copy of the information, much like NSD does. --- diff --git a/daemon/daemon.c b/daemon/daemon.c index 193608d40..4870089a7 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -321,17 +321,15 @@ static int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list) { struct acl_addr* acl_node; - struct addrinfo* addr; for(; port_list; port_list=port_list->next) { if(!port_list->socket) { /* This is mainly for testbound where port_list is * empty. */ continue; } - addr = port_list->socket->addr; if(!(acl_node = acl_interface_insert(list, - (struct sockaddr_storage*)addr->ai_addr, - (socklen_t)addr->ai_addrlen, + (struct sockaddr_storage*)port_list->socket->addr, + port_list->socket->addrlen, acl_refuse))) { return 0; } diff --git a/daemon/worker.c b/daemon/worker.c index 176abf57d..1a0b9abde 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1454,8 +1454,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error, */ if(worker->dtenv.log_client_query_messages) { log_addr(VERB_ALGO, "request from client", &repinfo->client_addr, repinfo->client_addrlen); - log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); - dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer, + log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen); + dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, c->type, c->ssl, c->buffer, ((worker->env.cfg->sock_queue_timeout && timeval_isset(&c->recv_tv))?&c->recv_tv:NULL)); } #endif @@ -1944,9 +1944,9 @@ send_reply_rc: * sending src (client)/dst (local service) addresses over DNSTAP from send_reply code label (when we serviced local zone for ex.) */ if(worker->dtenv.log_client_response_messages) { - log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); + log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen); log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen); - dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer); + dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, c->type, c->ssl, c->buffer); } #endif if(worker->env.cfg->log_replies) @@ -1961,13 +1961,13 @@ send_reply_rc: log_reply_info(NO_VERBOSE, &qinfo, &repinfo->client_addr, repinfo->client_addrlen, tv, 1, c->buffer, - (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr->ai_addr:NULL), + (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL), c->type); } else { log_reply_info(NO_VERBOSE, &qinfo, &repinfo->client_addr, repinfo->client_addrlen, tv, 1, c->buffer, - (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr->ai_addr:NULL), + (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL), c->type); } } diff --git a/doc/Changelog b/doc/Changelog index 6d8a1e291..8359f08f5 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +15 March 2024: Wouter + - Fix that addrinfo is not kept around but copied and freed, so that + log-destaddr uses a copy of the information, much like NSD does. + 13 March 2024: Wouter - Fix #1029: rpz trigger clientip and action rpz-passthru not working as expected. diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 753550978..26679941b 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -140,9 +140,11 @@ void verbose_print_unbound_socket(struct unbound_socket* ub_sock) { if(verbosity >= VERB_ALGO) { + char buf[256]; log_info("listing of unbound_socket structure:"); - verbose_print_addr(ub_sock->addr); - log_info("s is: %d, fam is: %s, acl: %s", ub_sock->s, + addr_to_str((void*)ub_sock->addr, ub_sock->addrlen, buf, + sizeof(buf)); + log_info("%s s is: %d, fam is: %s, acl: %s", buf, ub_sock->s, ub_sock->fam == AF_INET?"AF_INET":"AF_INET6", ub_sock->acl?"yes":"no"); } @@ -1047,7 +1049,22 @@ make_sock(int stype, const char* ifname, const char* port, } } - ub_sock->addr = res; + if(!res->ai_addr) { + log_err("getaddrinfo returned no address"); + freeaddrinfo(res); + sock_close(s); + return -1; + } + ub_sock->addr = memdup(res->ai_addr, res->ai_addrlen); + ub_sock->addrlen = res->ai_addrlen; + if(!ub_sock->addr) { + log_err("out of memory: allocate listening address"); + freeaddrinfo(res); + sock_close(s); + return -1; + } + freeaddrinfo(res); + ub_sock->s = s; ub_sock->fam = hints->ai_family; ub_sock->acl = NULL; @@ -1277,8 +1294,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, &noip6, rcv, snd, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) { - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); if(noip6) { log_warn("IPv6 protocol not available"); @@ -1289,8 +1305,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, /* getting source addr packet info is highly non-portable */ if(!set_recvpktinfo(s, hints->ai_family)) { sock_close(s); - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); return 0; } @@ -1301,8 +1316,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, ?listen_type_udpancil_dnscrypt:listen_type_udpancil, is_pp2, ub_sock)) { sock_close(s); - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); return 0; } @@ -1314,8 +1328,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, &noip6, rcv, snd, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) { - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); if(noip6) { log_warn("IPv6 protocol not available"); @@ -1332,8 +1345,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, listen_type_udpancil:listen_type_udp), is_pp2, ub_sock)) { sock_close(s); - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); return 0; } @@ -1356,8 +1368,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1, &noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) { - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); if(noip6) { /*log_warn("IPv6 protocol not available");*/ @@ -1369,8 +1380,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, verbose(VERB_ALGO, "setup TCP for SSL service"); if(!port_insert(list, s, port_type, is_pp2, ub_sock)) { sock_close(s); - if(ub_sock->addr) - freeaddrinfo(ub_sock->addr); + free(ub_sock->addr); free(ub_sock); return 0; } @@ -1952,8 +1962,7 @@ void listening_ports_free(struct listen_port* list) } /* rc_ports don't have ub_socket */ if(list->socket) { - if(list->socket->addr) - freeaddrinfo(list->socket->addr); + free(list->socket->addr); free(list->socket); } free(list); diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h index 816d79aea..84ac4b068 100644 --- a/services/listen_dnsport.h +++ b/services/listen_dnsport.h @@ -107,11 +107,13 @@ enum listen_type { * socket properties (just like NSD nsd_socket structure definition) */ struct unbound_socket { - /** socket-address structure */ - struct addrinfo* addr; + /** the address of the socket */ + struct sockaddr* addr; + /** length of the address */ + socklen_t addrlen; /** socket descriptor returned by socket() syscall */ int s; - /** address family (AF_INET/IF_INET6) */ + /** address family (AF_INET/AF_INET6) */ int fam; /** ACL on the socket (listening interface) */ struct acl_addr* acl; diff --git a/services/mesh.c b/services/mesh.c index 47cfb0424..3c2b536b4 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -1436,7 +1436,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep, log_reply_info(NO_VERBOSE, &m->s.qinfo, &r->query_reply.client_addr, r->query_reply.client_addrlen, duration, 0, r_buffer, - (m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr->ai_addr:NULL), + (m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr:NULL), r->query_reply.c->type); } } diff --git a/util/netevent.c b/util/netevent.c index 1fc8c6b86..980829d08 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -4772,9 +4772,9 @@ comm_point_send_reply(struct comm_reply *repinfo) * sending src (client)/dst (local service) addresses over DNSTAP from udp callback */ if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) { - log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); + log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen); log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen); - dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer); + dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer); } #endif } else { @@ -4783,9 +4783,9 @@ comm_point_send_reply(struct comm_reply *repinfo) * sending src (client)/dst (local service) addresses over DNSTAP from TCP callback */ if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) { - log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen); + log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen); log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen); - dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, + dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, repinfo->c->type, repinfo->c->ssl, ( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer )); } #endif diff --git a/util/netevent.h b/util/netevent.h index dc9619c16..1e4a13f9b 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -181,6 +181,8 @@ struct comm_point { /** if the event is added or not */ int event_added; + /** Reference to struct that is part of the listening ports, + * where for listening ports information is kept about the address. */ struct unbound_socket* socket; /** file descriptor for communication point */