diff mbox series

[FFmpeg-devel,1/3] avcodec/wmavoice: Don't initialize GetBitContext with buf == NULL

Message ID GV1P250MB0737853F680D4ECA74C45F1C8F549@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM
State Accepted
Commit d5eb74b58d95de979c9fa6e2d24ffbc5ac275121
Headers show
Series [FFmpeg-devel,1/3] avcodec/wmavoice: Don't initialize GetBitContext with buf == NULL | expand

Commit Message

Andreas Rheinhardt Sept. 28, 2022, 6:40 p.m. UTC
Happens when flushing. This triggers NULL + 0 (which is UB) in
init_get_bits_xe (which previously errored out, but the return value
has not been checked) and in copy_bits().

This fixes the wmavoice-(7|11|19)k FATE-tests with UBSan.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/wmavoice.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Andreas Rheinhardt Oct. 2, 2022, 5:16 p.m. UTC | #1
Andreas Rheinhardt:
> Happens when flushing. This triggers NULL + 0 (which is UB) in
> init_get_bits_xe (which previously errored out, but the return value
> has not been checked) and in copy_bits().
> 
> This fixes the wmavoice-(7|11|19)k FATE-tests with UBSan.
> 
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
> ---
>  libavcodec/wmavoice.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
> index 4438089e51..26744719e6 100644
> --- a/libavcodec/wmavoice.c
> +++ b/libavcodec/wmavoice.c
> @@ -1900,6 +1900,8 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
>  {
>      WMAVoiceContext *s = ctx->priv_data;
>      GetBitContext *gb = &s->gb;
> +    const uint8_t *buf = avpkt->data;
> +    uint8_t dummy[1];
>      int size, res, pos;
>  
>      /* Packets are sometimes a multiple of ctx->block_align, with a packet
> @@ -1908,7 +1910,8 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
>       * in a single "muxer" packet, so we artificially emulate that by
>       * capping the packet size at ctx->block_align. */
>      for (size = avpkt->size; size > ctx->block_align; size -= ctx->block_align);
> -    init_get_bits8(&s->gb, avpkt->data, size);
> +    buf = size ? buf : dummy;
> +    init_get_bits8(&s->gb, buf, size);
>  
>      /* size == ctx->block_align is used to indicate whether we are dealing with
>       * a new packet or a packet of which we already read the packet header
> @@ -1931,7 +1934,7 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
>              if (cnt + s->spillover_nbits > avpkt->size * 8) {
>                  s->spillover_nbits = avpkt->size * 8 - cnt;
>              }
> -            copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits);
> +            copy_bits(&s->pb, buf, size, gb, s->spillover_nbits);
>              flush_put_bits(&s->pb);
>              s->sframe_cache_size += s->spillover_nbits;
>              if ((res = synth_superframe(ctx, frame, got_frame_ptr)) == 0 &&
> @@ -1968,7 +1971,7 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
>      } else if ((s->sframe_cache_size = pos) > 0) {
>          /* ... cache it for spillover in next packet */
>          init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE);
> -        copy_bits(&s->pb, avpkt->data, size, gb, s->sframe_cache_size);
> +        copy_bits(&s->pb, buf, size, gb, s->sframe_cache_size);
>          // FIXME bad - just copy bytes as whole and add use the
>          // skip_bits_next field
>      }

Will apply this patchset tomorrow unless there are objections.

- Andreas
diff mbox series

Patch

diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index 4438089e51..26744719e6 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -1900,6 +1900,8 @@  static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
 {
     WMAVoiceContext *s = ctx->priv_data;
     GetBitContext *gb = &s->gb;
+    const uint8_t *buf = avpkt->data;
+    uint8_t dummy[1];
     int size, res, pos;
 
     /* Packets are sometimes a multiple of ctx->block_align, with a packet
@@ -1908,7 +1910,8 @@  static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
      * in a single "muxer" packet, so we artificially emulate that by
      * capping the packet size at ctx->block_align. */
     for (size = avpkt->size; size > ctx->block_align; size -= ctx->block_align);
-    init_get_bits8(&s->gb, avpkt->data, size);
+    buf = size ? buf : dummy;
+    init_get_bits8(&s->gb, buf, size);
 
     /* size == ctx->block_align is used to indicate whether we are dealing with
      * a new packet or a packet of which we already read the packet header
@@ -1931,7 +1934,7 @@  static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
             if (cnt + s->spillover_nbits > avpkt->size * 8) {
                 s->spillover_nbits = avpkt->size * 8 - cnt;
             }
-            copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits);
+            copy_bits(&s->pb, buf, size, gb, s->spillover_nbits);
             flush_put_bits(&s->pb);
             s->sframe_cache_size += s->spillover_nbits;
             if ((res = synth_superframe(ctx, frame, got_frame_ptr)) == 0 &&
@@ -1968,7 +1971,7 @@  static int wmavoice_decode_packet(AVCodecContext *ctx, AVFrame *frame,
     } else if ((s->sframe_cache_size = pos) > 0) {
         /* ... cache it for spillover in next packet */
         init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE);
-        copy_bits(&s->pb, avpkt->data, size, gb, s->sframe_cache_size);
+        copy_bits(&s->pb, buf, size, gb, s->sframe_cache_size);
         // FIXME bad - just copy bytes as whole and add use the
         // skip_bits_next field
     }