Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server control requests get eaten after a NULL character in the berval #40

Closed
phillipod opened this issue Nov 30, 2015 · 6 comments
Closed
Assignees
Labels
Milestone

Comments

@phillipod
Copy link
Collaborator

Hi,

I was looking into the syncrepl issue reported by Nat Sincheler, which I guess is the syncrepl issue you mentioned in #14. I don't think I've identified his issue, but we're definitely not handling BER correctly - in what appears to be a mirror of #28

net-ldapapi/LDAPapi.pm: 

sub create_control {
# SNIP
    my $status = ldap_create_control($oid, $berval, length($berval), $critical, $ctrl);
# SNIP
}

net-ldapapi/LDAPapi.xs:

int ldap_create_control(oid, bv_val, bv_len, iscritical, ctrlp) {
/* SNIP */
        ctrl->ldctl_value.bv_val = ber_strdup(bv_val);
        ctrl->ldctl_value.bv_len = bv_len;
/* SNIP */
}

openldap/libraries/liblber/memory.c:

char * ber_strdup( LDAP_CONST char *s ) {
        return ber_strdup_x( s, NULL );
}

char *ber_strdup_x( LDAP_CONST char *s, void *ctx ) {
        char    *p;
        size_t  len;
/* SNIP */
        len = strlen( s ) + 1;
        if ( (p = ber_memalloc_x( len, ctx )) != NULL ) {
                AC_MEMCPY( p, s, len );
        }

        return p;
}

If a berval containing an otherwise valid '\x00' byte is attempted to be passed, all data after the '\x00' byte will be discarded due to strlen() stopping at '\x00', say for instance the 'beforeCount' on a VLV control.

Using the sample code in #28, but changing 'beforeCount' to 0, I get this:

===== Server Side Sort and Virtual List View
 + Loading ASN for SortKeyList, SortResult, VirtualListViewRequest, VirtualListViewResponse
 + Constructing Server Side Sort control
sss ctrl berval =
[0000]   30 13 30 11  04 02 73 6E  80 08 32 2E  35 2E 31 33   0.0. ..sn ..2. 5.13
[0010]   2E 33 81 01  FF                                      .3.. .
 + Constructing Virtual List View control
vlv ctrl berval =
[0000]   30 0E 02 01  00 02 01 03  A0 06 02 01  01 02 01 00   0... .... .... ....
 + Searching for results
 - Fail
Protocol error
 + Parsing first entry
perl: error.c:255: ldap_parse_result: Assertion `r != ((void *)0)' failed.
Aborted

However, with the following change:

--- LDAPapi.xs.old      2015-06-14 04:54:23.000000000 +1200
+++ LDAPapi.xs  2015-12-01 00:53:17.000000000 +1300
@@ -1863,8 +1863,7 @@
         LDAPControl *ctrl = malloc(sizeof(LDAPControl));

         ctrl->ldctl_oid          = ber_strdup(oid);
-        ctrl->ldctl_value.bv_val = ber_strdup(bv_val);
-        ctrl->ldctl_value.bv_len = bv_len;
+       ber_str2bv(bv_val, bv_len, 1, &ctrl->ldctl_value);
         ctrl->ldctl_iscritical   = iscritical;

         ctrlp = ctrl;

I get this output:

===== Server Side Sort and Virtual List View
 + Loading ASN for SortKeyList, SortResult, VirtualListViewRequest, VirtualListViewResponse
 + Constructing Server Side Sort control
sss ctrl berval =
[0000]   30 13 30 11  04 02 73 6E  80 08 32 2E  35 2E 31 33   0.0. ..sn ..2. 5.13
[0010]   2E 33 81 01  FF                                      .3.. .
 + Constructing Virtual List View control
vlv ctrl berval =
[0000]   30 0E 02 01  00 02 01 03  A0 06 02 01  01 02 01 00   0... .... .... ....
 + Searching for results
 + Parsing first entry
result = $VAR1 = {
          'matcheddn' => undef,
          'referrals' => [],
          'errmsg' => undef,
          'serverctrls' => [
                             32738608,
                             27748368
                           ],
          'errcode' => 0
        };
 + Reading result-scope server response controls
 + Response control 32738608 [1.2.840.113556.1.4.474]
berval =
[0000]   30 03 0A 01  00                                      0... .
 + Parsing SSS response berval
$VAR1 = {
          'sortResult' => 0
        };
 + Response control 27748368 [2.16.840.1.113730.3.4.10]
berval =
[0000]   30 14 02 01  01 02 02 7E  B0 0A 01 00  04 08 50 0E   0... ...~ .... ..P.
[0010]   97 02 00 00  00 00                                   .... ..
 + Parsing VLV response berval
$VAR1 = {
          'contextID' => 'P',
          'contentCount' => 32432,
          'virtualListViewResult' => 0,
          'targetPosition' => 1
        };
 + Search results
dn: cn=Test User,ou=Users,o=Test Data,c=nz
dn: cn=Ani Odey,ou=Users,o=Test Data,c=nz
dn: cn=Vevelyn Odette,ou=Users,o=Test Data,c=nz
dn: cn=Donyetta Odett,ou=Users,o=Test Data,c=nz

To sum up - does it make sense to replace the ber_strdup() with ber_str2bv() in the XS wrapper ldap_create_control() ?

As I say, I don't think this is related to the syncrepl issue - but only because I don't see how a '\x00' character could be inserted into the BER of 'mode' on the syncRequestValue....

Perhaps there is another way we should be reading the user-provided BER? Otherwise, I'm happy to prepare a pull request for this, targeting a 3.0.5 or 3.1.x release

Cheers,
Phillip

@phillipod phillipod added the bug label Nov 30, 2015
@phillipod
Copy link
Collaborator Author

As an aside, should 'ber_strdup_x' in liblber really be using strlen()? :)

@hyc
Copy link
Collaborator

hyc commented Nov 30, 2015

Yes, ber_strdup is meant for C strings and C strings are NUL-terminated, by definition. But obviously you should not be using it on values that are not C strings. Likewise you cannot use ber_str2bv, for the same reason.

You should be using ber_dupbv, which is meant for bervals.

@quanah
Copy link
Owner

quanah commented Nov 30, 2015

@phillipod Want to hold 3.0.4 for this to be fixed?

@phillipod
Copy link
Collaborator Author

@hyc okay, makes sense about ber_strdup and ber_str2bv. But ber_dupbv seems to indicate that it is duplicating an existing struct berval to another struct berval - which seems kind of redundant when the code is trying to build a struct berval from just a chunk of memory?

What about ber_mem2bv? It seems to have the right semantics of not ever using strlen unlike ber_strdup and ber_str2bv, and it doesn't require the source to be a struct berval. Keep in mind that the underlying perl representation of the input should be a SVpv with a defined length instead of a NULL-terminated string.

@phillipod
Copy link
Collaborator Author

@quanah actually, yeah, might as well.

@hyc
Copy link
Collaborator

hyc commented Nov 30, 2015

phillipod wrote:

@hyc https://github.com/hyc okay, makes sense about /ber_strdup/ and
/ber_str2bv/. But /ber_dupbv/ seems to indicate that it is duplicating an
existing /struct berval/ to another /struct berval/ - which seems kind of
redundant when the code is trying to build a /struct berval/ from just a chunk
of memory?

What about /ber_mem2bv/? It seems to have the right semantics of not ever
using /strlen/ unlike /ber_strdup/ and /ber_str2bv/, and it doesn't require
the source to be a /struct berval/. Keep in mind that the underlying perl
representation of the input should be a SVpv with a defined length instead of
a NULL-terminated string.

Yeah, mem2bv should do fine.

-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/

phillipod added a commit to phillipod/net-ldapapi that referenced this issue Dec 1, 2015
…racter in the berval

- Adds Virtual List View to the server control testing with beforeCount set to 0 to provide a regression test for quanah#40
@quanah quanah closed this as completed in #41 Dec 1, 2015
quanah added a commit that referenced this issue Dec 1, 2015
…als_with_nulls

- Fixes #40: Server control requests get eaten after a NULL character in the berval
phillipod added a commit that referenced this issue Dec 1, 2015
… in the berval

- Adds Virtual List View to the server control testing with beforeCount set to 0 to provide a regression test for #40
@phillipod phillipod added this to the 3.0.4 milestone Dec 1, 2015
@phillipod phillipod self-assigned this Dec 1, 2015
rra pushed a commit to whm/libnet-ldapapi-perl that referenced this issue Dec 25, 2020
  * New upstream release.
  * Fix undef comparison
  * Misc variable initializations to quiet warnings
  * Fixed sasl mechanisms initializtion
  * Examples cleanup
  * LDAPv3 extended operation support
  * New developer mode test suite
  * Fixed quanah/net-ldapapi#3: ldap_set_rebind_proc XS being called with
    invalid arguments from set_rebind_proc
  * Fixed quanah/net-ldapapi#6: ldap_sasl_bind has wrong prototype in
    LDAPapi.xs
  * Fixed quanah/net-ldapapi#8: search_s() clobbers ATTRS parameter
  * Fixed quanah/net-ldapapi#11: result() blocking when called with output
    from rename()
  * Fixed quanah/net-ldapapi#20: ldap_result() doesn't honour passed
    timeout value
  * Fixed quanah/net-ldapapi#21: ldap_set_option(LDAP_OPT_TIMEOUT, 1) on
    OpenLDAP returns -1
  * Fixed quanah/net-ldapapi#28: Server control responses get eaten after
    a NULL character in the berval
  * Fixed quanah/net-ldapapi#30: ldap_search_ext() and ldap_search_ext_s()
    segfault when used with timeout
  * Fixed quanah/net-ldapapi#31: ldap_result() and ldap_url_search_st()
    timeout parameters have a granularity of 1 second
  * Fixed quanah/net-ldapapi#40: Server control requests get eaten after a
    NULL character in the berval
  * Correct merge problem with POD error.
  * Update standards version to 3.9.8 (no changes required).

[dgit import package libnet-ldapapi-perl 3.0.4-1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants