summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-12-29 11:38:17 +1100
committerAndrew Tridgell <tridge@samba.org>2010-01-02 08:16:55 +1100
commit708ad42b0b1029a813141d1b1d14c782f7ce6393 (patch)
treeb5eeb8bc6daae12808dfb8a4adf8d17cfba62e17 /source4
parentc3061794ef4d03d5b26d4a221a93722b3ed08197 (diff)
downloadsamba-708ad42b0b1029a813141d1b1d14c782f7ce6393.tar.gz
samba-708ad42b0b1029a813141d1b1d14c782f7ce6393.tar.bz2
samba-708ad42b0b1029a813141d1b1d14c782f7ce6393.zip
s4-dsdb: use safe length limiting in string->integer conversion
The ldap.py test suite could trigger a read past the end of the struct ldb_val buffer
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/ldb-samba/ldif_handlers.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c
index 39fc93af95..7ddc8e57a7 100644
--- a/source4/lib/ldb-samba/ldif_handlers.c
+++ b/source4/lib/ldb-samba/ldif_handlers.c
@@ -678,20 +678,43 @@ static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx,
v1, v2);
}
-/* Canonicalisation of two 32-bit integers */
-static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
- const struct ldb_val *in, struct ldb_val *out)
+/* length limited conversion of a ldb_val to a int32_t */
+static int val_to_int32(const struct ldb_val *in, int32_t *v)
{
char *end;
+ char buf[64];
+
+ /* make sure we don't read past the end of the data */
+ if (in->length > sizeof(buf)-1) {
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ }
+ strncpy(buf, (char *)in->data, in->length);
+ buf[in->length] = 0;
+
/* We've to use "strtoll" here to have the intended overflows.
* Otherwise we may get "LONG_MAX" and the conversion is wrong. */
- int32_t i = (int32_t) strtoll((char *)in->data, &end, 0);
+ *v = (int32_t) strtoll(buf, &end, 0);
if (*end != 0) {
- return -1;
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ }
+ return LDB_SUCCESS;
+}
+
+/* Canonicalisation of two 32-bit integers */
+static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *in, struct ldb_val *out)
+{
+ int32_t i;
+ int ret;
+
+ ret = val_to_int32(in, &i);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i);
if (out->data == NULL) {
- return -1;
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
}
out->length = strlen((char *)out->data);
return 0;
@@ -699,12 +722,13 @@ static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
/* Comparison of two 32-bit integers */
static int ldif_comparison_int32(struct ldb_context *ldb, void *mem_ctx,
- const struct ldb_val *v1, const struct ldb_val *v2)
+ const struct ldb_val *v1, const struct ldb_val *v2)
{
- /* We've to use "strtoll" here to have the intended overflows.
- * Otherwise we may get "LONG_MAX" and the conversion is wrong. */
- return (int32_t) strtoll((char *)v1->data, NULL, 0)
- - (int32_t) strtoll((char *)v2->data, NULL, 0);
+ int32_t i1=0, i2=0;
+ val_to_int32(v1, &i1);
+ val_to_int32(v2, &i2);
+ if (i1 == i2) return 0;
+ return i1 > i2? 1 : -1;
}
/*