[PATCHv7 06/13] kexec_file: Chain the stages into a pipeline

bot+bpf-ci at kernel.org bot+bpf-ci at kernel.org
Sat Mar 21 19:14:24 PDT 2026


> diff --git a/kernel/kexec_bpf_loader.c b/kernel/kexec_bpf_loader.c
> index af16f7b685d9..7f7884411e2c 100644
> --- a/kernel/kexec_bpf_loader.c
> +++ b/kernel/kexec_bpf_loader.c

[ ... ]

> @@ -301,6 +305,23 @@ static int kexec_buff_parser(struct bpf_parser_context *parser)
>  				vfree(ctx->kernel);
>  				ctx->kernel = decompressed_buf;
>  				ctx->kernel_sz = decompressed_sz;
> +				if (fill_pipeline) {
> +					int i;
> +
> +					for (i = 0; i < MAX_PARSING_BUF_NUM; i++) {
> +						if (ctx->next_parsing_buf[i])
> +							continue;
> +						ctx->next_parsing_buf[i] = decompressed_buf;
> +						ctx->next_parsing_buf_sz[i] = decompressed_sz;
> +						break;
> +					}

After this, both ctx->kernel and ctx->next_parsing_buf[i] point to
the same decompressed_buf allocation. When next_parsing_buf is later
promoted to parsing_buf in process_bpf_parsers_container(), there
are two independent references to the same memory.

If the next BPF stage issues another KEXEC_BPF_CMD_DECOMPRESS for
KEXEC_BPF_SUBCMD_KERNEL, vfree(ctx->kernel) frees the buffer while
parsing_buf[i] still references it.

The KEXEC_BPF_CMD_COPY path avoids this by allocating a separate
copy with __vmalloc(). Should the DECOMPRESS path do the same to
prevent aliased ownership?

> +					/* No enough parsing slot */
> +					if (i == MAX_PARSING_BUF_NUM) {
> +						ctx->kernel = NULL;
> +						vfree(decompressed_buf);
> +						return -ENOMEM;
> +					}
> +				}
>  				break;

[ ... ]

> @@ -313,6 +334,22 @@ static int kexec_buff_parser(struct bpf_parser_context *parser)
>  		if (!p)
>  			return -ENOMEM;
>  		memcpy(p, buf, cmd->payload_len);
> +		if (fill_pipeline) {
> +			pn = __vmalloc(cmd->payload_len, GFP_KERNEL | __GFP_ACCOUNT);
> +			if (!pn) {
> +				vfree(p);
> +				return -ENOMEM;
> +			}
> +			memcpy(pn, buf, cmd->payload_len);
> +			for (int i = 0; i < MAX_PARSING_BUF_NUM; i++) {
> +				if (!ctx->next_parsing_buf[i]) {
> +					ctx->next_parsing_buf[i] = pn;
> +					ctx->next_parsing_buf_sz[i] = cmd->payload_len;
> +					break;
> +				}
> +			}
> +		}

If all MAX_PARSING_BUF_NUM slots are already occupied, the loop
completes without storing pn anywhere, and the allocation is leaked.

The DECOMPRESS path handles this case with an explicit check:

    if (i == MAX_PARSING_BUF_NUM) {
        ctx->kernel = NULL;
        vfree(decompressed_buf);
        return -ENOMEM;
    }

Is a similar overflow check missing here for the COPY path?

[ ... ]


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23393379437


More information about the kexec mailing list