From cbe2ff451c5c637ec8bd39d30f65ae5f47888b32 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov@tarantool.org> Date: Mon, 27 Feb 2023 14:42:32 +0300 Subject: [PATCH] vinyl: fix use after free on key alloc error in iterator constructor Error labes got mixed up. Fix the order and add a test. Fixes commit 3f0263395bee ("vinyl: implement iterator pagination"). Closes #8372 NO_DOC=bug fix NO_CHANGELOG=fix for unreleased feature (cherry picked from commit 074e4eb8531ff48b0fa040f1f9a1cfffa3e0a869) --- src/box/vinyl.c | 4 +- ...8372_key_alloc_error_in_iter_ctor_test.lua | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 test/vinyl-luatest/gh_8372_key_alloc_error_in_iter_ctor_test.lua diff --git a/src/box/vinyl.c b/src/box/vinyl.c index fa8e0cd110..62d8992568 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -3832,10 +3832,10 @@ vinyl_index_create_iterator(struct index *base, enum iterator_type type, &it->iterator, lsm, tx, type, it->key, last, (const struct vy_read_view **)&tx->read_view); return (struct iterator *)it; -err_key: - mempool_free(&env->iterator_pool, it); err_pos: tuple_unref(it->key.stmt); +err_key: + mempool_free(&env->iterator_pool, it); return NULL; } diff --git a/test/vinyl-luatest/gh_8372_key_alloc_error_in_iter_ctor_test.lua b/test/vinyl-luatest/gh_8372_key_alloc_error_in_iter_ctor_test.lua new file mode 100644 index 0000000000..6942cfcc1d --- /dev/null +++ b/test/vinyl-luatest/gh_8372_key_alloc_error_in_iter_ctor_test.lua @@ -0,0 +1,38 @@ +local server = require('luatest.server') +local t = require('luatest') + +local g = t.group() + +g.before_all(function(cg) + cg.server = server:new({alias = 'master'}) + cg.server:start() + cg.server:exec(function() + box.schema.create_space('test', {engine = 'vinyl'}) + box.space.test:create_index('primary', {parts = {1, 'string'}}) + end) +end) + +g.after_all(function(cg) + cg.server:drop() +end) + +g.test_key_alloc_error = function(cg) + cg.server:exec(function() + box.cfg({vinyl_max_tuple_size = 1}) + t.assert_error_msg_matches( + "Failed to allocate [%d]+ bytes for tuple: tuple is too large. " .. + "Check 'vinyl_max_tuple_size' configuration option.", + box.space.test.select, box.space.test, {'foo'}) + end) +end + +g.test_pos_alloc_error = function(cg) + cg.server:exec(function() + box.cfg({vinyl_max_tuple_size = 100}) + t.assert_error_msg_matches( + "Failed to allocate [%d]+ bytes for tuple: tuple is too large. " .. + "Check 'vinyl_max_tuple_size' configuration option.", + box.space.test.select, box.space.test, {}, + {after = {string.rep('x', 101)}}) + end) +end -- GitLab