A stream write whose formatted output is empty still allocates a stream element and links it into the stream log. Capacity accounting only counts payload bytes, so such elements never count against the stream limit, and a program that keeps producing empty output allocates elements without bound until a reader drains them. Return success without allocating anything when there is nothing to write, for both bpf_stream_vprintk() and staged writes. Every element in a stream log then carries at least one byte, which later changes rely on when they derive read readiness from published byte counts. Fixes: 5ab154f1463a ("bpf: Introduce BPF standard streams") Suggested-by: Emil Tsalapatis Signed-off-by: Kumar Kartikeya Dwivedi --- kernel/bpf/stream.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/stream.c b/kernel/bpf/stream.c index 2b80a0599865..9829d1ebce70 100644 --- a/kernel/bpf/stream.c +++ b/kernel/bpf/stream.c @@ -75,8 +75,13 @@ static void bpf_stream_release_capacity(struct bpf_stream *stream, int len) static int bpf_stream_push_str(struct bpf_stream *stream, const char *str, int len) { - int ret = bpf_stream_consume_capacity(stream, len); + int ret; + + /* Nothing to publish; do not allocate an element for it. */ + if (!len) + return 0; + ret = bpf_stream_consume_capacity(stream, len); if (ret) return ret; @@ -333,8 +338,8 @@ int bpf_stream_stage_printk(struct bpf_stream_stage *ss, const char *fmt, ...) va_start(args, fmt); len = vscnprintf(buf->buf, ARRAY_SIZE(buf->buf), fmt, args); va_end(args); - /* Exclude NULL byte during push. */ - ret = __bpf_stream_push_str(&ss->log, buf->buf, len); + /* Exclude NULL byte during push; skip empty output entirely. */ + ret = len ? __bpf_stream_push_str(&ss->log, buf->buf, len) : 0; if (!ret) ss->len += len; bpf_put_buffers(); -- 2.53.0