Blame SOURCES/0059-CVE-2017-15134-crash-in-slapi_filter_sprintf.patch

b045b9
From cb008bcace2510f157ccec2df4e5ff254513b7c4 Mon Sep 17 00:00:00 2001
b045b9
From: Ludwig Krispenz <lkrispen@redhat.com>
b045b9
Date: Mon, 15 Jan 2018 10:24:41 +0100
b045b9
Subject: [PATCH] CVE 2017-15134 - crash in slapi_filter_sprintf
a66391
b045b9
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
a66391
---
a66391
 ldap/servers/slapd/util.c | 36 +++++++++++++++++++++++++++++++-----
a66391
 1 file changed, 31 insertions(+), 5 deletions(-)
a66391
a66391
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
b045b9
index a72de9b07..ddb2cc899 100644
a66391
--- a/ldap/servers/slapd/util.c
a66391
+++ b/ldap/servers/slapd/util.c
b045b9
@@ -238,9 +238,10 @@ escape_string_for_filename(const char *str, char buf[BUFSIZ])
b045b9
 struct filter_ctx
b045b9
 {
b045b9
     char *buf;
b045b9
-    char attr[ATTRSIZE];
b045b9
+    char *attr;
b045b9
     int attr_position;
b045b9
     int attr_found;
b045b9
+    size_t attr_size;
b045b9
     int buf_size;
b045b9
     int buf_len;
b045b9
     int next_arg_needs_esc_norm;
b045b9
@@ -279,7 +280,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
a66391
      *  Start collecting the attribute name so we can use the correct
a66391
      *  syntax normalization func.
a66391
      */
b045b9
-    if (ctx->attr_found == 0 && ctx->attr_position < (ATTRSIZE - 1)) {
b045b9
+    if (ctx->attr_found == 0 && ctx->attr_position < (ctx->attr_size - 1)) {
b045b9
         if (ctx->attr[0] == '\0') {
b045b9
             if (strstr(val, "=")) {
a66391
                 /* we have an attr we need to record */
b045b9
@@ -293,6 +294,14 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
a66391
                  *  attr with val.  The next pass should be '=', otherwise we will
a66391
                  *  reset it.
a66391
                  */
a66391
+                if (slen > ctx->attr_size) {
a66391
+                    if (ctx->attr_size == ATTRSIZE) {
a66391
+                        ctx->attr = slapi_ch_calloc(sizeof(char), slen+1);
a66391
+                    } else {
a66391
+                        ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (slen+1));
a66391
+                    }
a66391
+                    ctx->attr_size = slen+1;
a66391
+                }
a66391
                 memcpy(ctx->attr, val, slen);
a66391
                 ctx->attr_position = slen;
a66391
             }
b045b9
@@ -302,9 +311,20 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
a66391
             } else {
b045b9
                 if (special_attr_char(val[0])) {
a66391
                     /* this is not an attribute, we should not be collecting this, reset everything */
a66391
-                    memset(ctx->attr, '\0', ATTRSIZE);
a66391
+                    memset(ctx->attr, '\0', ctx->attr_size);
a66391
                     ctx->attr_position = 0;
a66391
                 } else {
a66391
+                    /* we can be adding char by char and overrun allocated size */
a66391
+                    if (ctx->attr_position >= ctx->attr_size) {
a66391
+                        if (ctx->attr_size == ATTRSIZE) {
a66391
+                            char *ctxattr = slapi_ch_calloc(sizeof(char), ctx->attr_size + ATTRSIZE);
a66391
+                            memcpy(ctxattr, ctx->attr, ctx->attr_size);
a66391
+                            ctx->attr = ctxattr;
a66391
+                        } else {
a66391
+                            ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (ctx->attr_size + ATTRSIZE));
a66391
+                        }
a66391
+                        ctx->attr_size = ctx->attr_size + ATTRSIZE;
a66391
+                    }
a66391
                     memcpy(ctx->attr + ctx->attr_position, val, 1);
a66391
                     ctx->attr_position++;
a66391
                 }
b045b9
@@ -377,7 +397,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
a66391
         ctx->next_arg_needs_esc_norm = 0;
a66391
         ctx->attr_found = 0;
a66391
         ctx->attr_position = 0;
a66391
-        memset(ctx->attr, '\0', ATTRSIZE);
a66391
+        memset(ctx->attr, '\0', ctx->attr_size);
a66391
         slapi_ch_free_string(&buf;;
a66391
 
a66391
         return filter_len;
b045b9
@@ -416,12 +436,14 @@ slapi_filter_sprintf(const char *fmt, ...)
a66391
 {
a66391
     struct filter_ctx ctx = {0};
a66391
     va_list args;
a66391
+    char attr_static[ATTRSIZE] = {0};
a66391
     char *buf;
a66391
     int rc;
a66391
 
a66391
     buf = slapi_ch_calloc(sizeof(char), FILTER_BUF + 1);
a66391
     ctx.buf = buf;
b045b9
-    memset(ctx.attr, '\0', ATTRSIZE);
a66391
+    ctx.attr = attr_static;
a66391
+    ctx.attr_size = ATTRSIZE;
b045b9
     ctx.attr_position = 0;
a66391
     ctx.attr_found = 0;
a66391
     ctx.buf_len = FILTER_BUF;
b045b9
@@ -438,6 +460,10 @@ slapi_filter_sprintf(const char *fmt, ...)
a66391
     }
a66391
     va_end(args);
a66391
 
a66391
+    if (ctx.attr_size > ATTRSIZE) {
a66391
+        slapi_ch_free_string(&ctx.attr);
a66391
+    }
a66391
+
a66391
     return ctx.buf;
a66391
 }
a66391
 
a66391
-- 
a66391
2.13.6
a66391