From: rob Date: Fri, 3 Aug 2018 01:51:28 +0000 (+0000) Subject: Place a limit on the number of elements in a ber sequence/set. This prevents X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=477e6dcfe2d7469b85e3760c740ba1e301b2f016;p=openbsd 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@ --- diff --git a/usr.bin/ldap/ber.c b/usr.bin/ldap/ber.c index f2543f23bbe..2aa24b12777 100644 --- a/usr.bin/ldap/ber.c +++ b/usr.bin/ldap/ber.c @@ -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 @@ -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.bin/ldap/ber.h b/usr.bin/ldap/ber.h index 9c76a815179..ee20c56ba99 100644 --- a/usr.bin/ldap/ber.h +++ b/usr.bin/ldap/ber.h @@ -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 @@ -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/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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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];