From: yaydn@protonmail.com Subject: Re: UPDATE: libvpx To: Brad Smith Cc: "ports@openbsd.org" Date: Mon, 15 Jun 2026 06:00:02 +0000 På søndag 14. juni 2026 kl. 09:17, skrev Brad Smith : > Add a big endian decoding fix and a fix for CVE-2026-2447. > > The big endian fix picked up from Solaris via the Linux > Sparc issues tracker. > > Tested on current/amd64. Intel Sandybridge. Built fine. No regressions with light testing in mpv. Hopefully someone with big endian hardware will test too. > Index: Makefile > =================================================================== > RCS file: /cvs/ports/multimedia/libvpx/Makefile,v > retrieving revision 1.63 > diff -u -p -u -p -r1.63 Makefile > --- Makefile 20 Mar 2026 10:31:04 -0000 1.63 > +++ Makefile 14 Jun 2026 06:57:56 -0000 > @@ -3,6 +3,7 @@ COMMENT= Google VP8/VP9 video codec > GH_ACCOUNT= webmproject > GH_PROJECT= libvpx > GH_TAGNAME= v1.16.0 > +REVISION= 0 > EPOCH= 0 > CATEGORIES= multimedia > > Index: patches/patch-vp9_decoder_vp9_detokenize_c > =================================================================== > RCS file: patches/patch-vp9_decoder_vp9_detokenize_c > diff -N patches/patch-vp9_decoder_vp9_detokenize_c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-vp9_decoder_vp9_detokenize_c 14 Jun 2026 06:57:56 -0000 > @@ -0,0 +1,64 @@ > +Fix decoding on big endian architectures > + > +https://github.com/oracle/solaris-userland/blob/e28bd2f2095e272e0090b81a028a5ff86e1091c1/components/desktop/libvpx/patches/01-fix-decoding-sparc.patch > + > +Index: vp9/decoder/vp9_detokenize.c > +--- vp9/decoder/vp9_detokenize.c.orig > ++++ vp9/decoder/vp9_detokenize.c > +@@ -19,6 +19,7 @@ > + #endif > + > + #include "vp9/decoder/vp9_detokenize.h" > ++#include "vpx_util/endian_inl.h" > + > + #define EOB_CONTEXT_NODE 0 > + #define ZERO_CONTEXT_NODE 1 > +@@ -284,6 +285,9 @@ int vp9_decode_block_tokens(TileWorkerData *twd, int p > + int ctx; > + int ctx_shift_a = 0; > + int ctx_shift_l = 0; > ++ uint16_t va16 = 0, vl16 = 0; > ++ uint32_t va32 = 0, vl32 = 0; > ++ uint64_t va64 = 0, vl64 = 0; > + > + switch (tx_size) { > + case TX_4X4: > +@@ -299,8 +303,10 @@ int vp9_decode_block_tokens(TileWorkerData *twd, int p > + ctx += !!*(const uint16_t *)l; > + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, > + dequant, ctx, sc->scan, sc->neighbors, r); > +- *(uint16_t *)a = ((eob > 0) * 0x0101) >> ctx_shift_a; > +- *(uint16_t *)l = ((eob > 0) * 0x0101) >> ctx_shift_l; > ++ va16 = HToLE16(((eob > 0) * 0x0101) >> ctx_shift_a); > ++ vl16 = HToLE16(((eob > 0) * 0x0101) >> ctx_shift_l); > ++ memcpy(a, &va16, sizeof(uint16_t)); > ++ memcpy(l, &vl16, sizeof(uint16_t)); > + break; > + case TX_16X16: > + get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_16X16); > +@@ -308,8 +314,10 @@ int vp9_decode_block_tokens(TileWorkerData *twd, int p > + ctx += !!*(const uint32_t *)l; > + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, > + dequant, ctx, sc->scan, sc->neighbors, r); > +- *(uint32_t *)a = ((eob > 0) * 0x01010101) >> ctx_shift_a; > +- *(uint32_t *)l = ((eob > 0) * 0x01010101) >> ctx_shift_l; > ++ va32 = HToLE32(((eob > 0) * 0x01010101) >> ctx_shift_a); > ++ vl32 = HToLE32(((eob > 0) * 0x01010101) >> ctx_shift_l); > ++ memcpy(a, &va32, sizeof(uint32_t)); > ++ memcpy(l, &vl32, sizeof(uint32_t)); > + break; > + case TX_32X32: > + get_ctx_shift(xd, &ctx_shift_a, &ctx_shift_l, x, y, 1 << TX_32X32); > +@@ -320,8 +328,10 @@ int vp9_decode_block_tokens(TileWorkerData *twd, int p > + ctx += !!*(const uint64_t *)l; > + eob = decode_coefs(xd, get_plane_type(plane), pd->dqcoeff, tx_size, > + dequant, ctx, sc->scan, sc->neighbors, r); > +- *(uint64_t *)a = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_a; > +- *(uint64_t *)l = ((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_l; > ++ va64 = HToLE64(((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_a); > ++ vl64 = HToLE64(((eob > 0) * 0x0101010101010101ULL) >> ctx_shift_l); > ++ memcpy(a, &va64, sizeof(uint64_t)); > ++ memcpy(l, &vl64, sizeof(uint64_t)); > + break; > + default: > + assert(0 && "Invalid transform size."); > Index: patches/patch-vp9_vp9_cx_iface_c > =================================================================== > RCS file: patches/patch-vp9_vp9_cx_iface_c > diff -N patches/patch-vp9_vp9_cx_iface_c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-vp9_vp9_cx_iface_c 14 Jun 2026 06:57:56 -0000 > @@ -0,0 +1,63 @@ > +write_superframe_index: return 0 if buffer is full > +d5f35ac8d93cba7f7a3f7ddb8f9dc8bd28f785e1 > + > +Index: vp9/vp9_cx_iface.c > +--- vp9/vp9_cx_iface.c.orig > ++++ vp9/vp9_cx_iface.c > +@@ -8,7 +8,9 @@ > + * be found in the AUTHORS file in the root of the source tree. > + */ > + > ++#include > + #include > ++#include > + #include > + #include > + #include > +@@ -122,6 +124,7 @@ struct vpx_codec_alg_priv { > + VP9_COMP *cpi; > + unsigned char *cx_data; > + size_t cx_data_sz; > ++ // pending_cx_data either is a null pointer or points into the cx_data buffer. > + unsigned char *pending_cx_data; > + size_t pending_cx_data_sz; > + int pending_frame_count; > +@@ -1252,8 +1255,12 @@ static int write_superframe_index(vpx_codec_alg_priv_t > + > + // Write the index > + index_sz = 2 + (mag + 1) * ctx->pending_frame_count; > +- if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) { > +- uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz; > ++ unsigned char *cx_data_end = ctx->cx_data + ctx->cx_data_sz; > ++ unsigned char *pending_cx_data_end = > ++ ctx->pending_cx_data + ctx->pending_cx_data_sz; > ++ ptrdiff_t space_remaining = cx_data_end - pending_cx_data_end; > ++ if (index_sz <= space_remaining) { > ++ uint8_t *x = pending_cx_data_end; > + int i, j; > + #ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA > + uint8_t marker_test = 0xc0; > +@@ -1284,6 +1291,8 @@ static int write_superframe_index(vpx_codec_alg_priv_t > + #ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA > + index_sz += index_sz_test; > + #endif > ++ } else { > ++ index_sz = 0; > + } > + return index_sz; > + } > +@@ -1612,9 +1621,12 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_pr > + ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; > + ctx->pending_frame_magnitude |= size; > + ctx->pending_cx_data_sz += size; > +- // write the superframe only for the case when > +- if (!ctx->output_cx_pkt_cb.output_cx_pkt) > ++ // write the superframe only for the case when the callback function > ++ // for getting per-layer packets is not registered. > ++ if (!ctx->output_cx_pkt_cb.output_cx_pkt) { > + size += write_superframe_index(ctx); > ++ assert(size <= cx_data_sz); > ++ } > + pkt.data.frame.buf = ctx->pending_cx_data; > + pkt.data.frame.sz = ctx->pending_cx_data_sz; > + ctx->pending_cx_data = NULL; > Index: patches/patch-vpx_util_endian_inl_h > =================================================================== > RCS file: patches/patch-vpx_util_endian_inl_h > diff -N patches/patch-vpx_util_endian_inl_h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-vpx_util_endian_inl_h 14 Jun 2026 06:57:56 -0000 > @@ -0,0 +1,27 @@ > +Fix decoding on big endian architectures > + > +https://github.com/oracle/solaris-userland/blob/e28bd2f2095e272e0090b81a028a5ff86e1091c1/components/desktop/libvpx/patches/01-fix-decoding-sparc.patch > + > +Index: vpx_util/endian_inl.h > +--- vpx_util/endian_inl.h.orig > ++++ vpx_util/endian_inl.h > +@@ -37,15 +37,19 @@ > + #endif > + > + #if defined(WORDS_BIGENDIAN) > ++#define HToLE64 BSwap64 > + #define HToLE32 BSwap32 > + #define HToLE16 BSwap16 > + #define HToBE64(x) (x) > + #define HToBE32(x) (x) > ++#define HToBE16(x) (x) > + #else > ++#define HToLE64(x) (x) > + #define HToLE32(x) (x) > + #define HToLE16(x) (x) > + #define HToBE64(X) BSwap64(X) > + #define HToBE32(X) BSwap32(X) > ++#define HToBE16(x) BSwap16(x) > + #endif > + > + #if LOCAL_GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16) > >