Summary
When OBI detects the HTTP/2 client preface, it advances args->u_buf past the preface but leaves args->bytes_len unchanged. Later HTTP/2 frame parsing still uses the old length while reading from the shifted pointer.
Impact
This can over-read past the valid post-preface payload and potentially export adjacent process memory into telemetry. The issue is limited to observability data exposure, so low severity is appropriate.
Environment
- First identified in: a0a038c
- Reviewed against current
main commit: d51a98d
Evidence
bpf/generictracer/protocol_handler.c still shifts args->u_buf by MIN_HTTP2_SIZE.
bpf/generictracer/protocol_http2.h still reads frame headers from the shifted pointer.
- The same parser still uses the unchanged
bytes_len as its bound.
Steps to reproduce
- From the repository root on
main, create /tmp/http2_preface_oob.c with these exact contents:
#include <arpa/inet.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MIN_HTTP2_SIZE = 24 };
typedef struct __attribute__((packed)) {
uint32_t length;
uint8_t type;
uint8_t flags;
uint32_t stream_id;
} frame_header_t;
typedef struct {
unsigned char *u_buf;
int bytes_len;
} call_protocol_args_t;
typedef struct {
call_protocol_args_t args;
uint32_t pos;
} grpc_frames_ctx_t;
static frame_header_t next_frame(const grpc_frames_ctx_t *g_ctx) {
const void *offset = (const unsigned char *)g_ctx->args.u_buf + g_ctx->pos;
frame_header_t header;
memcpy(&header, offset, sizeof(header));
header.length = ntohl(header.length << 8);
header.stream_id = ntohl(header.stream_id << 1);
return header;
}
int main(void) {
unsigned char *buf = malloc(MIN_HTTP2_SIZE + 1);
grpc_frames_ctx_t ctx = {0};
frame_header_t frame;
memset(buf, 0, MIN_HTTP2_SIZE + 1);
ctx.args.u_buf = buf;
ctx.args.bytes_len = MIN_HTTP2_SIZE + 1;
ctx.args.u_buf = ctx.args.u_buf + MIN_HTTP2_SIZE;
frame = next_frame(&ctx);
printf("frame type=%u len=%u stream=%u\n", frame.type, frame.length, frame.stream_id);
free(buf);
return 0;
}
- Build the ASan harness with
gcc -fsanitize=address -fno-omit-frame-pointer -O0 -g -o /tmp/http2_preface_oob /tmp/http2_preface_oob.c.
- Run
/tmp/http2_preface_oob.
- Observe that AddressSanitizer reports a heap-buffer-overflow after the HTTP/2 preface skip, proving the parser advances the pointer without shrinking the length.
Suggested Fix Direction
Reduce args->bytes_len whenever the preface is skipped, or track a separate effective length for the post-preface buffer.
Acceptance Criteria
- Pointer and effective length stay consistent after HTTP/2 preface handling.
- Small post-preface buffers do not cause parser over-reads.
- Tests cover preface-only and preface-plus-short-payload cases.
Note
I have reviewed this issue before posting it. It was identified by OpenAI Codex, and the draft was prepared with its assistance, but it may still contain mistakes, missing context, or incorrect conclusions. Please independently validate the behavior, impact, and proposed fix before acting on it.
Summary
When OBI detects the HTTP/2 client preface, it advances
args->u_bufpast the preface but leavesargs->bytes_lenunchanged. Later HTTP/2 frame parsing still uses the old length while reading from the shifted pointer.Impact
This can over-read past the valid post-preface payload and potentially export adjacent process memory into telemetry. The issue is limited to observability data exposure, so
lowseverity is appropriate.Environment
maincommit: d51a98dEvidence
bpf/generictracer/protocol_handler.cstill shiftsargs->u_bufbyMIN_HTTP2_SIZE.bpf/generictracer/protocol_http2.hstill reads frame headers from the shifted pointer.bytes_lenas its bound.Steps to reproduce
main, create/tmp/http2_preface_oob.cwith these exact contents:gcc -fsanitize=address -fno-omit-frame-pointer -O0 -g -o /tmp/http2_preface_oob /tmp/http2_preface_oob.c./tmp/http2_preface_oob.Suggested Fix Direction
Reduce
args->bytes_lenwhenever the preface is skipped, or track a separate effective length for the post-preface buffer.Acceptance Criteria
Note
I have reviewed this issue before posting it. It was identified by OpenAI Codex, and the draft was prepared with its assistance, but it may still contain mistakes, missing context, or incorrect conclusions. Please independently validate the behavior, impact, and proposed fix before acting on it.