summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorrob <rob@cvs.openbsd.org>2018-08-03 01:51:29 +0000
committerrob <rob@cvs.openbsd.org>2018-08-03 01:51:29 +0000
commitf9b8d3d18d16b42b4cc0446e221ec6a5b123df33 (patch)
tree1c190f4b212426d7e49d261a96023b484e0f6a00 /usr.sbin
parentf7eba6032a0373a25ae53dc4c7e488b5002edb37 (diff)
Place a limit on the number of elements in a ber sequence/set. This prevents
possible stack overflow due to recursion in ber_free_elements(). ok claudio@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ldapd/ber.c13
-rw-r--r--usr.sbin/ldapd/ber.h7
-rw-r--r--usr.sbin/snmpd/ber.c13
-rw-r--r--usr.sbin/snmpd/ber.h7
-rw-r--r--usr.sbin/ypldap/ber.c13
-rw-r--r--usr.sbin/ypldap/ber.h7
6 files changed, 45 insertions, 15 deletions
diff --git a/usr.sbin/ldapd/ber.c b/usr.sbin/ldapd/ber.c
index 08280dbeed7..2a53f6efa2a 100644
--- a/usr.sbin/ldapd/ber.c
+++ b/usr.sbin/ldapd/ber.c
@@ -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)) ==
diff --git a/usr.sbin/ldapd/ber.h b/usr.sbin/ldapd/ber.h
index d7d19631104..5e9c7aeacfa 100644
--- a/usr.sbin/ldapd/ber.h
+++ b/usr.sbin/ldapd/ber.h
@@ -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];
diff --git a/usr.sbin/snmpd/ber.c b/usr.sbin/snmpd/ber.c
index 0f9b51d4a60..e767754ac81 100644
--- a/usr.sbin/snmpd/ber.c
+++ b/usr.sbin/snmpd/ber.c
@@ -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)) ==
diff --git a/usr.sbin/snmpd/ber.h b/usr.sbin/snmpd/ber.h
index e8865849a30..8679798a8ea 100644
--- a/usr.sbin/snmpd/ber.h
+++ b/usr.sbin/snmpd/ber.h
@@ -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];
diff --git a/usr.sbin/ypldap/ber.c b/usr.sbin/ypldap/ber.c
index 5829298a650..e575b4930e6 100644
--- a/usr.sbin/ypldap/ber.c
+++ b/usr.sbin/ypldap/ber.c
@@ -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)) ==
diff --git a/usr.sbin/ypldap/ber.h b/usr.sbin/ypldap/ber.h
index 55e6cd44eb2..9e7b45e7ad3 100644
--- a/usr.sbin/ypldap/ber.h
+++ b/usr.sbin/ypldap/ber.h
@@ -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];