commit e9b75d8e87b364f3ad2843fce353aa314d714359
parent 27a61bc0c9b12e0e71f5756bc5e3d9401aa3a2b2
Author: lash <dev@holbrook.no>
Date: Tue, 14 May 2024 13:07:45 +0100
Correct overflow in buffer in ledger put
Diffstat:
4 files changed, 83 insertions(+), 10 deletions(-)
diff --git a/src/db.c b/src/db.c
@@ -30,6 +30,49 @@ int db_connect(struct db_ctx *ctx, char *conn) {
}
+int db_start(struct db_ctx *ctx) {
+ int r;
+
+ r = mdb_txn_begin(ctx->env, NULL, 0, &ctx->tx);
+ if (r) {
+ return ERR_FAIL;
+ }
+
+ r = mdb_dbi_open(ctx->tx, NULL, MDB_CREATE, &ctx->dbi);
+ if (r) {
+ return ERR_FAIL;
+ }
+ return ERR_OK;
+}
+
+int db_add(struct db_ctx *ctx, char *key, size_t key_len, char *data, size_t data_len) {
+ int r;
+
+ ctx->k.mv_data = key;
+ ctx->k.mv_size = key_len;
+ ctx->v.mv_data = data;
+ ctx->v.mv_size = data_len;
+
+ r = mdb_put(ctx->tx, ctx->dbi, &ctx->k, &ctx->v, MDB_NODUPDATA | MDB_NOOVERWRITE);
+ if (r) {
+ return ERR_FAIL;
+ }
+
+ return ERR_OK;
+}
+
+int db_finish(struct db_ctx *ctx) {
+ int r;
+
+ r = mdb_txn_commit(ctx->tx);
+ if (r) {
+ return ERR_FAIL;
+ }
+ ctx->tx = NULL;
+
+ return ERR_OK;
+}
+
/// \todo atomic tx put
int db_put(struct db_ctx *ctx, char *key, size_t key_len, char *data, size_t data_len) {
int r;
@@ -205,6 +248,10 @@ int db_next(struct db_ctx *ctx, enum DbKey pfx, char **key, size_t *key_len, cha
/// \todo find better name
void db_rewind(struct db_ctx *ctx) {
+ if (ctx->tx != NULL) {
+ mdb_txn_abort(ctx->tx);
+ }
+ ctx->tx = NULL;
ctx->browsing = 0;
}
diff --git a/src/db.h b/src/db.h
@@ -49,6 +49,10 @@ struct db_ctx {
MDB_cursor *crsr;
MDB_val k;
MDB_val v;
+ MDB_val *add_k;
+ MDB_val *add_v;
+ size_t add_cap;
+ size_t add_count;
enum DbKey current_key;
int started;
int browsing;
@@ -60,5 +64,8 @@ int db_put(struct db_ctx *ctx, char *key, size_t key_len, char *data, size_t dat
int db_next(struct db_ctx *ctx, enum DbKey pfx, char **key, size_t *key_len, char **value, size_t *value_len);
void db_rewind(struct db_ctx *ctx);
void db_reset(struct db_ctx *ctx);
+int db_start(struct db_ctx *ctx);
+int db_add(struct db_ctx *ctx, char *key, size_t key_len, char *data, size_t data_len);
+int db_finish(struct db_ctx *ctx);
#endif // _DB_H
diff --git a/src/ledger.c b/src/ledger.c
@@ -974,12 +974,12 @@ int kee_ledger_put(struct kee_ledger_t *ledger, struct db_ctx *db) {
int r;
size_t c;
size_t l;
- char mem[1024];
+ char mem[2048];
char *k;
char *v;
k = (char*)mem;
- v = ((char*)mem)+96;
+ v = ((char*)mem)+1024;
k[0] = DbKeyReverse;
memcpy(((char*)k)+1, ledger->digest, DIGEST_LENGTH);
@@ -998,6 +998,8 @@ int kee_ledger_put(struct kee_ledger_t *ledger, struct db_ctx *db) {
}
}
+ db_rewind(db);
+
l = db_key(DbKeyLedgerHead, NULL, k, 0);
if (l == 0) {
return ERR_FAIL;
@@ -1009,7 +1011,13 @@ int kee_ledger_put(struct kee_ledger_t *ledger, struct db_ctx *db) {
return ERR_DB_FAIL;
}
- r = db_put(db, k, l, v, c);
+ r = db_start(db);
+ if (r) {
+ return ERR_DB_FAIL;
+ }
+
+ //r = db_put(db, k, l, v, c);
+ r = db_add(db, k, l, v, c);
if (r) {
return ERR_DB_FAIL;
}
@@ -1019,7 +1027,13 @@ int kee_ledger_put(struct kee_ledger_t *ledger, struct db_ctx *db) {
l = DIGEST_LENGTH + 1;
*k = DbKeyReverse;
memcpy(k+1, ledger->digest, DIGEST_LENGTH);
- r = db_put(db, k, l, v, c);
+ //r = db_put(db, k, l, v+1, c-1);
+ r = db_add(db, k, l, v+1, c-1);
+ if (r) {
+ return ERR_DB_FAIL;
+ }
+
+ r = db_finish(db);
if (r) {
return ERR_DB_FAIL;
}
diff --git a/testdata_asn1.py b/testdata_asn1.py
@@ -393,8 +393,11 @@ class LedgerHead(Ledger):
def to_key(b):
r = b''
r += PFX_LEDGER_HEAD
- v = time.time_ns()
- b = v.to_bytes(8, byteorder='big')
+ t = time.time_ns()
+ v = int(t / 1000000000)
+ b = v.to_bytes(4, byteorder='big')
+ v = t - (v * 1000000000)
+ b += v.to_bytes(4, byteorder='big')
r += b
return r
@@ -643,7 +646,6 @@ if __name__ == '__main__':
r = generate_ledger(dbi, data_dir, signer, bob_name, ledger_item_count=1, alice=alice, bob=bob)
d = os.path.dirname(__file__)
- importer = LedgerBundle(data_dir, ledger_object)
import_dir = os.path.join(d, 'testdata', 'import')
try:
shutil.rmtree(import_dir)
@@ -651,20 +653,23 @@ if __name__ == '__main__':
pass
os.makedirs(import_dir)
+ ledger_object = r[0][2]
+ ledger_item_object = r[1][2]
+ importer = LedgerBundle(data_dir, ledger_object)
w = io.BytesIO()
fp = os.path.join(import_dir, 'request')
f = open(fp, 'wb')
- importer.encode(v[2], LedgerMode.REQUEST, w=f)
+ importer.encode(ledger_item_object, LedgerMode.REQUEST, w=f)
f.close()
w = io.BytesIO()
fp = os.path.join(import_dir, 'response')
f = open(fp, 'wb')
- importer.encode(v[2], LedgerMode.RESPONSE, w=f)
+ importer.encode(ledger_item_object, LedgerMode.RESPONSE, w=f)
f.close()
w = io.BytesIO()
fp = os.path.join(import_dir, 'final')
f = open(fp, 'wb')
- importer.encode(v[2], LedgerMode.FINAL, w=f)
+ importer.encode(ledger_item_object, LedgerMode.FINAL, w=f)
f.close()