Tarantool development patches archive
 help / color / mirror / Atom feed
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


  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