Blame SOURCES/0086-CVE-2017-15134-389-ds-base-Remote-DoS-via-search-fil.patch

6f51e1
From 040c492b4beb0efcd34b8420f682187441767055 Mon Sep 17 00:00:00 2001
6f51e1
From: Mark Reynolds <mreynolds@redhat.com>
6f51e1
Date: Tue, 16 Jan 2018 09:46:49 -0500
6f51e1
Subject: [PATCH] CVE-2017-15134 389-ds-base: Remote DoS via search filters in
6f51e1
 slapi_filter_sprintf
8a4a2a
6f51e1
Description: Improper handling of a search filter in slapi_filter_sprintf
6f51e1
             in slapd/util.c can lead to remote server crash and denial
6f51e1
             of service.
6f51e1
6f51e1
https://bugzilla.redhat.com/show_bug.cgi?id=1529117
8a4a2a
---
8a4a2a
 ldap/servers/slapd/util.c | 36 +++++++++++++++++++++++++++++++-----
8a4a2a
 1 file changed, 31 insertions(+), 5 deletions(-)
8a4a2a
8a4a2a
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
6f51e1
index 4ff6d4141..ffeeff6f3 100644
8a4a2a
--- a/ldap/servers/slapd/util.c
8a4a2a
+++ b/ldap/servers/slapd/util.c
6f51e1
@@ -224,9 +224,10 @@ escape_string_for_filename(const char *str, char buf[BUFSIZ])
6f51e1
 
6f51e1
 struct filter_ctx {
6f51e1
   char *buf;
6f51e1
-  char attr[ATTRSIZE];
6f51e1
+  char *attr;
6f51e1
   int attr_position;
6f51e1
   int attr_found;
6f51e1
+  size_t attr_size;
6f51e1
   int buf_size;
6f51e1
   int buf_len;
6f51e1
   int next_arg_needs_esc_norm;
6f51e1
@@ -265,7 +266,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
8a4a2a
      *  Start collecting the attribute name so we can use the correct
8a4a2a
      *  syntax normalization func.
8a4a2a
      */
6f51e1
-    if(ctx->attr_found == 0 && ctx->attr_position < (ATTRSIZE - 1)){
6f51e1
+    if(ctx->attr_found == 0 && ctx->attr_position < (ctx->attr_size - 1)) {
6f51e1
         if(ctx->attr[0] == '\0'){
6f51e1
             if(strstr(val,"=")){
8a4a2a
                 /* we have an attr we need to record */
6f51e1
@@ -279,6 +280,14 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
8a4a2a
                  *  attr with val.  The next pass should be '=', otherwise we will
8a4a2a
                  *  reset it.
8a4a2a
                  */
8a4a2a
+                if (slen > ctx->attr_size) {
8a4a2a
+                    if (ctx->attr_size == ATTRSIZE) {
8a4a2a
+                        ctx->attr = slapi_ch_calloc(sizeof(char), slen+1);
8a4a2a
+                    } else {
8a4a2a
+                        ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (slen+1));
8a4a2a
+                    }
8a4a2a
+                    ctx->attr_size = slen+1;
8a4a2a
+                }
8a4a2a
                 memcpy(ctx->attr, val, slen);
8a4a2a
                 ctx->attr_position = slen;
8a4a2a
             }
6f51e1
@@ -288,9 +297,20 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
8a4a2a
             } else {
6f51e1
                 if(special_attr_char(val[0])){
8a4a2a
                     /* this is not an attribute, we should not be collecting this, reset everything */
8a4a2a
-                    memset(ctx->attr, '\0', ATTRSIZE);
8a4a2a
+                    memset(ctx->attr, '\0', ctx->attr_size);
8a4a2a
                     ctx->attr_position = 0;
8a4a2a
                 } else {
8a4a2a
+                    /* we can be adding char by char and overrun allocated size */
8a4a2a
+                    if (ctx->attr_position >= ctx->attr_size) {
8a4a2a
+                        if (ctx->attr_size == ATTRSIZE) {
8a4a2a
+                            char *ctxattr = slapi_ch_calloc(sizeof(char), ctx->attr_size + ATTRSIZE);
8a4a2a
+                            memcpy(ctxattr, ctx->attr, ctx->attr_size);
8a4a2a
+                            ctx->attr = ctxattr;
8a4a2a
+                        } else {
8a4a2a
+                            ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (ctx->attr_size + ATTRSIZE));
8a4a2a
+                        }
8a4a2a
+                        ctx->attr_size = ctx->attr_size + ATTRSIZE;
8a4a2a
+                    }
8a4a2a
                     memcpy(ctx->attr + ctx->attr_position, val, 1);
8a4a2a
                     ctx->attr_position++;
8a4a2a
                 }
6f51e1
@@ -363,7 +383,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
8a4a2a
         ctx->next_arg_needs_esc_norm = 0;
8a4a2a
         ctx->attr_found = 0;
8a4a2a
         ctx->attr_position = 0;
8a4a2a
-        memset(ctx->attr, '\0', ATTRSIZE);
8a4a2a
+        memset(ctx->attr, '\0', ctx->attr_size);
8a4a2a
         slapi_ch_free_string(&buf);
8a4a2a
 
8a4a2a
         return filter_len;
6f51e1
@@ -402,13 +422,15 @@ slapi_filter_sprintf(const char *fmt, ...)
8a4a2a
 {
8a4a2a
     struct filter_ctx ctx = {0};
8a4a2a
     va_list args;
8a4a2a
+    char attr_static[ATTRSIZE] = {0};
8a4a2a
     char *buf;
8a4a2a
     int rc;
8a4a2a
 
8a4a2a
     buf = slapi_ch_calloc(sizeof(char), FILTER_BUF + 1);
8a4a2a
     ctx.buf = buf;
6f51e1
-    memset(ctx.attr,'\0', ATTRSIZE);
6f51e1
     ctx.attr_position = 0;
8a4a2a
+    ctx.attr = attr_static;
8a4a2a
+    ctx.attr_size = ATTRSIZE;
8a4a2a
     ctx.attr_found = 0;
8a4a2a
     ctx.buf_len = FILTER_BUF;
6f51e1
     ctx.buf_size = 0;
6f51e1
@@ -424,6 +446,10 @@ slapi_filter_sprintf(const char *fmt, ...)
8a4a2a
     }
8a4a2a
     va_end(args);
8a4a2a
 
8a4a2a
+    if (ctx.attr_size > ATTRSIZE) {
8a4a2a
+        slapi_ch_free_string(&ctx.attr);
8a4a2a
+    }
8a4a2a
+
8a4a2a
     return ctx.buf;
8a4a2a
 }
8a4a2a
 
8a4a2a
-- 
8a4a2a
2.13.6
8a4a2a