diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-12-29 11:38:17 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-01-02 08:16:55 +1100 |
commit | 708ad42b0b1029a813141d1b1d14c782f7ce6393 (patch) | |
tree | b5eeb8bc6daae12808dfb8a4adf8d17cfba62e17 /source4 | |
parent | c3061794ef4d03d5b26d4a221a93722b3ed08197 (diff) | |
download | samba-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.c | 46 |
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; } /* |