It looks like a BER problem found while testing the new ldap client (with an
empty password) was already addressed in snmpd back in 2010 by martinh.

In LDAP under a CONTEXT class, 0 corresponds to LDAP_AUTH_SIMPLE. This is
currently interpreted as an EOC (end-of-content) and causes a
miscalculation of the length which results in unexpected behaviour.

Reyk pointed me in the right direction, and after much messing around I came
up with a solution which was close to the following snmpd commit.

>From the src/usr.sbin/snmpd/ber.c commit log:

----------------------------
revision 1.23
date: 2010/09/20 08:30:13;  author: martinh;  state: Exp;  lines: +3 -2;
Allow output of null values with a context class. This is used in SNMPv2 to
return an error exception value for a varbind result ("noSuchObject[0]
IMPLICIT NULL" in rfc1905).
----------------------------

However, BER_TYPE_EOC only applies to the UNIVERSAL class, so I think an
explicit check against BER_CLASS_UNIVERSAL is a better solution and works
across both ldap and snmp.

The following diff applies this change to ldap, ldapd, and ypldap, and brings
snmpd in line with this approach.

Thoughts?

Ok?

Index: usr.bin/ldap/ber.c
===================================================================
RCS file: /cvs/src/usr.bin/ldap/ber.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 ber.c
--- usr.bin/ldap/ber.c  13 Jun 2018 15:45:57 -0000      1.1.1.1
+++ usr.bin/ldap/ber.c  24 Jun 2018 21:37:39 -0000
@@ -861,7 +861,8 @@ ber_calc_len(struct ber_element *root)
                size += ber_calc_len(root->be_next);
 
        /* This is an empty element, do not use a minimal size */
-       if (root->be_type == BER_TYPE_EOC && root->be_len == 0)
+       if (root->be_class == BER_CLASS_UNIVERSAL &&
+           root->be_type == BER_TYPE_EOC && root->be_len == 0)
                return (0);
 
        return (root->be_len + size);

Index: usr.sbin/ldapd/ber.c
===================================================================
RCS file: /cvs/src/usr.sbin/ldapd/ber.c,v
retrieving revision 1.13
diff -u -p -r1.13 ber.c
--- usr.sbin/ldapd/ber.c        8 Feb 2018 18:02:06 -0000       1.13
+++ usr.sbin/ldapd/ber.c        24 Jun 2018 21:37:39 -0000
@@ -874,7 +874,8 @@ ber_calc_len(struct ber_element *root)
                size += ber_calc_len(root->be_next);
 
        /* This is an empty element, do not use a minimal size */
-       if (root->be_type == BER_TYPE_EOC && root->be_len == 0)
+       if (root->be_class == BER_CLASS_UNIVERSAL &&
+           root->be_type == BER_TYPE_EOC && root->be_len == 0)
                return (0);
 
        return (root->be_len + size);

Index: usr.sbin/ypldap/ber.c
===================================================================
RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v
retrieving revision 1.13
diff -u -p -r1.13 ber.c
--- usr.sbin/ypldap/ber.c       8 Feb 2018 18:02:06 -0000       1.13
+++ usr.sbin/ypldap/ber.c       24 Jun 2018 21:37:39 -0000
@@ -861,7 +861,8 @@ ber_calc_len(struct ber_element *root)
                size += ber_calc_len(root->be_next);
 
        /* This is an empty element, do not use a minimal size */
-       if (root->be_type == BER_TYPE_EOC && root->be_len == 0)
+       if (root->be_class == BER_CLASS_UNIVERSAL &&
+           root->be_type == BER_TYPE_EOC && root->be_len == 0)
                return (0);
 
        return (root->be_len + size);

Index: usr.sbin/snmpd/ber.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v
retrieving revision 1.32
diff -u -p -r1.32 ber.c
--- usr.sbin/snmpd/ber.c        8 Feb 2018 18:02:06 -0000       1.32
+++ usr.sbin/snmpd/ber.c        24 Jun 2018 21:37:39 -0000
@@ -880,7 +880,7 @@ ber_calc_len(struct ber_element *root)
                size += ber_calc_len(root->be_next);
 
        /* This is an empty element, do not use a minimal size */
-       if (root->be_class != BER_CLASS_CONTEXT &&
+       if (root->be_class == BER_CLASS_UNIVERSAL &&
            root->be_type == BER_TYPE_EOC && root->be_len == 0)
                return (0);
 

Reply via email to