Skip to content

Commit 49b8153

Browse files
committed
Fixed invalid memory read/segfault
This patch fixes segfaults caused by invalid memory read during leafref links removal process. It is tight hash_table implementation, as hash_table removal of record can invalidate all other record pointers due to memory reallocation process
1 parent 2141fe0 commit 49b8153

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

src/context.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ ly_ctx_ht_err_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod), void *UN
272272
static ly_bool
273273
ly_ctx_ht_leafref_links_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod), void *UNUSED(cb_data))
274274
{
275-
struct lyd_leafref_links_rec *rec1 = val1_p, *rec2 = val2_p;
275+
struct lyd_leafref_links_rec **rec1 = val1_p, **rec2 = val2_p;
276276

277-
return rec1->node == rec2->node;
277+
return (*rec1)->node == (*rec2)->node;
278278
}
279279

280280
/**
@@ -285,9 +285,10 @@ ly_ctx_ht_leafref_links_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod)
285285
static void
286286
ly_ctx_ht_leafref_links_rec_free(void *val_p)
287287
{
288-
struct lyd_leafref_links_rec *rec = val_p;
288+
struct lyd_leafref_links_rec **rec = val_p;
289289

290-
lyd_free_leafref_links_rec(rec);
290+
lyd_free_leafref_links_rec(*rec);
291+
free(*rec);
291292
}
292293

293294
LIBYANG_API_DEF LY_ERR
@@ -316,7 +317,7 @@ ly_ctx_new(const char *search_dir, uint16_t options, struct ly_ctx **new_ctx)
316317
LY_CHECK_ERR_GOTO(lyplg_init(builtin_plugins_only), LOGINT(NULL); rc = LY_EINT, cleanup);
317318

318319
if (options & LY_CTX_LEAFREF_LINKING) {
319-
ctx->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
320+
ctx->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec *), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
320321
LY_CHECK_ERR_GOTO(!ctx->leafref_links_ht, rc = LY_EMEM, cleanup);
321322
}
322323

@@ -654,7 +655,7 @@ ly_ctx_set_options(struct ly_ctx *ctx, uint16_t option)
654655
}
655656

656657
if (!(ctx->flags & LY_CTX_LEAFREF_LINKING) && (option & LY_CTX_LEAFREF_LINKING)) {
657-
ctx->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
658+
ctx->leafref_links_ht = lyht_new(1, sizeof(struct lyd_leafref_links_rec *), ly_ctx_ht_leafref_links_equal_cb, NULL, 1);
658659
LY_CHECK_ERR_RET(!ctx->leafref_links_ht, LOGARG(ctx, option), LY_EMEM);
659660
}
660661

src/tree_data.c

+14-3
Original file line numberDiff line numberDiff line change
@@ -3610,8 +3610,11 @@ LY_ERR
36103610
lyd_get_or_create_leafref_links_record(const struct lyd_node_term *node, struct lyd_leafref_links_rec **record, ly_bool create)
36113611
{
36123612
struct ly_ht *ht;
3613+
LY_ERR ret = LY_SUCCESS;
36133614
uint32_t hash;
36143615
struct lyd_leafref_links_rec rec = {0};
3616+
struct lyd_leafref_links_rec *rec_p = &rec;
3617+
struct lyd_leafref_links_rec **rec_p2;
36153618

36163619
assert(node);
36173620
assert(record);
@@ -3626,15 +3629,23 @@ lyd_get_or_create_leafref_links_record(const struct lyd_node_term *node, struct
36263629
ht = LYD_CTX(node)->leafref_links_ht;
36273630
hash = lyht_hash((const char *)&node, sizeof node);
36283631

3629-
if (lyht_find(ht, &rec, hash, (void **)record) == LY_ENOTFOUND) {
3632+
if (lyht_find(ht, &rec_p, hash, (void **)&rec_p2) == LY_ENOTFOUND) {
36303633
if (create) {
3631-
LY_CHECK_RET(lyht_insert_no_check(ht, &rec, hash, (void **)record));
3634+
rec_p = calloc(1, sizeof rec);
3635+
rec_p->node = node;
3636+
LY_CHECK_ERR_RET(!rec_p, LOGMEM(LYD_CTX(node)), LY_EMEM);
3637+
ret = lyht_insert_no_check(ht, &rec_p, hash, (void **)&rec_p2);
3638+
LY_CHECK_ERR_GOTO(ret, free(rec_p), cleanup);
36323639
} else {
36333640
return LY_ENOTFOUND;
36343641
}
36353642
}
36363643

3637-
return LY_SUCCESS;
3644+
cleanup:
3645+
if (!ret) {
3646+
*record = *rec_p2;
3647+
}
3648+
return ret;
36383649
}
36393650

36403651
LIBYANG_API_DEF LY_ERR

src/tree_data_free.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ lyd_free_leafref_nodes(const struct lyd_node_term *node)
191191
/* free entry itself from hash table */
192192
ht = LYD_CTX(node)->leafref_links_ht;
193193
hash = lyht_hash((const char *)&node, sizeof node);
194-
lyht_remove(ht, rec, hash);
194+
lyht_remove(ht, &rec, hash);
195+
free(rec);
195196
}
196197

197198
/**

0 commit comments

Comments
 (0)