From 75649b623519dda99b772342bbbe625a45234864 Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Sat, 20 Jul 2024 00:33:24 +0800 Subject: [PATCH] fastping: fix asan warnings. --- src/dns.c | 125 ++++++++++++++++++++++++++++++++++++++--------- src/dns_client.c | 1 - src/fast_ping.c | 64 ++++++++++++++---------- 3 files changed, 139 insertions(+), 51 deletions(-) diff --git a/src/dns.c b/src/dns.c index 519a3db9ca..286784a458 100644 --- a/src/dns.c +++ b/src/dns.c @@ -48,12 +48,17 @@ #define member_size(type, member) sizeof(((type *)0)->member) +static int is_aligned(void *ptr, int aligment) +{ + return ((uintptr_t)(ptr)) % aligment == 0; +} + /* read short and move pointer */ static unsigned short _dns_read_short(unsigned char **buffer) { unsigned short value = 0; - if ((uintptr_t)(*buffer) % 2 == 0) { + if (is_aligned(*buffer, 2)) { value = *((unsigned short *)(*buffer)); } else { memcpy(&value, *buffer, 2); @@ -83,7 +88,7 @@ static void _dns_write_short(unsigned char **buffer, unsigned short value) { value = htons(value); - if ((uintptr_t)(*buffer) % 2 == 0) { + if (is_aligned(*buffer, 2)) { *((unsigned short *)(*buffer)) = value; } else { memcpy(*buffer, &value, 2); @@ -105,7 +110,7 @@ static void _dns_write_shortptr(unsigned char **buffer, void *ptrvalue) value = htons(value); - if ((uintptr_t)(*buffer) % 2 == 0) { + if (is_aligned(*buffer, 2)) { *((unsigned short *)(*buffer)) = value; } else { memcpy(*buffer, &value, 2); @@ -118,7 +123,7 @@ static void _dns_write_shortptr(unsigned char **buffer, void *ptrvalue) static void _dns_write_int(unsigned char **buffer, unsigned int value) { value = htonl(value); - if ((uintptr_t)(*buffer) % 4 == 0) { + if (is_aligned(*buffer, 4)) { *((unsigned int *)(*buffer)) = value; } else { memcpy(*buffer, &value, 4); @@ -138,7 +143,7 @@ static void _dns_write_intptr(unsigned char **buffer, void *ptrvalue) } value = htonl(value); - if ((uintptr_t)(*buffer) % 4 == 0) { + if (is_aligned(*buffer, 4)) { *((unsigned int *)(*buffer)) = value; } else { memcpy(*buffer, &value, 4); @@ -151,7 +156,7 @@ static unsigned int _dns_read_int(unsigned char **buffer) { unsigned int value = 0; - if ((uintptr_t)(*buffer) % 4 == 0) { + if (is_aligned(*buffer, 4)) { value = *((unsigned int *)(*buffer)); } else { memcpy(&value, *buffer, 4); @@ -658,9 +663,20 @@ int dns_add_rr_nested_memcpy(struct dns_rr_nested *rr_nested, const void *data, return -1; } + if (is_aligned(rr_nested->context.ptr, 2) == 0) { + return -1; + } + memcpy(rr_nested->context.ptr, data, data_len); rr_nested->context.ptr += data_len; + if (is_aligned(rr_nested->context.ptr, 2) == 0) { + if (_dns_left_len(&rr_nested->context) < 1) { + return -1; + } + _dns_write_char(&rr_nested->context.ptr, 0); + } + return 0; } @@ -714,6 +730,11 @@ void *dns_get_rr_nested_next(struct dns_rrs *rrs, void *rr_nested, int rr_nested { void *end = rrs->data + rrs->len; void *p = rr_nested + rr_nested_len; + + if (is_aligned(p, 2) == 0) { + p++; + } + if (p == end) { return NULL; } else if (p > end) { @@ -1257,6 +1278,14 @@ int dns_add_HTTPS_start(struct dns_rr_nested *svcparam_buffer, struct dns_packet safe_strncpy((char *)svcparam_buffer->context.ptr, target, target_len); svcparam_buffer->context.ptr += target_len; + if (is_aligned(svcparam_buffer->context.ptr, 2) != 1) { + if (_dns_left_len(&svcparam_buffer->context) < 1) { + return -1; + } + + _dns_write_char(&svcparam_buffer->context.ptr, 0); + } + return 0; } @@ -1266,9 +1295,17 @@ int dns_HTTPS_add_raw(struct dns_rr_nested *svcparam, unsigned short key, unsign return -1; } - dns_add_rr_nested_memcpy(svcparam, &key, 2); - dns_add_rr_nested_memcpy(svcparam, &len, 2); - dns_add_rr_nested_memcpy(svcparam, value, len); + if (dns_add_rr_nested_memcpy(svcparam, &key, 2) != 0) { + return -1; + } + + if (dns_add_rr_nested_memcpy(svcparam, &len, 2) != 0) { + return -1; + } + + if (dns_add_rr_nested_memcpy(svcparam, value, len) != 0) { + return -1; + } return 0; } @@ -1279,11 +1316,19 @@ int dns_HTTPS_add_port(struct dns_rr_nested *svcparam, unsigned short port) } unsigned short value = DNS_HTTPS_T_PORT; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } + value = 2; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } + value = htons(port); - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } return 0; } @@ -1295,11 +1340,18 @@ int dns_HTTPS_add_alpn(struct dns_rr_nested *svcparam, const char *alpn, int alp } unsigned short value = DNS_HTTPS_T_ALPN; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } value = alpn_len; - dns_add_rr_nested_memcpy(svcparam, &value, 2); - dns_add_rr_nested_memcpy(svcparam, alpn, alpn_len); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } + + if (dns_add_rr_nested_memcpy(svcparam, alpn, alpn_len) != 0) { + return -1; + } return 0; } @@ -1311,11 +1363,18 @@ int dns_HTTPS_add_ech(struct dns_rr_nested *svcparam, void *ech, int ech_len) } unsigned short value = DNS_HTTPS_T_ECH; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } value = ech_len; - dns_add_rr_nested_memcpy(svcparam, &value, 2); - dns_add_rr_nested_memcpy(svcparam, ech, ech_len); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } + + if (dns_add_rr_nested_memcpy(svcparam, ech, ech_len) != 0) { + return -1; + } return 0; } @@ -1327,13 +1386,19 @@ int dns_HTTPS_add_ipv4hint(struct dns_rr_nested *svcparam, unsigned char *addr[] } unsigned short value = DNS_HTTPS_T_IPV4HINT; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } value = addr_num * DNS_RR_A_LEN; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } for (int i = 0; i < addr_num; i++) { - dns_add_rr_nested_memcpy(svcparam, addr[i], DNS_RR_A_LEN); + if (dns_add_rr_nested_memcpy(svcparam, addr[i], DNS_RR_A_LEN) != 0) { + return -1; + } } return 0; @@ -1346,13 +1411,19 @@ int dns_HTTPS_add_ipv6hint(struct dns_rr_nested *svcparam, unsigned char *addr[] } unsigned short value = DNS_HTTPS_T_IPV6HINT; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } value = addr_num * DNS_RR_AAAA_LEN; - dns_add_rr_nested_memcpy(svcparam, &value, 2); + if (dns_add_rr_nested_memcpy(svcparam, &value, 2) != 0) { + return -1; + } for (int i = 0; i < addr_num; i++) { - dns_add_rr_nested_memcpy(svcparam, addr[i], DNS_RR_AAAA_LEN); + if (dns_add_rr_nested_memcpy(svcparam, addr[i], DNS_RR_AAAA_LEN) != 0) { + return -1; + } } return 0; @@ -1397,6 +1468,12 @@ int dns_get_HTTPS_svcparm_start(struct dns_rrs *rrs, struct dns_https_param **ht return -1; } + /* PADDING */ + if (is_aligned(data, 2) != 1) { + data++; + rr_len--; + } + if (rr_len == 0) { *https_param = NULL; return 0; diff --git a/src/dns_client.c b/src/dns_client.c index f814d4ff90..770e52e594 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -569,7 +569,6 @@ static struct dns_server_info *_dns_client_get_server(char *server_ip, int port, continue; } - pthread_mutex_unlock(&client.server_list_lock); server_info_return = server_info; break; } diff --git a/src/fast_ping.c b/src/fast_ping.c index e9429384bf..4ee3e4f11a 100644 --- a/src/fast_ping.c +++ b/src/fast_ping.c @@ -84,7 +84,6 @@ struct fast_ping_packet_msg { struct timeval tv; unsigned int sid; unsigned int seq; - unsigned int cookie; }; struct fast_ping_packet { @@ -121,7 +120,7 @@ struct ping_host_struct { char host[PING_MAX_HOSTLEN]; int fd; - unsigned int seq; + unsigned short seq; int ttl; struct timeval last; int interval; @@ -129,8 +128,7 @@ struct ping_host_struct { int count; int send; int run; - unsigned int cookie; - unsigned int sid; + unsigned short sid; unsigned short port; unsigned short ss_family; union { @@ -140,6 +138,8 @@ struct ping_host_struct { }; socklen_t addr_len; struct fast_ping_packet packet; + /* for memory address alignment */ + struct fast_ping_packet recv_packet_buffer; struct fast_ping_fake_ip *fake; int fake_time_fd; @@ -726,7 +726,6 @@ static int _fast_ping_sendping_v6(struct ping_host_struct *ping_host) gettimeofday(&packet->msg.tv, NULL); gettimeofday(&ping_host->last, NULL); packet->msg.sid = ping_host->sid; - packet->msg.cookie = ping_host->cookie; packet->msg.seq = ping_host->seq; icmp6->icmp6_cksum = _fast_ping_checksum((void *)packet, sizeof(struct fast_ping_packet)); @@ -812,7 +811,6 @@ static int _fast_ping_sendping_v4(struct ping_host_struct *ping_host) gettimeofday(&ping_host->last, NULL); packet->msg.sid = ping_host->sid; packet->msg.seq = ping_host->seq; - packet->msg.cookie = ping_host->cookie; icmp->icmp_cksum = _fast_ping_checksum((void *)packet, sizeof(struct fast_ping_packet)); len = sendto(ping.fd_icmp, packet, sizeof(struct fast_ping_packet), 0, &ping_host->addr, ping_host->addr_len); @@ -1409,7 +1407,6 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c char ip_str[PING_MAX_HOSTLEN]; int port = -1; FAST_PING_TYPE ping_type = FAST_PING_END; - unsigned int seed = 0; int ret = 0; struct fast_ping_fake_ip *fake = NULL; int fake_time_fd = -1; @@ -1438,8 +1435,6 @@ struct ping_host_struct *fast_ping_start(PING_TYPE type, const char *host, int c atomic_set(&ping_host->ref, 0); atomic_set(&ping_host->notified, 0); ping_host->sid = atomic_inc_return(&ping_sid); - seed = ping_host->sid; - ping_host->cookie = rand_r(&seed); ping_host->run = 0; if (ping_callback) { ping_host->ping_callback = ping_callback; @@ -1546,6 +1541,11 @@ static struct fast_ping_packet *_fast_ping_icmp6_packet(struct ping_host_struct struct cmsghdr *c = NULL; int hops = 0; + if (data_len < (int)sizeof(struct icmp6_hdr)) { + tlog(TLOG_DEBUG, "ping package length is invalid, %d, %d", data_len, (int)sizeof(struct fast_ping_packet)); + return NULL; + } + for (c = CMSG_FIRSTHDR(msg); c; c = CMSG_NXTHDR(msg, c)) { if (c->cmsg_level != IPPROTO_IPV6) { continue; @@ -1593,12 +1593,32 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct * int hlen = 0; int icmp_len = 0; - hlen = ip->ip_hl << 2; - packet = (struct fast_ping_packet *)(packet_data + hlen); + if (ping.no_unprivileged_ping) { + hlen = ip->ip_hl << 2; + if (ip->ip_p != IPPROTO_ICMP) { + tlog(TLOG_DEBUG, "ip type failed, %d:%d", ip->ip_p, IPPROTO_ICMP); + return NULL; + } + } + + if (data_len - hlen < (int)sizeof(struct icmp)) { + tlog(TLOG_DEBUG, "response ping package length is invalid, len: %d", data_len); + return NULL; + } + + if ((uintptr_t)(packet_data + hlen) % __alignof__(void *) == 0 || ping.no_unprivileged_ping == 0) { + packet = (struct fast_ping_packet *)(packet_data + hlen); + } else { + int copy_len = sizeof(ping_host->recv_packet_buffer); + if (copy_len > data_len - hlen) { + copy_len = data_len - hlen; + } + memcpy(&ping_host->recv_packet_buffer, packet_data + hlen, copy_len); + packet = &ping_host->recv_packet_buffer; + } + icmp = &packet->icmp; icmp_len = data_len - hlen; - packet->ttl = ip->ip_ttl; - if (icmp_len < 16) { tlog(TLOG_ERROR, "length is invalid, %d", icmp_len); return NULL; @@ -1609,18 +1629,12 @@ static struct fast_ping_packet *_fast_ping_icmp_packet(struct ping_host_struct * return NULL; } - if (ping.no_unprivileged_ping) { - if (ip->ip_p != IPPROTO_ICMP) { - tlog(TLOG_ERROR, "ip type failed, %d:%d", ip->ip_p, IPPROTO_ICMP); - return NULL; - } - - if (icmp->icmp_id != ping.ident) { - tlog(TLOG_ERROR, "ident failed, %d:%d", icmp->icmp_id, ping.ident); - return NULL; - } + if (icmp->icmp_id != ping.ident && ping.no_unprivileged_ping) { + tlog(TLOG_WARN, "ident failed, %d:%d", icmp->icmp_id, ping.ident); + return NULL; } + packet->ttl = ip->ip_ttl; return packet; } @@ -1689,7 +1703,6 @@ static int _fast_ping_process_icmp(struct ping_host_struct *ping_host, struct ti struct timeval *tvsend = NULL; unsigned int sid = 0; unsigned int seq = 0; - unsigned int cookie = 0; struct msghdr msg; struct iovec iov; char ans_data[4096]; @@ -1726,14 +1739,13 @@ static int _fast_ping_process_icmp(struct ping_host_struct *ping_host, struct ti tvsend = &packet->msg.tv; sid = packet->msg.sid; seq = packet->msg.seq; - cookie = packet->msg.cookie; addrkey = _fast_ping_hash_key(sid, (struct sockaddr *)&from); pthread_mutex_lock(&ping.map_lock); hash_for_each_possible(ping.addrmap, recv_ping_host, addr_node, addrkey) { if (_fast_ping_sockaddr_ip_cmp(&recv_ping_host->addr, recv_ping_host->addr_len, (struct sockaddr *)&from, from_len) == 0 && - recv_ping_host->sid == sid && recv_ping_host->cookie == cookie) { + recv_ping_host->sid == sid) { _fast_ping_host_get(recv_ping_host); break; }