From: Vladimir Davydov <vdavydov.dev@gmail.com> To: tarantool-patches@freelists.org Subject: [PATCH] xrow: fix request_str crash on long requests Date: Mon, 18 Mar 2019 19:45:29 +0300 [thread overview] Message-ID: <234177c19ce6bdc86ba64555f02f8fb76e3768a0.1552927469.git.vdavydov.dev@gmail.com> (raw) If tt_static_buf is too small to store the request string, 'pos' will become greater than 'end', leading to snprintf(pos, end - pos) crash, as it doesn't allow the buffer size to be negative. Use SNPRINT instead. --- https://github.com/tarantool/tarantool/tree/dv/fix-request-str-crash-on-long-requests src/box/xrow.c | 33 ++++++++++++++++++++------------- test/box-tap/cfg.test.lua | 21 ++++++++++++++++++++- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/box/xrow.c b/src/box/xrow.c index bddae1d5..4a0632fe 100644 --- a/src/box/xrow.c +++ b/src/box/xrow.c @@ -675,13 +675,11 @@ done: return 0; } -const char * -request_str(const struct request *request) +static int +request_snprint(char *buf, int size, const struct request *request) { - char *buf = tt_static_buf(); - char *end = buf + TT_STATIC_BUF_LEN; - char *pos = buf; - pos += snprintf(pos, end - pos, "{type: '%s', " + int total = 0; + SNPRINT(total, snprintf, buf, size, "{type: '%s', " "replica_id: %u, lsn: %lld, " "space_id: %u, index_id: %u", iproto_type_name(request->type), @@ -690,18 +688,27 @@ request_str(const struct request *request) (unsigned) request->space_id, (unsigned) request->index_id); if (request->key != NULL) { - pos += snprintf(pos, end - pos, ", key: "); - pos += mp_snprint(pos, end - pos, request->key); + SNPRINT(total, snprintf, buf, size, ", key:"); + SNPRINT(total, mp_snprint, buf, size, request->key); } if (request->tuple != NULL) { - pos += snprintf(pos, end - pos, ", tuple: "); - pos += mp_snprint(pos, end - pos, request->tuple); + SNPRINT(total, snprintf, buf, size, ", tuple"); + SNPRINT(total, mp_snprint, buf, size, request->tuple); } if (request->ops != NULL) { - pos += snprintf(pos, end - pos, ", ops: "); - pos += mp_snprint(pos, end - pos, request->ops); + SNPRINT(total, snprintf, buf, size, ", ops: "); + SNPRINT(total, mp_snprint, buf, size, request->ops); } - pos += snprintf(pos, end - pos, "}"); + SNPRINT(total, snprintf, buf, size, "}"); + return total; +} + +const char * +request_str(const struct request *request) +{ + char *buf = tt_static_buf(); + if (request_snprint(buf, TT_STATIC_BUF_LEN, request) < 0) + return "<failed to format request>"; return buf; } diff --git a/test/box-tap/cfg.test.lua b/test/box-tap/cfg.test.lua index f791cc3f..55de5e41 100755 --- a/test/box-tap/cfg.test.lua +++ b/test/box-tap/cfg.test.lua @@ -6,7 +6,7 @@ local socket = require('socket') local fio = require('fio') local uuid = require('uuid') local msgpack = require('msgpack') -test:plan(102) +test:plan(104) -------------------------------------------------------------------------------- -- Invalid values @@ -566,5 +566,24 @@ os.exit(0) ]] test:is(run_script(code), 0, "log_nonblock") +-- +-- Crash (instead of panic) when trying to recover a huge tuple. +-- +dir = fio.tempdir() +code1 = string.format([[ +box.cfg{wal_dir = '%s', memtx_dir = '%s', memtx_max_tuple_size = 10 * 1024 * 1024} +box.schema.space.create('test') +box.space.test:create_index('primary') +box.space.test:insert{1, string.rep('x', 1024 * 1024)} +os.exit(0) +]], dir, dir) +code2 = string.format([[ +box.cfg{wal_dir = '%s', memtx_dir = '%s', memtx_max_tuple_size = 10 * 1024} +os.exit(0) +]], dir, dir) +test:is(run_script(code1), 0, "create huge tuple") +test:is(run_script(code2), PANIC, "panic on huge tuple recovery") +fio.rmtree(dir) + test:check() os.exit(0) -- 2.11.0
next reply other threads:[~2019-03-18 16:45 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-18 16:45 Vladimir Davydov [this message] 2019-03-18 17:01 ` Vladimir Davydov 2019-03-18 17:53 ` Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=234177c19ce6bdc86ba64555f02f8fb76e3768a0.1552927469.git.vdavydov.dev@gmail.com \ --to=vdavydov.dev@gmail.com \ --cc=tarantool-patches@freelists.org \ --subject='Re: [PATCH] xrow: fix request_str crash on long requests' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox