All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jianlin Shi" <shijianlin11@foxmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf] bpf: roll back stream capacity when allocation fails
Date: Mon, 20 Jul 2026 01:35:18 +0000	[thread overview]
Message-ID: <20260720013519.3BE771F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <tencent_E69EAE29327E25B3548A9AF3F4FA289A6806@qq.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] The patch addresses a capacity leak in `bpf_stream_push_str()` when stream element allocation fails, but entirely misses the identical capacity leak in the staging logic (`bpf_stream_stage_printk()` and `bpf_stream_stage_commit()`).
- [High] If copy_to_user() fails during bpf_stream_read() after some elements have already been consumed, the function returns -EFAULT instead of the number of bytes successfully read, resulting in silent data loss.
--

--- Patch [1]: [PATCH bpf] bpf: roll back stream capacity when allocation fails ---
commit 06c82cbb65aa09c192205a6718b0fa398300f1ac
Author: Jianlin Shi <shijianlin11@foxmail.com>

bpf: roll back stream capacity when allocation fails

The patch fixes a stream capacity leak in bpf_stream_push_str().
If allocating a stream element fails, the previously charged capacity
is now rolled back to avoid permanent exhaustion.

> diff --git a/kernel/bpf/stream.c b/kernel/bpf/stream.c
> index be9ce98e94692..4b8a74b9162e1 100644
> --- a/kernel/bpf/stream.c
> +++ b/kernel/bpf/stream.c
> @@ -79,7 +79,14 @@ static int bpf_stream_push_str(struct bpf_stream *stream, const char *str, int l
>  {
>  	int ret = bpf_stream_consume_capacity(stream, len);
>  
> -	return ret ?: __bpf_stream_push_str(&stream->log, str, len);
> +	if (ret)
> +		return ret;
> +
> +	ret = __bpf_stream_push_str(&stream->log, str, len);
> +	if (ret)
> +		atomic_sub(len, &stream->capacity);
> +
> +	return ret;
>  }

[Severity: High]
This isn't a bug introduced by this patch, but it seems there's an identical
capacity leak in the staging logic that this patch doesn't address.

In bpf_stream_stage_printk(), ss->len is unconditionally incremented even if
allocation fails:

kernel/bpf/stream.c:bpf_stream_stage_printk() {
    ...
    ss->len += ret;
    /* Exclude NULL byte during push. */
    ret = __bpf_stream_push_str(&ss->log, buf->buf, ret);
    ...
}

Then in include/linux/bpf.h, the bpf_stream_stage() macro unconditionally
calls bpf_stream_stage_commit():

#define bpf_stream_stage(ss, prog, stream_id, expr)            \
    ({                                                     \
        bpf_stream_stage_init(&ss);                    \
        (expr);                                        \
        bpf_stream_stage_commit(&ss, prog, stream_id); \
        bpf_stream_stage_free(&ss);                    \
    })

Which then permanently charges the falsely inflated length against the capacity:

kernel/bpf/stream.c:bpf_stream_stage_commit() {
    ...
    ret = bpf_stream_consume_capacity(stream, ss->len);
    ...
}

Should the staging logic also be updated to prevent permanently leaking
stream capacity when memory allocation fails?

[Severity: High]
This is a pre-existing issue, but I noticed another problem related to how
stream errors are handled in bpf_stream_read() when copy_to_user() fails.

If some elements are successfully consumed and freed:

kernel/bpf/stream.c:bpf_stream_read() {
    ...
    bpf_stream_backlog_pop(stream);
    bpf_stream_release_capacity(stream, elem);
    bpf_stream_free_elem(elem);
    ...
}

But a subsequent copy_to_user() fails on an unmapped page, the function returns
-EFAULT unconditionally:

    ...
    mutex_unlock(&stream->lock);
    return ret ? ret : len - rem_len;
}

Does this mean the successfully copied elements from earlier loop iterations
are permanently lost without the reader knowing how many bytes were read?
Should it return the bytes successfully read (len - rem_len) when some
elements were already consumed?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/tencent_E69EAE29327E25B3548A9AF3F4FA289A6806@qq.com?part=1

  reply	other threads:[~2026-07-20  1:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20  1:23 [PATCH bpf] bpf: roll back stream capacity when allocation fails Jianlin Shi
2026-07-20  1:35 ` sashiko-bot [this message]
2026-07-20  3:40 ` Pu Lehui
2026-07-20  5:13   ` Jianlin Shi
2026-07-20  5:13 ` [PATCH bpf-next v2] " Jianlin Shi
2026-07-20  5:26   ` sashiko-bot

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=20260720013519.3BE771F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=shijianlin11@foxmail.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.