From f758b35ec97fc6e58ef4b4d93eddd1ea53772356 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Fri, 3 Feb 2017 17:17:22 -0800 Subject: [PATCH 1/2] Ticket #49121 - ns-slapd crashes in ldif_sput due to the output buf size is less than the real size. Description: Invalid memory writes are reported in the openldap function ldif_sput. The function wraps around at the 78th byte by default. The output buffer did not contain the spaces for '\n's. This patch prepares the extra room for the '\n's by replacing LDIF_SIZE_ NEEDED with LDIF_SIZE_NEEDED_WRAP in entry2str_internal_size_value to prevent the shortage of the output buffer. In addition, we pass the full length of the ldif line as the wrap width to ldif_sput_wrap that should avoid wrapping if LDIF_OPT_NOWRAP option is given to slapi_ldif_put_type_ and_value_with_options. --- ldap/servers/slapd/entry.c | 5 ++++- ldap/servers/slapd/ldaputil.c | 20 ++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c index 51ca3cc..598eb66 100644 --- a/ldap/servers/slapd/entry.c +++ b/ldap/servers/slapd/entry.c @@ -1464,7 +1464,10 @@ entry2str_internal_size_value( const char *attrtype, const Slapi_Value *v, attrtypelen += DELETED_VALUE_STRSIZE; } } - elen = LDIF_SIZE_NEEDED(attrtypelen, slapi_value_get_berval(v)->bv_len); +/* compatibility with U-Mich off by two bug */ +#define LDIF_KLUDGE 2 + /* Allocate conservative size for openldap ldif_sput with the default wrap width. */ + elen = LDIF_SIZE_NEEDED_WRAP(attrtypelen, slapi_value_get_berval(v)->bv_len, LDIF_LINE_WIDTH+LDIF_KLUDGE); bail: return elen; } diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c index ca16588..10c3014 100644 --- a/ldap/servers/slapd/ldaputil.c +++ b/ldap/servers/slapd/ldaputil.c @@ -443,23 +443,19 @@ slapi_ldif_put_type_and_value_with_options( char **out, const char *t, const cha /* openldap always wraps and always does conservative base64 encoding we unwrap here, but clients will have to do their own base64 decode */ int type = LDIF_PUT_VALUE; - char *save = *out; if (options & LDIF_OPT_VALUE_IS_URL) { type = LDIF_PUT_URL; } - ldif_sput( out, type, t, val, vlen ); if (options & LDIF_OPT_NOWRAP) { - /* modify out in place, stripping out continuation lines */ - char *src = save; - char *dest = save; - for (; src < *out; ++src) { - if ((src < (*out - 2)) && !strncmp(src, "\n ", 2)) { - src += 2; /* skip continuation */ - } - *dest++ = *src; - } - *out = dest; /* move 'out' back if we removed some continuation lines */ + /* + * Make the estimated size of "key: value" the wrap width to aviod wrapping in ldif_sput_wrap. + * format -- type:[:] value'\0' + */ + ber_len_t wrap = (ber_len_t)((t ? strlen(t) : 0) + LDIF_BASE64_LEN(vlen) + 4); + ldif_sput_wrap( out, type, t, val, vlen, wrap ); + } else { + ldif_sput( out, type, t, val, vlen ); } #else ldif_put_type_and_value_with_options( out, (char *)t, (char *)val, vlen, options ); -- 2.9.3