Fix all UBSAN warnings triggered by tests.
authorKirill Isakov <is-kir@ya.ru>
Fri, 23 Jul 2021 16:37:49 +0000 (22:37 +0600)
committerKirill Isakov <is-kir@ya.ru>
Sun, 25 Jul 2021 14:51:02 +0000 (20:51 +0600)
src/hash.c
src/net_setup.c
src/route.c
src/sptps.c
src/sptps.h
src/subnet_parse.c
src/utils.c

index 63b8f54..39e88c9 100644 (file)
@@ -29,11 +29,11 @@ static uint32_t hash_function(const void *p, size_t len) {
        uint32_t hash = 0;
 
        while(true) {
-               for(int i = len > 4 ? 4 : len; --i;) {
+               for(size_t i = len > 4 ? 4 : len; --i;) {
                        hash += (uint32_t)q[len - i] << (8 * i);
                }
 
-               hash *= 0x9e370001UL; // Golden ratio prime.
+               hash = (uint32_t)(hash * 0x9e370001UL); // Golden ratio prime.
 
                if(len <= 4) {
                        break;
index 1257151..a04f953 100644 (file)
@@ -231,7 +231,7 @@ static bool read_ecdsa_private_key(void) {
                return false;
        }
 
-       if(s.st_mode & ~0100700) {
+       if(s.st_mode & ~0100700u) {
                logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname);
        }
 
@@ -323,7 +323,7 @@ static bool read_rsa_private_key(void) {
                return false;
        }
 
-       if(s.st_mode & ~0100700) {
+       if(s.st_mode & ~0100700u) {
                logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname);
        }
 
index d1048e7..3fe6edb 100644 (file)
@@ -63,7 +63,7 @@ static timeout_t age_subnets_timeout;
 
 /* RFC 1071 */
 
-static uint16_t inet_checksum(void *vdata, int len, uint16_t prevsum) {
+static uint16_t inet_checksum(void *vdata, size_t len, uint16_t prevsum) {
        uint8_t *data = vdata;
        uint16_t word;
        uint32_t checksum = prevsum ^ 0xFFFF;
@@ -83,7 +83,7 @@ static uint16_t inet_checksum(void *vdata, int len, uint16_t prevsum) {
                checksum = (checksum & 0xFFFF) + (checksum >> 16);
        }
 
-       return ~checksum;
+       return (uint16_t) ~checksum;
 }
 
 static bool ratelimit(int frequency) {
@@ -199,7 +199,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_
        ip.ip_src = ip_dst;
        ip.ip_dst = ip_src;
 
-       ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
+       ip.ip_sum = inet_checksum(&ip, ip_size, 0xFFFF);
 
        /* Fill in ICMP header */
 
@@ -207,7 +207,7 @@ static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_
        icmp.icmp_code = code;
        icmp.icmp_cksum = 0;
 
-       icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0);
+       icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, 0xFFFF);
        icmp.icmp_cksum = inet_checksum(DATA(packet) + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum);
 
        /* Copy structs on stack back to packet */
@@ -312,7 +312,7 @@ static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_
 
        /* Generate checksum */
 
-       checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
+       checksum = inet_checksum(&pseudo, sizeof(pseudo), 0xFFFF);
        checksum = inet_checksum(&icmp6, icmp6_size, checksum);
        checksum = inet_checksum(DATA(packet) + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum);
 
@@ -401,7 +401,7 @@ static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *pac
        }
 
        /* Find TCP header */
-       int start = ether_size;
+       size_t start = ether_size;
        uint16_t type = DATA(packet)[12] << 8 | DATA(packet)[13];
 
        if(type == ETH_P_8021Q) {
@@ -573,7 +573,7 @@ static void route_broadcast(node_t *source, vpn_packet_t *packet) {
 static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) {
        struct ip ip;
        vpn_packet_t fragment;
-       int maxlen, todo;
+       size_t maxlen, todo;
        uint8_t *offset;
        uint16_t ip_off, origf;
 
@@ -601,7 +601,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et
        ip_off &= IP_OFFMASK;
 
        while(todo) {
-               int len = todo > maxlen ? maxlen : todo;
+               size_t len = todo > maxlen ? maxlen : todo;
                memcpy(DATA(&fragment) + ether_size + ip_size, offset, len);
                todo -= len;
                offset += len;
@@ -609,7 +609,7 @@ static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t et
                ip.ip_len = htons(ip_size + len);
                ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0));
                ip.ip_sum = 0;
-               ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
+               ip.ip_sum = inet_checksum(&ip, ip_size, 0xFFFF);
                memcpy(DATA(&fragment), DATA(packet), ether_size);
                memcpy(DATA(&fragment) + ether_size, &ip, ip_size);
                fragment.len = ether_size + ip_size + len;
@@ -857,7 +857,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) {
 
        /* Generate checksum */
 
-       checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
+       checksum = inet_checksum(&pseudo, sizeof(pseudo), 0xFFFF);
        checksum = inet_checksum(&ns, ns_size, checksum);
 
        if(has_opt) {
@@ -931,7 +931,7 @@ static void route_neighborsol(node_t *source, vpn_packet_t *packet) {
 
        /* Generate checksum */
 
-       checksum = inet_checksum(&pseudo, sizeof(pseudo), ~0);
+       checksum = inet_checksum(&pseudo, sizeof(pseudo), 0xFFFF);
        checksum = inet_checksum(&ns, ns_size, checksum);
 
        if(has_opt) {
index eeaf833..6ad1c8d 100644 (file)
@@ -92,7 +92,7 @@ static void warning(sptps_t *s, const char *format, ...) {
 
 // Send a record (datagram version, accepts all record types, handles encryption and authentication).
 static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const void *data, uint16_t len) {
-       char buffer[len + 21UL];
+       uint8_t buffer[len + 21UL];
 
        // Create header with sequence number, length and record type
        uint32_t seqno = s->outseqno++;
@@ -117,7 +117,7 @@ static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_
                return send_record_priv_datagram(s, type, data, len);
        }
 
-       char buffer[len + 19UL];
+       uint8_t buffer[len + 19UL];
 
        // Create header with sequence number, length and record type
        uint32_t seqno = s->outseqno++;
@@ -187,8 +187,8 @@ static bool send_sig(sptps_t *s) {
        size_t siglen = ecdsa_size(s->mykey);
 
        // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label
-       char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
-       char sig[siglen];
+       uint8_t msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
+       uint8_t sig[siglen];
 
        msg[0] = s->initiator;
        memcpy(msg + 1, s->mykex, 1 + 32 + keylen);
@@ -253,7 +253,7 @@ static bool send_ack(sptps_t *s) {
 }
 
 // Receive an ACKnowledgement record.
-static bool receive_ack(sptps_t *s, const char *data, uint16_t len) {
+static bool receive_ack(sptps_t *s, const uint8_t *data, uint16_t len) {
        (void)data;
 
        if(len) {
@@ -278,7 +278,7 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) {
 }
 
 // Receive a Key EXchange record, respond by sending a SIG record.
-static bool receive_kex(sptps_t *s, const char *data, uint16_t len) {
+static bool receive_kex(sptps_t *s, const uint8_t *data, uint16_t len) {
        // Verify length of the HELLO record
        if(len != 1 + 32 + ECDH_SIZE) {
                return error(s, EIO, "Invalid KEX record length");
@@ -307,7 +307,7 @@ static bool receive_kex(sptps_t *s, const char *data, uint16_t len) {
 }
 
 // Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys.
-static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
+static bool receive_sig(sptps_t *s, const uint8_t *data, uint16_t len) {
        size_t keylen = ECDH_SIZE;
        size_t siglen = ecdsa_size(s->hiskey);
 
@@ -317,7 +317,7 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
        }
 
        // Concatenate both KEX messages, plus tag indicating if it is from the connection originator
-       char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
+       uint8_t msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
 
        msg[0] = !s->initiator;
        memcpy(msg + 1, s->hiskex, 1 + 32 + keylen);
@@ -383,7 +383,7 @@ bool sptps_force_kex(sptps_t *s) {
 }
 
 // Receive a handshake record.
-static bool receive_handshake(sptps_t *s, const char *data, uint16_t len) {
+static bool receive_handshake(sptps_t *s, const uint8_t *data, uint16_t len) {
        // Only a few states to deal with handshaking.
        switch(s->state) {
        case SPTPS_SECONDARY_KEX:
@@ -528,7 +528,7 @@ bool sptps_verify_datagram(sptps_t *s, const void *vdata, size_t len) {
 }
 
 // Receive incoming data, datagram version.
-static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len) {
+static bool sptps_receive_data_datagram(sptps_t *s, const uint8_t *data, size_t len) {
        if(len < (s->instate ? 21 : 5)) {
                return error(s, EIO, "Received short packet");
        }
@@ -558,7 +558,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len
 
        // Decrypt
 
-       char buffer[len];
+       uint8_t buffer[len];
        size_t outlen;
 
        if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) {
@@ -599,7 +599,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len
 
 // Receive incoming data. Check if it contains a complete record, if so, handle it.
 size_t sptps_receive_data(sptps_t *s, const void *vdata, size_t len) {
-       const char *data = vdata;
+       const uint8_t *data = vdata;
        size_t total_read = 0;
 
        if(!s->state) {
index f5686f4..1da0af8 100644 (file)
@@ -50,7 +50,7 @@ typedef struct sptps {
        bool datagram;
        int state;
 
-       char *inbuf;
+       uint8_t *inbuf;
        size_t buflen;
        uint16_t reclen;
 
index 32b7e0a..d877c7f 100644 (file)
@@ -186,9 +186,7 @@ static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) {
 }
 
 int subnet_compare(const subnet_t *a, const subnet_t *b) {
-       int result;
-
-       result = a->type - b->type;
+       int result = (int)a->type - (int)b->type;
 
        if(result) {
                return result;
index c9f3085..f14094f 100644 (file)
@@ -54,7 +54,7 @@ static int charhex2bin(char c) {
 }
 
 size_t hex2bin(const char *src, void *vdst, size_t length) {
-       char *dst = vdst;
+       uint8_t *dst = vdst;
        size_t i;
 
        for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++) {
@@ -67,7 +67,8 @@ size_t hex2bin(const char *src, void *vdst, size_t length) {
 size_t bin2hex(const void *vsrc, char *dst, size_t length) {
        const char *src = vsrc;
 
-       for(size_t i = length; i-- > 0;) {
+       for(size_t i = length; i > 0;) {
+               --i;
                dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15];
                dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4];
        }