Place a limit on the number of elements in a ber sequence/set. This prevents
authorrob <rob@openbsd.org>
Fri, 3 Aug 2018 01:51:28 +0000 (01:51 +0000)
committerrob <rob@openbsd.org>
Fri, 3 Aug 2018 01:51:28 +0000 (01:51 +0000)
possible stack overflow due to recursion in ber_free_elements().

ok claudio@

usr.bin/ldap/ber.c
usr.bin/ldap/ber.h
usr.sbin/ldapd/ber.c
usr.sbin/ldapd/ber.h
usr.sbin/snmpd/ber.c
usr.sbin/snmpd/ber.h
usr.sbin/ypldap/ber.c
usr.sbin/ypldap/ber.h

index f2543f2..2aa24b1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.c,v 1.17 2018/07/31 19:38:09 rob Exp $ */
+/*     $OpenBSD: ber.c,v 1.18 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -1156,7 +1156,7 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
        long long val = 0;
        struct ber_element *next;
        unsigned int type;
-       int i, class, cstruct;
+       int i, class, cstruct, elements = 0;
        ssize_t len, r, totlen = 0;
        u_char c;
 
@@ -1250,9 +1250,18 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
                }
                next = elm->be_sub;
                while (len > 0) {
+                       /*
+                        * Prevent stack overflow from excessive recursion
+                        * depth in ber_free_elements().
+                        */
+                       if (elements >= BER_MAX_SEQ_ELEMENTS) {
+                               errno = ERANGE;
+                               return -1;
+                       }
                        r = ber_read_element(ber, next);
                        if (r == -1)
                                return -1;
+                       elements++;
                        len -= r;
                        if (len > 0 && next->be_next == NULL) {
                                if ((next->be_next = ber_get_element(0)) ==
index 9c76a81..ee20c56 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.h,v 1.5 2018/07/31 11:02:01 claudio Exp $ */
+/*     $OpenBSD: ber.h,v 1.6 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -75,8 +75,9 @@ struct ber {
 #define BER_CLASS_MASK         0x3
 
 /* common definitions */
-#define BER_MIN_OID_LEN                2       /* OBJECT */
-#define BER_MAX_OID_LEN                32      /* OBJECT */
+#define BER_MIN_OID_LEN                2               /* OBJECT */
+#define BER_MAX_OID_LEN                32              /* OBJECT */
+#define BER_MAX_SEQ_ELEMENTS   USHRT_MAX       /* 65535 */
 
 struct ber_oid {
        u_int32_t       bo_id[BER_MAX_OID_LEN + 1];
index 08280db..2a53f6e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.c,v 1.27 2018/07/31 19:38:09 rob Exp $ */
+/*     $OpenBSD: ber.c,v 1.28 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -1156,7 +1156,7 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
        long long val = 0;
        struct ber_element *next;
        unsigned int type;
-       int i, class, cstruct;
+       int i, class, cstruct, elements = 0;
        ssize_t len, r, totlen = 0;
        u_char c;
 
@@ -1250,9 +1250,18 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
                }
                next = elm->be_sub;
                while (len > 0) {
+                       /*
+                        * Prevent stack overflow from excessive recursion
+                        * depth in ber_free_elements().
+                        */
+                       if (elements >= BER_MAX_SEQ_ELEMENTS) {
+                               errno = ERANGE;
+                               return -1;
+                       }
                        r = ber_read_element(ber, next);
                        if (r == -1)
                                return -1;
+                       elements++;
                        len -= r;
                        if (len > 0 && next->be_next == NULL) {
                                if ((next->be_next = ber_get_element(0)) ==
index d7d1963..5e9c7ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.h,v 1.6 2018/07/31 11:01:00 claudio Exp $ */
+/*     $OpenBSD: ber.h,v 1.7 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -75,8 +75,9 @@ struct ber {
 #define BER_CLASS_MASK         0x3
 
 /* common definitions */
-#define BER_MIN_OID_LEN                2       /* OBJECT */
-#define BER_MAX_OID_LEN                32      /* OBJECT */
+#define BER_MIN_OID_LEN                2               /* OBJECT */
+#define BER_MAX_OID_LEN                32              /* OBJECT */
+#define BER_MAX_SEQ_ELEMENTS   USHRT_MAX       /* 65535 */
 
 struct ber_oid {
        u_int32_t       bo_id[BER_MAX_OID_LEN + 1];
index 0f9b51d..e767754 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.c,v 1.46 2018/07/31 19:38:09 rob Exp $ */
+/*     $OpenBSD: ber.c,v 1.47 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -1156,7 +1156,7 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
        long long val = 0;
        struct ber_element *next;
        unsigned int type;
-       int i, class, cstruct;
+       int i, class, cstruct, elements = 0;
        ssize_t len, r, totlen = 0;
        u_char c;
 
@@ -1250,9 +1250,18 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
                }
                next = elm->be_sub;
                while (len > 0) {
+                       /*
+                        * Prevent stack overflow from excessive recursion
+                        * depth in ber_free_elements().
+                        */
+                       if (elements >= BER_MAX_SEQ_ELEMENTS) {
+                               errno = ERANGE;
+                               return -1;
+                       }
                        r = ber_read_element(ber, next);
                        if (r == -1)
                                return -1;
+                       elements++;
                        len -= r;
                        if (len > 0 && next->be_next == NULL) {
                                if ((next->be_next = ber_get_element(0)) ==
index e886584..8679798 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.h,v 1.12 2018/07/31 11:01:29 claudio Exp $ */
+/*     $OpenBSD: ber.h,v 1.13 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -75,8 +75,9 @@ struct ber {
 #define BER_CLASS_MASK         0x3
 
 /* common definitions */
-#define BER_MIN_OID_LEN                2       /* OBJECT */
-#define BER_MAX_OID_LEN                32      /* OBJECT */
+#define BER_MIN_OID_LEN                2               /* OBJECT */
+#define BER_MAX_OID_LEN                32              /* OBJECT */
+#define BER_MAX_SEQ_ELEMENTS   USHRT_MAX       /* 65535 */
 
 struct ber_oid {
        u_int32_t       bo_id[BER_MAX_OID_LEN + 1];
index 5829298..e575b49 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.c,v 1.29 2018/07/31 19:38:09 rob Exp $ */
+/*     $OpenBSD: ber.c,v 1.30 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -1156,7 +1156,7 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
        long long val = 0;
        struct ber_element *next;
        unsigned int type;
-       int i, class, cstruct;
+       int i, class, cstruct, elements = 0;
        ssize_t len, r, totlen = 0;
        u_char c;
 
@@ -1250,9 +1250,18 @@ ber_read_element(struct ber *ber, struct ber_element *elm)
                }
                next = elm->be_sub;
                while (len > 0) {
+                       /*
+                        * Prevent stack overflow from excessive recursion
+                        * depth in ber_free_elements().
+                        */
+                       if (elements >= BER_MAX_SEQ_ELEMENTS) {
+                               errno = ERANGE;
+                               return -1;
+                       }
                        r = ber_read_element(ber, next);
                        if (r == -1)
                                return -1;
+                       elements++;
                        len -= r;
                        if (len > 0 && next->be_next == NULL) {
                                if ((next->be_next = ber_get_element(0)) ==
index 55e6cd4..9e7b45e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ber.h,v 1.7 2018/07/31 11:00:12 claudio Exp $ */
+/*     $OpenBSD: ber.h,v 1.8 2018/08/03 01:51:28 rob Exp $ */
 
 /*
  * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -75,8 +75,9 @@ struct ber {
 #define BER_CLASS_MASK         0x3
 
 /* common definitions */
-#define BER_MIN_OID_LEN                2       /* OBJECT */
-#define BER_MAX_OID_LEN                32      /* OBJECT */
+#define BER_MIN_OID_LEN                2               /* OBJECT */
+#define BER_MAX_OID_LEN                32              /* OBJECT */
+#define BER_MAX_SEQ_ELEMENTS   USHRT_MAX       /* 65535 */
 
 struct ber_oid {
        u_int32_t       bo_id[BER_MAX_OID_LEN + 1];