summaryrefslogtreecommitdiff
path: root/lib/dbwrap/dbwrap_rbt.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2015-07-18 21:50:55 +0200
committerRalph Böhme <slow@samba.org>2015-07-20 23:18:23 +0200
commit64a88f74ca5309dce1d3ec0755ceba4af5144dbd (patch)
tree13297452ff8f6745fa53779a2c4fd16e3ccb4d92 /lib/dbwrap/dbwrap_rbt.c
parentd87877251a553ac60f314ebe435ec33f46fb6b98 (diff)
downloadsamba-64a88f74ca5309dce1d3ec0755ceba4af5144dbd.tar.gz
dbwrap_rbt: Make "key" and "value" aligned to 16 byte
Reported by Uri Simchoni <urisimchoni@gmail.com>. Thanks! Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org> Autobuild-User(master): Ralph Böhme <slow@samba.org> Autobuild-Date(master): Mon Jul 20 23:18:23 CEST 2015 on sn-devel-104
Diffstat (limited to 'lib/dbwrap/dbwrap_rbt.c')
-rw-r--r--lib/dbwrap/dbwrap_rbt.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/lib/dbwrap/dbwrap_rbt.c b/lib/dbwrap/dbwrap_rbt.c
index 3f970865982..03f2f576256 100644
--- a/lib/dbwrap/dbwrap_rbt.c
+++ b/lib/dbwrap/dbwrap_rbt.c
@@ -38,13 +38,6 @@ struct db_rbt_rec {
struct db_rbt_node {
struct rb_node rb_node;
size_t keysize, valuesize;
-
- /*
- * key and value are appended implicitly, "data" is only here as a
- * target for offsetof()
- */
-
- char data[1];
};
/*
@@ -83,12 +76,43 @@ static int db_rbt_compare(TDB_DATA a, TDB_DATA b)
static void db_rbt_parse_node(struct db_rbt_node *node,
TDB_DATA *key, TDB_DATA *value)
{
- key->dptr = ((uint8_t *)node) + offsetof(struct db_rbt_node, data);
+ size_t key_offset, value_offset;
+
+ key_offset = DBWRAP_RBT_ALIGN(sizeof(struct db_rbt_node));
+ key->dptr = ((uint8_t *)node) + key_offset;
key->dsize = node->keysize;
- value->dptr = key->dptr + node->keysize;
+
+ value_offset = DBWRAP_RBT_ALIGN(node->keysize);
+ value->dptr = key->dptr + value_offset;
value->dsize = node->valuesize;
}
+static ssize_t db_rbt_reclen(size_t keylen, size_t valuelen)
+{
+ size_t len, tmp;
+
+ len = DBWRAP_RBT_ALIGN(sizeof(struct db_rbt_node));
+
+ tmp = DBWRAP_RBT_ALIGN(keylen);
+ if (tmp < keylen) {
+ goto overflow;
+ }
+
+ len += tmp;
+ if (len < tmp) {
+ goto overflow;
+ }
+
+ len += valuelen;
+ if (len < valuelen) {
+ goto overflow;
+ }
+
+ return len;
+overflow:
+ return -1;
+}
+
static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
{
struct db_rbt_ctx *db_ctx = talloc_get_type_abort(
@@ -99,6 +123,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
struct rb_node ** p;
struct rb_node * parent;
+ ssize_t reclen;
TDB_DATA this_key, this_val;
if (rec_priv->node != NULL) {
@@ -123,10 +148,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag)
}
}
- node = (struct db_rbt_node *)talloc_size(db_ctx,
- offsetof(struct db_rbt_node, data) + rec->key.dsize
- + data.dsize);
+ reclen = db_rbt_reclen(rec->key.dsize, data.dsize);
+ if (reclen == -1) {
+ return NT_STATUS_INSUFFICIENT_RESOURCES;
+ }
+ node = talloc_size(db_ctx, reclen);
if (node == NULL) {
return NT_STATUS_NO_MEMORY;
}