[x264-devel] Buffer overflow in x264_plane_copy_interleave_neon
Kirill Batuzov
batuzovk at ispras.ru
Fri Aug 26 15:30:35 CEST 2016
On Thu, 25 Aug 2016, Henrik Gramner wrote:
>
> The ARM code should be fixed to do the same.
Looks like x86 wrappers can be used for ARM as well without any changes.
Here is a proof of concept patch. I copy-pasted the wrapper and renamed
the assembler function. This did fix the problem for my case. Just to be
clear, I'm not ready to sign up to do a proper fix, just reporting a bug
and sharing whatever relevant information I dug up.
diff --git a/common/arm/mc-a.S b/common/arm/mc-a.S
index 76295cd..549d5bf 100644
--- a/common/arm/mc-a.S
+++ b/common/arm/mc-a.S
@@ -1577,7 +1577,7 @@ block4:
pop {r4-r8, r10, r11, pc}
endfunc
-function x264_plane_copy_interleave_neon
+function x264_plane_copy_interleave_core_neon
push {r4-r7, lr}
ldrd r6, r7, [sp, #28]
ldrd r4, r5, [sp, #20]
diff --git a/common/arm/mc-c.c b/common/arm/mc-c.c
index d330bc3..40ef325 100644
--- a/common/arm/mc-c.c
+++ b/common/arm/mc-c.c
@@ -57,7 +57,7 @@ void x264_plane_copy_deinterleave_rgb_neon( pixel *dsta, intptr_t i_dsta,
pixel *dstb, intptr_t i_dstb,
pixel *dstc, intptr_t i_dstc,
pixel *src, intptr_t i_src, int pw, int w, int h );
-void x264_plane_copy_interleave_neon( pixel *dst, intptr_t i_dst,
+void x264_plane_copy_interleave_core_neon( pixel *dst, intptr_t i_dst,
pixel *srcu, intptr_t i_srcu,
pixel *srcv, intptr_t i_srcv, int w, int h );
void x264_plane_copy_swap_neon( pixel *dst, intptr_t i_dst,
@@ -67,6 +67,36 @@ void x264_store_interleave_chroma_neon( pixel *dst, intptr_t i_dst, pixel *srcu,
void x264_load_deinterleave_chroma_fdec_neon( pixel *dst, pixel *src, intptr_t i_src, int height );
void x264_load_deinterleave_chroma_fenc_neon( pixel *dst, pixel *src, intptr_t i_src, int height );
+#define PLANE_INTERLEAVE(cpu) \
+static void x264_plane_copy_interleave_##cpu( pixel *dst, intptr_t i_dst,\
+ pixel *srcu, intptr_t i_srcu,\
+ pixel *srcv, intptr_t i_srcv, int w, int h )\
+{\
+ int c_w = 16 / sizeof(pixel) - 1;\
+ if( !(w&c_w) )\
+ x264_plane_copy_interleave_core_##cpu( dst, i_dst, srcu, i_srcu, srcv, i_srcv, w, h );\
+ else if( w > c_w && (i_srcu ^ i_srcv) >= 0 ) /* only works correctly for strides with identical signs */\
+ {\
+ if( --h > 0 )\
+ {\
+ if( i_srcu > 0 )\
+ {\
+ x264_plane_copy_interleave_core_##cpu( dst, i_dst, srcu, i_srcu, srcv, i_srcv, (w+c_w)&~c_w, h );\
+ dst += i_dst * h;\
+ srcu += i_srcu * h;\
+ srcv += i_srcv * h;\
+ }\
+ else\
+ x264_plane_copy_interleave_core_##cpu( dst+i_dst, i_dst, srcu+i_srcu, i_srcu, srcv+i_srcv, i_srcv, (w+c_w)&~c_w, h );\
+ }\
+ x264_plane_copy_interleave_c( dst, 0, srcu, 0, srcv, 0, w, 1 );\
+ }\
+ else\
+ x264_plane_copy_interleave_c( dst, i_dst, srcu, i_srcu, srcv, i_srcv, w, h );\
+}
+
+PLANE_INTERLEAVE(neon)
+
#if !HIGH_BIT_DEPTH
#define MC_WEIGHT(func)\
void x264_mc_weight_w20##func##_neon( uint8_t *, intptr_t, uint8_t *, intptr_t, const x264_weight_t *, int );\
More information about the x264-devel
mailing list