CVE-2013-7008: Other (NVD-CWE-Other)
value: The decode_slice_header function in libavcodec/h264.c in FFmpeg before 2.1 incorrectly relies on a certain droppable field, which allows remote attackers to cause a denial of service (deadlock) or possibly have unspecified other impact via crafted H.264 data.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Published: 2013-12-09T16:36Z
Repository: https://github.com/FFmpeg/FFmpeg
Language: C
Files changed: libavcodec/h264.c
Commit date: 2013-10-24 23:15:30 +0200
Commit message: avcodec/h264: do not trust last_pic_droppable when marking pictures as done

This simplifies the code and fixes a deadlock

Fixes Ticket2927
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Diff: diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 6d7ac58b75a..66720571ab1 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -3619,30 +3619,30 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
             assert(h0->cur_pic_ptr);
             assert(h0->cur_pic_ptr->f.data[0]);
             assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
 
             /* Mark old field/frame as completed */
-            if (!last_pic_droppable && h0->cur_pic_ptr->tf.owner == h0->avctx) {
+            if (h0->cur_pic_ptr->tf.owner == h0->avctx) {
                 ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                           last_pic_structure == PICT_BOTTOM_FIELD);
             }
 
             /* figure out if we have a complementary field pair */
             if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
-                if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
+                if (last_pic_structure != PICT_FRAME) {
                     ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                               last_pic_structure == PICT_TOP_FIELD);
                 }
             } else {
                 if (h0->cur_pic_ptr->frame_num != h->frame_num) {
                     /* This and previous field were reference, but had
                      * different frame_nums. Consider this field first in
                      * pair. Throw away previous field except for reference
                      * purposes. */
-                    if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
+                    if (last_pic_structure != PICT_FRAME) {
                         ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                                   last_pic_structure == PICT_TOP_FIELD);
                     }
                 } else {
                     /* Second field in complementary pair */

Vulnerable code:             if (!last_pic_droppable && h0->cur_pic_ptr->tf.owner == h0->avctx) {
                if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
                    if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
Fixed code:             if (h0->cur_pic_ptr->tf.owner == h0->avctx) {
                if (last_pic_structure != PICT_FRAME) {
                    if (last_pic_structure != PICT_FRAME) {