chiark / gitweb /
SECURITY: actually reject messages with improper lengths
[secnet.git] / ipaddr.c
index b941295e7558b71da549ea0b496fc8046c0dc6dd..f8cda00eabbc3f6c5dac170c249a9cb8211572b0 100644 (file)
--- a/ipaddr.c
+++ b/ipaddr.c
@@ -2,7 +2,10 @@
    inspired by the 'ipaddr.py' library from Cendio Systems AB. */
 
 #include "secnet.h"
+#include <limits.h>
+#include <assert.h>
 #include <stdio.h>
+#include <string.h>
 #include "ipaddr.h"
 
 #define DEFAULT_ALLOC 2
@@ -14,7 +17,7 @@ struct subnet_list *subnet_list_new(void)
     r=safe_malloc(sizeof(*r),"subnet_list_new:list");
     r->entries=0;
     r->alloc=DEFAULT_ALLOC;
-    r->list=safe_malloc(sizeof(*r->list)*r->alloc,"subnet_list_new:data");
+    r->list=safe_malloc_ary(sizeof(*r->list),r->alloc,"subnet_list_new:data");
     return r;
 }
 
@@ -24,12 +27,13 @@ void subnet_list_free(struct subnet_list *a)
     free(a);
 }
 
-static void subnet_list_set_len(struct subnet_list *a, uint32_t l)
+static void subnet_list_set_len(struct subnet_list *a, int32_t l)
 {
     struct subnet *nd;
-    uint32_t na;
+    int32_t na;
 
     if (l>a->alloc) {
+       assert(a->alloc < (int)(INT_MAX/sizeof(*nd))-EXTEND_ALLOC_BY);
        na=a->alloc+EXTEND_ALLOC_BY;
        nd=realloc(a->list,sizeof(*nd)*na);
        if (!nd) {
@@ -41,9 +45,10 @@ static void subnet_list_set_len(struct subnet_list *a, uint32_t l)
     a->entries=l;
 }
 
-void subnet_list_append(struct subnet_list *a, uint32_t prefix, uint32_t len)
+void subnet_list_append(struct subnet_list *a, uint32_t prefix, int len)
 {
     struct subnet *sn;
+    assert(a->entries < INT_MAX);
     subnet_list_set_len(a,a->entries+1);
     sn=&a->list[a->entries-1];
     sn->prefix=prefix;
@@ -70,7 +75,7 @@ void ipset_free(struct ipset *a)
 #ifdef DEBUG
 static void ipset_dump(struct ipset *a, string_t name)
 {
-    uint32_t i;
+    int32_t i;
 
     printf("%s: ",name);
     for (i=0; i<a->l; i++) {
@@ -94,7 +99,7 @@ struct ipset *ipset_from_subnet(struct subnet s)
 struct ipset *ipset_from_subnet_list(struct subnet_list *l)
 {
     struct ipset *r, *a, *b;
-    uint32_t i;
+    int32_t i;
 
     r=ipset_new();
     for (i=0; i<l->entries; i++) {
@@ -107,12 +112,13 @@ struct ipset *ipset_from_subnet_list(struct subnet_list *l)
     return r;
 }
 
-static void ipset_set_len(struct ipset *a, uint32_t l)
+static void ipset_set_len(struct ipset *a, int32_t l)
 {
     struct iprange *nd;
-    uint32_t na;
+    int32_t na;
 
     if (l>a->a) {
+       assert(a->a < INT_MAX-EXTEND_ALLOC_BY);
        na=a->a+EXTEND_ALLOC_BY;
        nd=realloc(a->d,sizeof(*nd)*na);
        if (!nd) {
@@ -135,7 +141,7 @@ struct ipset *ipset_union(struct ipset *a, struct ipset *b)
 {
     struct ipset *c;
     struct iprange r;
-    uint32_t ia,ib;
+    int32_t ia,ib;
 
     c=ipset_new();
     ia=0; ib=0;
@@ -166,7 +172,7 @@ struct ipset *ipset_intersection(struct ipset *a, struct ipset *b)
 {
     struct ipset *r;
     struct iprange ra, rb;
-    uint32_t ia,ib;
+    int32_t ia,ib;
 
     r=ipset_new();
     ia=0; ib=0;
@@ -214,7 +220,8 @@ struct ipset *ipset_complement(struct ipset *a)
     struct ipset *r;
     struct iprange n;
     int64_t pre;
-    uint32_t i,lo,hi;
+    int32_t i;
+    uint32_t lo,hi;
 
     r=ipset_new();
     pre=-1;
@@ -253,7 +260,7 @@ bool_t ipset_is_empty(struct ipset *a)
 
 bool_t ipset_contains_addr(struct ipset *a, uint32_t addr)
 {
-    uint32_t i;
+    int32_t i;
     struct iprange r;
 
     for (i=0; i<a->l; i++) {
@@ -284,8 +291,8 @@ struct subnet_list *ipset_to_subnet_list(struct ipset *is)
 {
     struct subnet_list *r;
     int64_t a,b,lobit,himask,lomask;
-    int32_t bits;
-    uint32_t i;
+    int bits;
+    int32_t i;
 
     r=subnet_list_new();
     for (i=0; i<is->l; i++) {
@@ -346,13 +353,13 @@ string_t subnet_to_string(struct subnet sn)
     return s;
 }
 
-static struct subnet string_item_to_subnet(item_t *i, string_t desc,
+static struct subnet string_item_to_subnet(item_t *i, cstring_t desc,
                                           bool_t *invert)
 {
     struct subnet s;
     uint32_t a, b, c, d, n;
-    uint32_t match;
-    string_t in;
+    int match;
+    cstring_t in;
 
     *invert=False;
 
@@ -397,10 +404,10 @@ static struct subnet string_item_to_subnet(item_t *i, string_t desc,
     return s;
 }
 
-uint32_t string_item_to_ipaddr(item_t *i, string_t desc)
+uint32_t string_item_to_ipaddr(item_t *i, cstring_t desc)
 {
     uint32_t a, b, c, d;
-    uint32_t match;
+    int match;
 
     /* i is not guaranteed to be a string */
     if (i->type!=t_string) {
@@ -419,7 +426,7 @@ uint32_t string_item_to_ipaddr(item_t *i, string_t desc)
 }
 
 struct ipset *string_list_to_ipset(list_t *l, struct cloc loc,
-                                  string_t module, string_t param)
+                                  cstring_t module, cstring_t param)
 {
     struct ipset *r, *n, *isn;
     uint32_t e,i;