ldb client controls: avoid talloc_memdup(x, y, (size_t)-1);
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Tue, 15 Mar 2016 23:46:12 +0000 (12:46 +1300)
committerJeremy Allison <jra@samba.org>
Fri, 18 Mar 2016 23:56:42 +0000 (00:56 +0100)
ldb_base64_decode() returns -1 if a string can't be parsed as base64,
and this is not the kind of value you want to use in talloc_memdup().

In these cases it can happen innocently if the strings are truncated
to fit in their buffers.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Mar 19 00:56:42 CET 2016 on sn-devel-144

lib/ldb/common/ldb_controls.c

index 7da0cf04e0d7659c3c8dbed59ebaeb89df346658..0fdd13abc655e089188e094f4d181c271d843932 100644 (file)
@@ -507,8 +507,16 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
                        control->match.byOffset.contentCount = cc;
                }
                if (ctxid[0]) {
-                       control->ctxid_len = ldb_base64_decode(ctxid);
-                       control->contextId = talloc_memdup(control, ctxid, control->ctxid_len);
+                       int len = ldb_base64_decode(ctxid);
+                       if (len < 0) {
+                               ldb_set_errstring(ldb,
+                                                 "invalid VLV context_id\n");
+                               talloc_free(ctrl);
+                               return NULL;
+                       }
+                       control->ctxid_len = len;
+                       control->contextId = talloc_memdup(control, ctxid,
+                                                          control->ctxid_len);
                } else {
                        control->ctxid_len = 0;
                        control->contextId = NULL;
@@ -552,7 +560,14 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
                control->flags = flags;
                control->max_attributes = max_attrs;
                if (*cookie) {
-                       control->cookie_len = ldb_base64_decode(cookie);
+                       int len = ldb_base64_decode(cookie);
+                       if (len < 0) {
+                               ldb_set_errstring(ldb,
+                                                 "invalid dirsync cookie\n");
+                               talloc_free(ctrl);
+                               return NULL;
+                       }
+                       control->cookie_len = len;
                        control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
                } else {
                        control->cookie = NULL;
@@ -597,7 +612,15 @@ struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLO
                control->flags = flags;
                control->max_attributes = max_attrs;
                if (*cookie) {
-                       control->cookie_len = ldb_base64_decode(cookie);
+                       int len = ldb_base64_decode(cookie);
+                       if (len < 0) {
+                               ldb_set_errstring(ldb,
+                                                 "invalid dirsync_ex cookie"
+                                                 " (probably too long)\n");
+                               talloc_free(ctrl);
+                               return NULL;
+                       }
+                       control->cookie_len = len;
                        control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
                } else {
                        control->cookie = NULL;