Forráskód Böngészése

minor changes.
- Remove all usage of variable length arrays.
- BReactor: when doing epoll_ctl(EPOLL_CTL_MOD), pass a valid struct epoll_event, to work on ancient
kernels.
- misc/ipaddr.h: cleanup

ambrop7 14 éve
szülő
commit
aaf0717949

+ 4 - 5
INSTALL

@@ -3,13 +3,15 @@
 1.1 Operating system
 
 Linux:
-- kernel version >=2.6.22 (for epoll and signalfd)
-- glibc >=2.8 (for epoll and signalfd)
+- Linux kernel 2.6. Kernel 2.4 will work, but performance will suffer.
 - tested on x86, x86_64 and ARM architectures. Not tested on any big-endian architecture.
 
 Windows:
 - Windows XP or newer; tested on Windows XP and Windows 7
 
+FreeBSD:
+- Not regularly tested.
+
 Other systems are not supported.
 
 1.2 Compilers
@@ -25,15 +27,12 @@ Windows:
 C language features used:
   - Standard (all part of C99):
     - designated initializers
-    - variable length arrays as automatic variables
     - stdint.h, inttypes.h, stddef.h
     - intermingled declarations and code
     - for loop initial declaration
     - one-line "//" comments
   - Extensions:
-    - statements and declarations in expressions
     - packed structure attribute (to pack a structure and allow unaligned access)
-    - __alignof__ for querying the required alignment of types
 
 1.3 CMake
 

+ 3 - 3
client/SPProtoDecoder.c

@@ -69,7 +69,7 @@ static void decode_work_func (SPProtoDecoder *o)
         }
         
         // copy IV as BEncryption_Decrypt changes the IV
-        uint8_t iv[o->enc_block_size];
+        uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE];
         memcpy(iv, in, o->enc_block_size);
         
         // decrypt
@@ -125,12 +125,12 @@ static void decode_work_func (SPProtoDecoder *o)
     if (SPPROTO_HAVE_HASH(o->sp_params)) {
         uint8_t *header_hash = header + SPPROTO_HEADER_HASH_OFF(o->sp_params);
         // read hash
-        uint8_t hash[o->hash_size];
+        uint8_t hash[BHASH_MAX_SIZE];
         memcpy(hash, header_hash, o->hash_size);
         // zero hash in packet
         memset(header_hash, 0, o->hash_size);
         // calculate hash
-        uint8_t hash_calc[o->hash_size];
+        uint8_t hash_calc[BHASH_MAX_SIZE];
         BHash_calculate(o->sp_params.hash_mode, plaintext, plaintext_len, hash_calc);
         // set hash field to its original value
         memcpy(header_hash, hash, o->hash_size);

+ 2 - 2
client/SPProtoEncoder.c

@@ -108,7 +108,7 @@ static void encode_work_func (SPProtoEncoder *o)
         // zero hash field
         memset(header_hash, 0, o->hash_size);
         // calculate hash
-        uint8_t hash[o->hash_size];
+        uint8_t hash[BHASH_MAX_SIZE];
         BHash_calculate(o->sp_params.hash_mode, plaintext, plaintext_len, hash);
         // set hash field
         memcpy(header_hash, hash, o->hash_size);
@@ -130,7 +130,7 @@ static void encode_work_func (SPProtoEncoder *o)
         BRandom_randomize(o->out, o->enc_block_size);
         
         // copy IV because BEncryption_Encrypt changes the IV
-        uint8_t iv[o->enc_block_size];
+        uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE];
         memcpy(iv, o->out, o->enc_block_size);
         
         // encrypt

+ 5 - 11
client/client.c

@@ -36,6 +36,7 @@
 #include <misc/nsskey.h>
 #include <misc/loglevel.h>
 #include <misc/loggers_string.h>
+#include <misc/string_begins_with.h>
 #include <structure/LinkedList2.h>
 #include <base/DebugObject.h>
 #include <base/BLog.h>
@@ -1169,15 +1170,8 @@ int process_arguments (void)
             POINTER(eout, out->ext_addrs[out->num_ext_addrs])
             
             // read addr
-            char *colon = strstr(eaddr->addr, ":");
-            if (!colon) {
-                BLog(BLOG_ERROR, "ext addr: no colon");
-                return 0;
-            }
-            char addrstr[colon - eaddr->addr + 1];
-            memcpy(addrstr, eaddr->addr, colon - eaddr->addr);
-            addrstr[colon - eaddr->addr] = '\0';
-            if (!strcmp(addrstr, "{server_reported}")) {
+            if (string_begins_with(eaddr->addr, "{server_reported}:")) {
+                char *colon = strstr(eaddr->addr, ":");
                 if ((eout->server_reported_port = atoi(colon + 1)) < 0) {
                     BLog(BLOG_ERROR, "ext addr: wrong port");
                     return 0;
@@ -2172,11 +2166,11 @@ void peer_bind_one_address (struct peer_data *peer, int addr_index, int *cont)
             return;
         }
         
-        uint8_t key[SPPROTO_HAVE_ENCRYPTION(sp_params) ? BEncryption_cipher_key_size(sp_params.encryption_mode) : 0];
+        uint8_t key[BENCRYPTION_MAX_KEY_SIZE];
         
         // generate and set encryption key
         if (SPPROTO_HAVE_ENCRYPTION(sp_params)) {
-            BRandom_randomize(key, sizeof(key));
+            BRandom_randomize(key, BEncryption_cipher_key_size(sp_params.encryption_mode));
             DatagramPeerIO_SetEncryptionKey(&peer->pio.udp.pio, key);
         }
         

+ 2 - 3
dhcpclient/BDHCPClient.c

@@ -172,11 +172,10 @@ int BDHCPClient_Init (BDHCPClient *o, const char *ifname, BReactor *reactor, BDH
     
     // set socket filter
     {
-        size_t flen = sizeof(dhcp_sock_filter) / sizeof(dhcp_sock_filter[0]);
-        struct sock_filter filter[flen];
+        struct sock_filter filter[sizeof(dhcp_sock_filter) / sizeof(dhcp_sock_filter[0])];
         memcpy(filter, dhcp_sock_filter, sizeof(filter));
         struct sock_fprog fprog = {
-            .len = flen,
+            .len = sizeof(filter) / sizeof(filter[0]),
             .filter = filter
         };
         if (setsockopt(BDatagram_GetFd(&o->dgram), SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0) {

+ 4 - 4
examples/bencryption_bench.c

@@ -87,11 +87,11 @@ int main (int argc, char **argv)
     int key_size = BEncryption_cipher_key_size(cipher);
     int block_size = BEncryption_cipher_block_size(cipher);
     
-    uint8_t key[key_size];
-    BRandom_randomize(key, sizeof(key));
+    uint8_t key[BENCRYPTION_MAX_KEY_SIZE];
+    BRandom_randomize(key, key_size);
     
-    uint8_t iv[block_size];
-    BRandom_randomize(iv, sizeof(iv));
+    uint8_t iv[BENCRYPTION_MAX_BLOCK_SIZE];
+    BRandom_randomize(iv, block_size);
     
     if (num_blocks > INT_MAX / block_size) {
         printf("too much");

+ 3 - 3
misc/bsort.h

@@ -32,12 +32,13 @@
 #include <string.h>
 
 #include <misc/debug.h>
+#include <misc/balloc.h>
 
 typedef int (*BSort_comparator) (const void *e1, const void *e2);
 
-static void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator compatator);
+static void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator compatator, void *temp);
 
-void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator compatator)
+void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator compatator, void *temp)
 {
     ASSERT(esize > 0)
     
@@ -50,7 +51,6 @@ void BInsertionSort (void *arr, size_t count, size_t esize, BSort_comparator com
             if (c <= 0) {
                 break;
             }
-            uint8_t temp[esize];
             memcpy(temp, x, esize);
             memcpy(x, y, esize);
             memcpy(y, temp, esize);

+ 17 - 41
misc/ipaddr.h

@@ -33,6 +33,7 @@
 
 #include <misc/debug.h>
 #include <misc/byteorder.h>
+#include <misc/parse_number.h>
 
 struct ipv4_ifaddr {
     uint32_t addr;
@@ -41,47 +42,18 @@ struct ipv4_ifaddr {
 
 static int ipaddr_parse_ipv4_addr_bin (char *name, size_t name_len, uint32_t *out_addr);
 static int ipaddr_parse_ipv4_addr (char *name, uint32_t *out_addr);
+static int ipaddr_parse_ipv4_prefix_bin (char *str, size_t str_len, int *num);
 static int ipaddr_parse_ipv4_prefix (char *str, int *num);
 static int ipaddr_parse_ipv4_ifaddr (char *str, struct ipv4_ifaddr *out);
 static int ipaddr_ipv4_ifaddr_from_addr_mask (uint32_t addr, uint32_t mask, struct ipv4_ifaddr *out);
 static int ipaddr_ipv4_mask_from_prefix (int prefix);
 static int ipaddr_ipv4_addrs_in_network (uint32_t addr1, uint32_t addr2, int netprefix);
 
-static int ipaddr_char_is_digit (char c)
-{
-    return (c >= '0' && c <= '9');
-}
-
-static int ipaddr_parse_number (char *data, size_t data_len, int *out)
-{
-    if (data_len == 0) {
-        return 0;
-    }
-    
-    for (size_t i = 0; i < data_len; i++) {
-        if (!ipaddr_char_is_digit(data[i])) {
-            return 0;
-        }
-    }
-    
-    char data2[data_len + 1];
-    memcpy(data2, data, data_len);
-    data2[data_len] = '\0';
-    
-    *out = atoi(data2);
-    
-    return 1;
-}
-
 int ipaddr_parse_ipv4_addr_bin (char *name, size_t name_len, uint32_t *out_addr)
 {
     for (size_t i = 0; ; i++) {
         size_t j;
-        for (j = 0; j < name_len && name[j] != '.'; j++) {
-            if (!ipaddr_char_is_digit(name[j])) {
-                return 0;
-            }
-        }
+        for (j = 0; j < name_len && name[j] != '.'; j++);
         
         if ((j == name_len && i < 3) || (j < name_len && i == 3)) {
             return 0;
@@ -91,8 +63,8 @@ int ipaddr_parse_ipv4_addr_bin (char *name, size_t name_len, uint32_t *out_addr)
             return 0;
         }
         
-        int d;
-        if (!ipaddr_parse_number(name, j, &d)) {
+        uintmax_t d;
+        if (!parse_unsigned_integer_bin(name, j, &d)) {
             return 0;
         }
         
@@ -116,17 +88,25 @@ int ipaddr_parse_ipv4_addr (char *name, uint32_t *out_addr)
     return ipaddr_parse_ipv4_addr_bin(name, strlen(name), out_addr);
 }
 
-int ipaddr_parse_ipv4_prefix (char *str, int *num)
+int ipaddr_parse_ipv4_prefix_bin (char *str, size_t str_len, int *num)
 {
-    if (strlen(str) > 2 || !ipaddr_parse_number(str, strlen(str), num)) {
+    uintmax_t d;
+    if (!parse_unsigned_integer_bin(str, str_len, &d)) {
         return 0;
     }
-    if (*num > 32) {
+    if (d > 32) {
         return 0;
     }
+    
+    *num = d;
     return 1;
 }
 
+int ipaddr_parse_ipv4_prefix (char *str, int *num)
+{
+    return ipaddr_parse_ipv4_prefix_bin(str, strlen(str), num);
+}
+
 int ipaddr_parse_ipv4_ifaddr (char *str, struct ipv4_ifaddr *out)
 {
     char *slash = strstr(str, "/");
@@ -145,11 +125,7 @@ int ipaddr_parse_ipv4_ifaddr (char *str, struct ipv4_ifaddr *out)
         return 0;
     }
     
-    if (!ipaddr_parse_number(prefix, prefix_len, &out->prefix)) {
-        return 0;
-    }
-    
-    if (out->prefix > 32) {
+    if (!ipaddr_parse_ipv4_prefix_bin(prefix, prefix_len, &out->prefix)) {
         return 0;
     }
     

+ 12 - 3
misc/parse_number.h

@@ -28,18 +28,21 @@
 #define BADVPN_MISC_PARSE_NUMBER_H
 
 #include <inttypes.h>
+#include <string.h>
+#include <stddef.h>
 
+static int parse_unsigned_integer_bin (const char *str, size_t str_len, uintmax_t *out);
 static int parse_unsigned_integer (const char *str, uintmax_t *out);
 
-int parse_unsigned_integer (const char *str, uintmax_t *out)
+int parse_unsigned_integer_bin (const char *str, size_t str_len, uintmax_t *out)
 {
     uintmax_t n = 0;
     
-    if (!*str) {
+    if (str_len == 0) {
         return 0;
     }
     
-    while (*str) {
+    while (str_len > 0) {
         if (*str < '0' || *str > '9') {
             return 0;
         }
@@ -56,10 +59,16 @@ int parse_unsigned_integer (const char *str, uintmax_t *out)
         n += digit;
         
         str++;
+        str_len--;
     }
     
     *out = n;
     return 1;
 }
 
+int parse_unsigned_integer (const char *str, uintmax_t *out)
+{
+    return parse_unsigned_integer_bin(str, strlen(str), out);
+}
+
 #endif

+ 25 - 5
ncd/NCDIfConfig.c

@@ -104,7 +104,11 @@ fail0:
 
 int NCDIfConfig_set_up (const char *ifname)
 {
-    char cmd[50 + strlen(ifname)];
+    if (strlen(ifname) >= IFNAMSIZ) {
+        return 0;
+    }
+    
+    char cmd[50 + IFNAMSIZ];
     sprintf(cmd, IP_CMD" link set %s up", ifname);
     
     return !run_command(cmd);
@@ -112,7 +116,11 @@ int NCDIfConfig_set_up (const char *ifname)
 
 int NCDIfConfig_set_down (const char *ifname)
 {
-    char cmd[50 + strlen(ifname)];
+    if (strlen(ifname) >= IFNAMSIZ) {
+        return 0;
+    }
+    
+    char cmd[50 + IFNAMSIZ];
     sprintf(cmd, IP_CMD" link set %s down", ifname);
     
     return !run_command(cmd);
@@ -123,9 +131,13 @@ int NCDIfConfig_add_ipv4_addr (const char *ifname, struct ipv4_ifaddr ifaddr)
     ASSERT(ifaddr.prefix >= 0)
     ASSERT(ifaddr.prefix <= 32)
     
+    if (strlen(ifname) >= IFNAMSIZ) {
+        return 0;
+    }
+    
     uint8_t *addr = (uint8_t *)&ifaddr.addr;
     
-    char cmd[50 + strlen(ifname)];
+    char cmd[50 + IFNAMSIZ];
     sprintf(cmd, IP_CMD" addr add %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d dev %s", addr[0], addr[1], addr[2], addr[3], ifaddr.prefix, ifname);
     
     return !run_command(cmd);
@@ -136,9 +148,13 @@ int NCDIfConfig_remove_ipv4_addr (const char *ifname, struct ipv4_ifaddr ifaddr)
     ASSERT(ifaddr.prefix >= 0)
     ASSERT(ifaddr.prefix <= 32)
     
+    if (strlen(ifname) >= IFNAMSIZ) {
+        return 0;
+    }
+    
     uint8_t *addr = (uint8_t *)&ifaddr.addr;
     
-    char cmd[50 + strlen(ifname)];
+    char cmd[50 + IFNAMSIZ];
     sprintf(cmd, IP_CMD" addr del %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"/%d dev %s", addr[0], addr[1], addr[2], addr[3], ifaddr.prefix, ifname);
     
     return !run_command(cmd);
@@ -156,7 +172,7 @@ static int route_cmd (const char *cmdtype, struct ipv4_ifaddr dest, const uint32
         const uint8_t *g_addr = (uint8_t *)gateway;
         sprintf(gwstr, " via %"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8, g_addr[0], g_addr[1], g_addr[2], g_addr[3]);
     } else {
-        sprintf(gwstr, "");
+        gwstr[0] = '\0';
     }
     
     char cmd[100];
@@ -222,6 +238,10 @@ fail0:
 
 static int open_tuntap (const char *ifname, int flags)
 {
+    if (strlen(ifname) >= IFNAMSIZ) {
+        return 0;
+    }
+    
     int fd = open(TUN_DEVNODE, O_RDWR);
     if (fd < 0) {
          BLog(BLOG_ERROR, "open tun failed");

+ 22 - 5
ncd/modules/net_dns.c

@@ -31,6 +31,7 @@
 
 #include <misc/offset.h>
 #include <misc/bsort.h>
+#include <misc/balloc.h>
 #include <structure/LinkedList2.h>
 #include <ncd/NCDModule.h>
 #include <ncd/NCDIfConfig.h>
@@ -129,11 +130,16 @@ static int dns_sort_comparator (const void *v1, const void *v2)
 
 static int set_servers (void)
 {
+    int ret = 0;
+    
     // count servers
     size_t num_ipv4_dns_servers = num_servers();
     
     // allocate sort array
-    struct dns_sort_entry servers[num_ipv4_dns_servers];
+    struct dns_sort_entry *servers = BAllocArray(num_ipv4_dns_servers, sizeof(servers[0]));
+    if (!servers) {
+        goto fail0;
+    }
     size_t num_servers = 0;
     
     // fill sort array
@@ -156,20 +162,31 @@ static int set_servers (void)
     
     // sort by priority
     // use a custom insertion sort instead of qsort() because we want a stable sort
-    BInsertionSort(servers, num_servers, sizeof(servers[0]), dns_sort_comparator);
+    struct dns_sort_entry sort_temp;
+    BInsertionSort(servers, num_servers, sizeof(servers[0]), dns_sort_comparator, &sort_temp);
     
     // copy addresses into an array
-    uint32_t addrs[num_servers];
+    uint32_t *addrs = BAllocArray(num_servers, sizeof(addrs[0]));
+    if (!addrs) {
+        goto fail1;
+    }
     for (size_t i = 0; i < num_servers; i++) {
         addrs[i] = servers[i].addr;
     }
     
     // set servers
     if (!NCDIfConfig_set_dns_servers(addrs, num_servers)) {
-        return 0;
+        goto fail2;
     }
     
-    return 1;
+    ret = 1;
+    
+fail2:
+    BFree(addrs);
+fail1:
+    BFree(servers);
+fail0:
+    return ret;
 }
 
 static int func_globalinit (struct NCDModuleInitParams params)

+ 2 - 1
predicate/BPredicate.c

@@ -26,6 +26,7 @@
 
 #include <misc/debug.h>
 #include <misc/offset.h>
+#include <misc/balloc.h>
 #include <predicate/BPredicate_internal.h>
 #include <predicate/BPredicate_parser.h>
 #include <predicate/LexMemoryBufferInput.h>
@@ -68,7 +69,7 @@ static int eval_function (BPredicate *p, struct predicate_node *root)
     
     // evaluate arguments
     struct arguments_node *arg = root->function.args;
-    void *args[func->num_args];
+    void *args[PREDICATE_MAX_ARGS];
     for (int i = 0; i < func->num_args; i++) {
         if (!arg) {
             BLog(BLOG_WARNING, "not enough arguments");

+ 2 - 0
security/BHash.h

@@ -40,6 +40,8 @@
 #define BHASH_TYPE_SHA1 2
 #define BHASH_TYPE_SHA1_SIZE 20
 
+#define BHASH_MAX_SIZE 20
+
 /**
  * Checks if the given hash type number is valid.
  * 

+ 2 - 2
security/OTPCalculator.c

@@ -72,11 +72,11 @@ otp_t * OTPCalculator_Generate (OTPCalculator *calc, uint8_t *key, uint8_t *iv,
     ASSERT(shuffle == 0 || shuffle == 1)
     
     // copy IV so it can be updated
-    uint8_t iv_work[calc->block_size];
+    uint8_t iv_work[BENCRYPTION_MAX_BLOCK_SIZE];
     memcpy(iv_work, iv, calc->block_size);
     
     // create zero block
-    uint8_t zero[calc->block_size];
+    uint8_t zero[BENCRYPTION_MAX_BLOCK_SIZE];
     memset(zero, 0, calc->block_size);
     
     // init encryptor

+ 3 - 1
system/BReactor.c

@@ -1082,7 +1082,9 @@ void BReactor_RemoveFileDescriptor (BReactor *bsys, BFileDescriptor *bs)
     #ifdef BADVPN_USE_EPOLL
     
     // delete epoll entry
-    ASSERT_FORCE(epoll_ctl(bsys->efd, EPOLL_CTL_DEL, bs->fd, NULL) == 0)
+    struct epoll_event event;
+    memset(&event, 0, sizeof(event));
+    ASSERT_FORCE(epoll_ctl(bsys->efd, EPOLL_CTL_DEL, bs->fd, &event) == 0)
     
     // write through epoll returned pointer
     if (bs->epoll_returned_ptr) {

+ 5 - 1
tests/bproto_test.c

@@ -3,6 +3,7 @@
 #include <stdio.h>
 
 #include <misc/debug.h>
+#include <misc/balloc.h>
 
 #include <generated/bproto_bproto_test.h>
 
@@ -20,7 +21,8 @@ int main ()
     
     int len = msg1_SIZEa + msg1_SIZEc + msg1_SIZEd + msg1_SIZEd + msg1_SIZEe + msg1_SIZEf(strlen(f)) + msg1_SIZEg;
     
-    uint8_t msg[len];
+    uint8_t *msg = BAlloc(len);
+    ASSERT_FORCE(msg)
     msg1Writer writer;
     msg1Writer_Init(&writer, msg);
     msg1Writer_Adda(&writer, a);
@@ -68,5 +70,7 @@ int main ()
     
     ASSERT(msg1Parser_GotEverything(&parser))
     
+    BFree(msg);
+    
     return 0;
 }