* [PATCH] xrow: fix request_str crash on long requests
@ 2019-03-18 16:45 Vladimir Davydov
2019-03-18 17:01 ` Vladimir Davydov
0 siblings, 1 reply; 3+ messages in thread
From: Vladimir Davydov @ 2019-03-18 16:45 UTC (permalink / raw)
To: tarantool-patches
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] xrow: fix request_str crash on long requests
2019-03-18 16:45 [PATCH] xrow: fix request_str crash on long requests Vladimir Davydov
@ 2019-03-18 17:01 ` Vladimir Davydov
2019-03-18 17:53 ` Vladimir Davydov
0 siblings, 1 reply; 3+ messages in thread
From: Vladimir Davydov @ 2019-03-18 17:01 UTC (permalink / raw)
To: tarantool-patches
On Mon, Mar 18, 2019 at 07:45:29PM +0300, Vladimir Davydov wrote:
> 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:");
Oops, skipped ' '.
> + 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");
Lost the colon (:), sorry.
Amended on the branch.
> + 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;
> }
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-03-18 17:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-18 16:45 [PATCH] xrow: fix request_str crash on long requests Vladimir Davydov
2019-03-18 17:01 ` Vladimir Davydov
2019-03-18 17:53 ` Vladimir Davydov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox