kee

Offline IOU signer with QR as transport
git clone https://holbrook.no/src/kee
Info | Log | Files | Refs | README | LICENSE

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:
Msrc/db.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Msrc/db.h | 7+++++++
Msrc/ledger.c | 22++++++++++++++++++----
Mtestdata_asn1.py | 17+++++++++++------
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()