mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
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
This commit is contained in:
parent
c3061794ef
commit
708ad42b0b
@ -678,20 +678,43 @@ static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx,
|
|||||||
v1, v2);
|
v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
*v = (int32_t) strtoll(buf, &end, 0);
|
||||||
|
if (*end != 0) {
|
||||||
|
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
|
||||||
|
}
|
||||||
|
return LDB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Canonicalisation of two 32-bit integers */
|
/* Canonicalisation of two 32-bit integers */
|
||||||
static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
|
static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
|
||||||
const struct ldb_val *in, struct ldb_val *out)
|
const struct ldb_val *in, struct ldb_val *out)
|
||||||
{
|
{
|
||||||
char *end;
|
int32_t i;
|
||||||
/* We've to use "strtoll" here to have the intended overflows.
|
int ret;
|
||||||
* Otherwise we may get "LONG_MAX" and the conversion is wrong. */
|
|
||||||
int32_t i = (int32_t) strtoll((char *)in->data, &end, 0);
|
ret = val_to_int32(in, &i);
|
||||||
if (*end != 0) {
|
if (ret != LDB_SUCCESS) {
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i);
|
out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i);
|
||||||
if (out->data == NULL) {
|
if (out->data == NULL) {
|
||||||
return -1;
|
ldb_oom(ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
out->length = strlen((char *)out->data);
|
out->length = strlen((char *)out->data);
|
||||||
return 0;
|
return 0;
|
||||||
@ -699,12 +722,13 @@ static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
|
|||||||
|
|
||||||
/* Comparison of two 32-bit integers */
|
/* Comparison of two 32-bit integers */
|
||||||
static int ldif_comparison_int32(struct ldb_context *ldb, void *mem_ctx,
|
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.
|
int32_t i1=0, i2=0;
|
||||||
* Otherwise we may get "LONG_MAX" and the conversion is wrong. */
|
val_to_int32(v1, &i1);
|
||||||
return (int32_t) strtoll((char *)v1->data, NULL, 0)
|
val_to_int32(v2, &i2);
|
||||||
- (int32_t) strtoll((char *)v2->data, NULL, 0);
|
if (i1 == i2) return 0;
|
||||||
|
return i1 > i2? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user