From: Evgeniy Temirgaleev via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: Sergey Bronnikov <estetus@gmail.com>
Cc: tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH luajit 2/3] sysprof: fix crash on a failed stream flush
Date: Wed, 11 Nov 2026 19:34:02 +0300 [thread overview]
Message-ID: <a22710f2-8844-4594-bb42-ee70aae254d2@tarantool.org> (raw)
In-Reply-To: <ec34b6138bdc9ff271ed2ccf34cc4e1f629e7950.1793624427.git.estetus@gmail.com>
Sergey! At the end of the letter for commit 1/3 I write a note on
lj_wbuf_addn() implementation. Actually, this note and question is
closer to this commit.
Please, see.
On 11/2/26 4:12 PM, Sergey Bronnikov wrote:
> From: Sergey Bronnikov <sergeyb@tarantool.org>
>
> A writer may release the stream buffer and set its pointer to NULL
> on an unrecoverable error, e.g., when the file system with the
> profile is full. The write buffer stops the stream in this case,
> but a caller of `wbuf_reserve()` still writes data using the
> released buffer. This leads to a null pointer dereference inside
> `lj_utils_write_uleb128()` when the flush is triggered while
> streaming a sample.
>
> Now `wbuf_reserve()` reports whether the stream was stopped during
> the flush. All the write functions skip writing in this case,
> including the loop pumping a large payload through the buffer.
>
> Fixes tarantool/tarantool#11620
> ---
> src/lj_wbuf.c | 20 +-
> .../gh-11620-sysprof-enospc-crash.test.c | 180 ++++++++++++++++++
> test/tarantool-c-tests/unit-wbuf.test.c | 102 ++++++++++
> 3 files changed, 298 insertions(+), 4 deletions(-)
> create mode 100644 test/tarantool-c-tests/gh-11620-sysprof-enospc-crash.test.c
>
> diff --git a/src/lj_wbuf.c b/src/lj_wbuf.c
> index 0001a02e..0794b186 100644
> --- a/src/lj_wbuf.c
> +++ b/src/lj_wbuf.c
> @@ -51,11 +51,18 @@ void LJ_FASTCALL lj_wbuf_terminate(struct lj_wbuf *buf)
> lj_wbuf_init(buf, NULL, NULL, NULL, 0);
> }
>
> -static LJ_AINLINE void wbuf_reserve(struct lj_wbuf *buf, size_t n)
> +/*
> +** Reserve n bytes in the buffer. Returns non-zero if the space is reserved
> +** and zero if the stream was stopped during the flush. In the latter case
> +** the writer may release the buffer (buf->buf == NULL), so it must not be
> +** used by the caller.
> +*/
> +static LJ_AINLINE int wbuf_reserve(struct lj_wbuf *buf, size_t n)
> {
> lj_assertX(n <= buf->size, "wbuf overflow");
> if (LJ_UNLIKELY(wbuf_left(buf) < n))
> lj_wbuf_flush(buf);
> + return !lj_wbuf_test_flag(buf, STREAM_STOP);
> }
>
> /* Writes a byte to the output buffer. */
> @@ -63,7 +70,8 @@ void LJ_FASTCALL lj_wbuf_addbyte(struct lj_wbuf *buf, uint8_t b)
> {
> if (LJ_UNLIKELY(lj_wbuf_test_flag(buf, STREAM_STOP)))
> return;
> - wbuf_reserve(buf, sizeof(b));
> + if (LJ_UNLIKELY(!wbuf_reserve(buf, sizeof(b))))
> + return;
> *buf->pos++ = b;
> }
>
> @@ -72,7 +80,8 @@ void LJ_FASTCALL lj_wbuf_addu64(struct lj_wbuf *buf, uint64_t n)
> {
> if (LJ_UNLIKELY(lj_wbuf_test_flag(buf, STREAM_STOP)))
> return;
> - wbuf_reserve(buf, LEB128_U64_MAXSIZE);
> + if (LJ_UNLIKELY(!wbuf_reserve(buf, LEB128_U64_MAXSIZE)))
> + return;
Is it OK, if the writer report an error only, the buffer content will be
discarded (not written), and we will success in 'pushing more data to
the stream buffer after a hole'?
> buf->pos += (ptrdiff_t)lj_utils_write_uleb128(buf->pos, n);
> }
>
> @@ -91,11 +100,14 @@ void lj_wbuf_addn(struct lj_wbuf *buf, const void *src, size_t n)
> memcpy(buf->pos, src, left);
> buf->pos += (ptrdiff_t)left;
> lj_wbuf_flush(buf);
> + if (LJ_UNLIKELY(lj_wbuf_test_flag(buf, STREAM_STOP)))
> + return;
What would happen if writer() reports an error, but doesn't stop a stream?
> src = (uint8_t *)src + (ptrdiff_t)left;
> n -= left;
> }
>
> - wbuf_reserve(buf, n);
> + if (LJ_UNLIKELY(!wbuf_reserve(buf, n)))
> + return;
> memcpy(buf->pos, src, n);
> buf->pos += (ptrdiff_t)n;
> }
> diff --git a/test/tarantool-c-tests/gh-11620-sysprof-enospc-crash.test.c b/test/tarantool-c-tests/gh-11620-sysprof-enospc-crash.test.c
> new file mode 100644
> index 00000000..0f5ffe53
> --- /dev/null
> +++ b/test/tarantool-c-tests/gh-11620-sysprof-enospc-crash.test.c
<snipped>
--
--
Best regards,
Evgeniy Temirgaleev
next prev parent reply other threads:[~2026-11-11 16:34 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 13:11 [Tarantool-patches] [PATCH luajit 0/3] Fix sysprof crash due to insufficient free disk space Sergey Bronnikov via Tarantool-patches
2026-11-02 13:12 ` [Tarantool-patches] [PATCH luajit 1/3] test: add unit tests for the write buffer Sergey Bronnikov via Tarantool-patches
2026-11-05 18:39 ` Sergey Kaplun via Tarantool-patches
2026-11-11 15:24 ` Evgeniy Temirgaleev via Tarantool-patches
2026-11-02 13:12 ` [Tarantool-patches] [PATCH luajit 2/3] sysprof: fix crash on a failed stream flush Sergey Bronnikov via Tarantool-patches
2026-11-06 10:59 ` Sergey Kaplun via Tarantool-patches
2026-11-11 16:34 ` Evgeniy Temirgaleev via Tarantool-patches [this message]
2026-11-02 13:12 ` [Tarantool-patches] [PATCH luajit 3/3] sysprof: release resources on a halted profiler Sergey Bronnikov via Tarantool-patches
2026-11-06 11:06 ` Sergey Kaplun via Tarantool-patches
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=a22710f2-8844-4594-bb42-ee70aae254d2@tarantool.org \
--to=tarantool-patches@dev.tarantool.org \
--cc=e.temirgaleev@tarantool.org \
--cc=estetus@gmail.com \
--subject='Re: [Tarantool-patches] [PATCH luajit 2/3] sysprof: fix crash on a failed stream flush' \
/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