Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Fix UBSan `-fsanitize=function` violations in `vidinput.c` vtbl dispatch:
`yuv_input.c` and `y4m_input.c` functions registered in `YUV_INPUT_VTBL` /
`Y4M_INPUT_VTBL` used concrete `yuv_input *` / `y4m_input *` parameter types
instead of the erased `void *` mandated by the typedef in `vidinput.h`.
UBSan detected these as type-mismatched indirect calls on every frame read.
Added vtbl-compatible static wrapper functions; removed C-style casts from
both VTBL initialisers. Netflix golden scores unchanged.
44 changes: 37 additions & 7 deletions core/tools/y4m_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,12 +1016,42 @@ static int y4m_fetch_into_vmaf_picture(y4m_input *_y4m, FILE *_fin, VmafPicture
return 1;
}

OC_EXTERN const video_input_vtbl Y4M_INPUT_VTBL = {
(raw_input_open_func)NULL,
(video_input_open_func)y4m_input_open,
(video_input_get_info_func)y4m_input_get_info,
(video_input_fetch_frame_func)y4m_input_fetch_frame,
(video_input_close_func)y4m_input_close,
(video_input_fetch_into_vmaf_picture_func)y4m_fetch_into_vmaf_picture};
/*
* vtbl-compatible wrapper functions — match the exact function pointer
* signatures in vidinput.h to avoid UBSan -fsanitize=function violations.
* The concrete y4m_input* implementations remain typed for readability.
*/
static void *y4m_vtbl_open(FILE *fin)
{
return y4m_input_open(fin);
}

static void y4m_vtbl_get_info(void *ctx, video_input_info *info)
{
y4m_input_get_info((y4m_input *)ctx, info);
}

static int y4m_vtbl_fetch_frame(void *ctx, FILE *fin, video_input_ycbcr ycbcr, char tag[5])
{
return y4m_input_fetch_frame((y4m_input *)ctx, fin, ycbcr, tag);
}

static void y4m_vtbl_close(void *ctx)
{
y4m_input_close((y4m_input *)ctx);
}

static int y4m_vtbl_fetch_into_vmaf_picture(void *ctx, FILE *fin, VmafPicture *pic)
{
return y4m_fetch_into_vmaf_picture((y4m_input *)ctx, fin, pic);
}

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) — extern linkage required: vidinput.c references this symbol via `extern video_input_vtbl Y4M_INPUT_VTBL`
OC_EXTERN const video_input_vtbl Y4M_INPUT_VTBL = {NULL,
y4m_vtbl_open,
y4m_vtbl_get_info,
y4m_vtbl_fetch_frame,
y4m_vtbl_close,
y4m_vtbl_fetch_into_vmaf_picture};

// NOLINTEND(bugprone-unchecked-string-to-number-conversion,cert-err34-c)
41 changes: 35 additions & 6 deletions core/tools/yuv_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,40 @@ static int yuv_fetch_into_vmaf_picture(yuv_input *yuv, FILE *fin, VmafPicture *p
return 1;
}

/*
* vtbl-compatible wrapper functions — each matches the exact function pointer
* signature in vidinput.h so the VTBL initializer below requires no C-style
* casts. The casts were previously silencing a type mismatch between the
* concrete `yuv_input *` parameter and the erased `void *` in the typedef,
* which UBSan's -fsanitize=function detects at runtime as undefined behaviour.
* The concrete implementations remain typed for readability and safety.
*/
static void *yuv_vtbl_open_raw(FILE *fin, unsigned w, unsigned h, int pix_fmt, unsigned bitdepth)
{
return yuv_input_open(fin, w, h, (enum VmafPixelFormat)pix_fmt, bitdepth);
}

static void yuv_vtbl_get_info(void *ctx, video_input_info *info)
{
yuv_input_get_info((yuv_input *)ctx, info);
}

static int yuv_vtbl_fetch_frame(void *ctx, FILE *fin, video_input_ycbcr ycbcr, char tag[5])
{
return yuv_input_fetch_frame((yuv_input *)ctx, fin, ycbcr, tag);
}

static void yuv_vtbl_close(void *ctx)
{
yuv_input_close((yuv_input *)ctx);
}

static int yuv_vtbl_fetch_into_vmaf_picture(void *ctx, FILE *fin, VmafPicture *pic)
{
return yuv_fetch_into_vmaf_picture((yuv_input *)ctx, fin, pic);
}

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) — extern linkage required: vidinput.c references this symbol via `extern video_input_vtbl YUV_INPUT_VTBL`
OC_EXTERN const video_input_vtbl YUV_INPUT_VTBL = {
(raw_input_open_func)yuv_input_open,
(video_input_open_func)NULL,
(video_input_get_info_func)yuv_input_get_info,
(video_input_fetch_frame_func)yuv_input_fetch_frame,
(video_input_close_func)yuv_input_close,
(video_input_fetch_into_vmaf_picture_func)yuv_fetch_into_vmaf_picture};
yuv_vtbl_open_raw, NULL, yuv_vtbl_get_info,
yuv_vtbl_fetch_frame, yuv_vtbl_close, yuv_vtbl_fetch_into_vmaf_picture};
Loading