hi,

SECURITY FIX for nginx OPENBSD_5_1 branch.

resolves: 
CVE-2012-2089 - Buffer overflow in the ngx_http_mp4_module
CVE-2012-1180 - Memory disclosure with specially crafted backend responses

OK ?
Index: Makefile
===================================================================
RCS file: /cvs/ports/www/nginx/Makefile,v
retrieving revision 1.48
diff -u -p -r1.48 Makefile
--- Makefile    18 Jan 2012 10:00:52 -0000      1.48
+++ Makefile    15 Apr 2012 15:20:12 -0000
@@ -2,6 +2,7 @@
 
 COMMENT=       robust and small HTTP server and mail proxy server
 
+REVISION=      0
 DISTNAME=      nginx-1.0.11
 CATEGORIES=    www
 
Index: patches/patch-src_http_modules_ngx_http_fastcgi_module_c
===================================================================
RCS file: patches/patch-src_http_modules_ngx_http_fastcgi_module_c
diff -N patches/patch-src_http_modules_ngx_http_fastcgi_module_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_http_modules_ngx_http_fastcgi_module_c    15 Apr 2012 
15:20:12 -0000
@@ -0,0 +1,23 @@
+$OpenBSD$
+
+SECURITY FIX:
+CVE-2012-1180 - Memory disclosure with specially crafted backend responses
+patch from upstream: http://nginx.org/download/patch.2012.memory.txt
+
+--- src/http/modules/ngx_http_fastcgi_module.c.orig    Wed Dec 14 13:13:25 2011
++++ src/http/modules/ngx_http_fastcgi_module.c Sun Apr 15 12:00:09 2012
+@@ -1445,10 +1445,10 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
+                     h->lowcase_key = h->key.data + h->key.len + 1
+                                      + h->value.len + 1;
+ 
+-                    ngx_cpystrn(h->key.data, r->header_name_start,
+-                                h->key.len + 1);
+-                    ngx_cpystrn(h->value.data, r->header_start,
+-                                h->value.len + 1);
++                    ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
++                    h->key.data[h->key.len] = '\0';
++                    ngx_memcpy(h->value.data, r->header_start, h->value.len);
++                    h->value.data[h->value.len] = '\0';
+                 }
+ 
+                 h->hash = r->header_hash;
Index: patches/patch-src_http_modules_ngx_http_mp4_module_c
===================================================================
RCS file: patches/patch-src_http_modules_ngx_http_mp4_module_c
diff -N patches/patch-src_http_modules_ngx_http_mp4_module_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_http_modules_ngx_http_mp4_module_c        15 Apr 2012 
15:20:14 -0000
@@ -0,0 +1,588 @@
+$OpenBSD$
+
+SECURITY FIX:
+CVE-2012-2089 - Buffer overflow in the ngx_http_mp4_module
+patch from upstream: http://nginx.org/download/patch.2012.mp4.txt
+
+--- src/http/modules/ngx_http_mp4_module.c.orig        Wed Dec 14 16:02:37 2011
++++ src/http/modules/ngx_http_mp4_module.c     Sun Apr 15 12:11:24 2012
+@@ -155,6 +155,7 @@ typedef struct {
+ 
+ #define ngx_mp4_atom_header(mp4)   (mp4->buffer_pos - 8)
+ #define ngx_mp4_atom_data(mp4)     mp4->buffer_pos
++#define ngx_mp4_atom_data_size(t)  (uint64_t) (sizeof(t) - 8)
+ #define ngx_mp4_atom_next(mp4, n)  mp4->buffer_pos += n; mp4->offset += n
+ 
+ 
+@@ -203,7 +204,7 @@ typedef struct {
+ static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4);
+ static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
+     ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size);
+-static ngx_int_t ngx_http_mp4_read(ngx_http_mp4_file_t *mp4);
++static ngx_int_t ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size);
+ static ngx_int_t ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4,
+     uint64_t atom_data_size);
+ static ngx_int_t ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4,
+@@ -264,7 +265,7 @@ static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_htt
+     ngx_http_mp4_trak_t *trak);
+ static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4,
+     uint64_t atom_data_size);
+-static void ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
++static ngx_int_t ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
+     ngx_http_mp4_trak_t *trak);
+ static ngx_int_t ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4,
+     uint64_t atom_data_size);
+@@ -692,7 +693,9 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
+             return NGX_ERROR;
+         }
+ 
+-        ngx_http_mp4_update_stsz_atom(mp4, &trak[i]);
++        if (ngx_http_mp4_update_stsz_atom(mp4, &trak[i]) != NGX_OK) {
++            return NGX_ERROR;
++        }
+ 
+         if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) {
+             if (ngx_http_mp4_update_co64_atom(mp4, &trak[i]) != NGX_OK) {
+@@ -784,10 +787,8 @@ ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
+ 
+     while (mp4->offset < end) {
+ 
+-        if (mp4->buffer_pos + sizeof(uint32_t) > mp4->buffer_end) {
+-            if (ngx_http_mp4_read(mp4) != NGX_OK) {
+-                return NGX_ERROR;
+-            }
++        if (ngx_http_mp4_read(mp4, sizeof(uint32_t)) != NGX_OK) {
++            return NGX_ERROR;
+         }
+ 
+         atom_header = mp4->buffer_pos;
+@@ -804,17 +805,14 @@ ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
+ 
+             if (atom_size == 1) {
+ 
+-                if (mp4->buffer_pos + sizeof(ngx_mp4_atom_header64_t)
+-                    > mp4->buffer_end)
++                if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header64_t))
++                    != NGX_OK)
+                 {
+-                    if (ngx_http_mp4_read(mp4) != NGX_OK) {
+-                        return NGX_ERROR;
+-                    }
+-
+-                    atom_header = mp4->buffer_pos;
++                    return NGX_ERROR;
+                 }
+ 
+                 /* 64-bit atom size */
++                atom_header = mp4->buffer_pos;
+                 atom_size = ngx_mp4_get_64value(atom_header + 8);
+                 atom_header_size = sizeof(ngx_mp4_atom_header64_t);
+ 
+@@ -826,20 +824,26 @@ ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
+             }
+         }
+ 
+-        if (mp4->buffer_pos + sizeof(ngx_mp4_atom_header_t) > 
mp4->buffer_end) {
+-            if (ngx_http_mp4_read(mp4) != NGX_OK) {
+-                return NGX_ERROR;
+-            }
+-
+-            atom_header = mp4->buffer_pos;
++        if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header_t)) != NGX_OK) {
++            return NGX_ERROR;
+         }
+ 
++        atom_header = mp4->buffer_pos;
+         atom_name = atom_header + sizeof(uint32_t);
+ 
+         ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+                        "mp4 atom: %*s @%O:%uL",
+                        4, atom_name, mp4->offset, atom_size);
+ 
++        if (atom_size > (uint64_t) (NGX_MAX_OFF_T_VALUE - mp4->offset)
++            || mp4->offset + (off_t) atom_size > end)
++        {
++            ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                          "\"%s\" mp4 atom too large:%uL",
++                          mp4->file.name.data, atom_size);
++            return NGX_ERROR;
++        }
++
+         for (n = 0; atom[n].name; n++) {
+ 
+             if (ngx_strncmp(atom_name, atom[n].name, 4) == 0) {
+@@ -866,14 +870,24 @@ ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
+ 
+ 
+ static ngx_int_t
+-ngx_http_mp4_read(ngx_http_mp4_file_t *mp4)
++ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size)
+ {
+-    ngx_int_t  n;
++    ssize_t  n;
+ 
++    if (mp4->buffer_pos + size <= mp4->buffer_end) {
++        return NGX_OK;
++    }
++
+     if (mp4->offset + (off_t) mp4->buffer_size > mp4->end) {
+         mp4->buffer_size = (size_t) (mp4->end - mp4->offset);
+     }
+ 
++    if (mp4->buffer_size < size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 file truncated", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     if (mp4->buffer == NULL) {
+         mp4->buffer = ngx_palloc(mp4->request->pool, mp4->buffer_size);
+         if (mp4->buffer == NULL) {
+@@ -881,7 +895,6 @@ ngx_http_mp4_read(ngx_http_mp4_file_t *mp4)
+         }
+ 
+         mp4->buffer_start = mp4->buffer;
+-        mp4->buffer_end = mp4->buffer + mp4->buffer_size;
+     }
+ 
+     n = ngx_read_file(&mp4->file, mp4->buffer_start, mp4->buffer_size,
+@@ -891,11 +904,15 @@ ngx_http_mp4_read(ngx_http_mp4_file_t *mp4)
+         return NGX_ERROR;
+     }
+ 
+-    if (n == 0) {
+-        return NGX_OK;
++    if ((size_t) n != mp4->buffer_size) {
++        ngx_log_error(NGX_LOG_CRIT, mp4->file.log, 0,
++                      ngx_read_file_n " read only %z of %z from \"%s\"",
++                      n, mp4->buffer_size, mp4->file.name.data);
++        return NGX_ERROR;
+     }
+ 
+     mp4->buffer_pos = mp4->buffer_start;
++    mp4->buffer_end = mp4->buffer_start + mp4->buffer_size;
+ 
+     return NGX_OK;
+ }
+@@ -910,7 +927,9 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, 
+ 
+     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom");
+ 
+-    if (atom_data_size > 1024) {
++    if (atom_data_size > 1024
++        || ngx_mp4_atom_data(mp4) + atom_data_size > mp4->buffer_end)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+                       "\"%s\" mp4 ftyp atom is too large:%uL",
+                       mp4->file.name.data, atom_data_size);
+@@ -1159,6 +1178,12 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, 
+     mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_mvhd_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 mvhd atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     if (mvhd_atom->version[0] == 0) {
+         /* version 0: 32-bit duration */
+         timescale = ngx_mp4_get_32value(mvhd_atom->timescale);
+@@ -1166,6 +1191,14 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, 
+ 
+     } else {
+         /* version 1: 64-bit duration */
++
++        if (ngx_mp4_atom_data_size(ngx_mp4_mvhd64_atom_t) > atom_data_size) {
++            ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                          "\"%s\" mp4 mvhd atom too small",
++                          mp4->file.name.data);
++            return NGX_ERROR;
++        }
++
+         timescale = ngx_mp4_get_32value(mvhd64_atom->timescale);
+         duration = ngx_mp4_get_64value(mvhd64_atom->duration);
+     }
+@@ -1336,12 +1369,26 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, 
+     tkhd64_atom = (ngx_mp4_tkhd64_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(tkhd_atom, 't', 'k', 'h', 'd');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_tkhd_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 tkhd atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     if (tkhd_atom->version[0] == 0) {
+         /* version 0: 32-bit duration */
+         duration = ngx_mp4_get_32value(tkhd_atom->duration);
+ 
+     } else {
+         /* version 1: 64-bit duration */
++
++        if (ngx_mp4_atom_data_size(ngx_mp4_tkhd64_atom_t) > atom_data_size) {
++            ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                          "\"%s\" mp4 tkhd atom too small",
++                          mp4->file.name.data);
++            return NGX_ERROR;
++        }
++
+         duration = ngx_mp4_get_64value(tkhd64_atom->duration);
+     }
+ 
+@@ -1465,6 +1512,12 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, 
+     mdhd64_atom = (ngx_mp4_mdhd64_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(mdhd_atom, 'm', 'd', 'h', 'd');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_mdhd_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 mdhd atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     if (mdhd_atom->version[0] == 0) {
+         /* version 0: everything is 32-bit */
+         timescale = ngx_mp4_get_32value(mdhd_atom->timescale);
+@@ -1472,6 +1525,14 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, 
+ 
+     } else {
+         /* version 1: 64-bit duration and 32-bit timescale */
++
++        if (ngx_mp4_atom_data_size(ngx_mp4_mdhd64_atom_t) > atom_data_size) {
++            ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                          "\"%s\" mp4 mdhd atom too small",
++                          mp4->file.name.data);
++            return NGX_ERROR;
++        }
++
+         timescale = ngx_mp4_get_32value(mdhd64_atom->timescale);
+         duration = ngx_mp4_get_64value(mdhd64_atom->duration);
+     }
+@@ -1747,12 +1808,9 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, 
+     ngx_mp4_set_32value(stsd_atom->size, atom_size);
+     ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd');
+ 
+-    if ((uint64_t) (sizeof(ngx_mp4_stsd_atom_t) - 
sizeof(ngx_mp4_atom_header_t))
+-         > atom_data_size)
+-    {
++    if (ngx_mp4_atom_data_size(ngx_mp4_stsd_atom_t) > atom_data_size) {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 stsd atom too large",
+-                      mp4->file.name.data);
++                      "\"%s\" mp4 stsd atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
+@@ -1816,21 +1874,28 @@ ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, 
+     stts_atom = (ngx_mp4_stts_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(stts_atom, 's', 't', 't', 's');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 stts atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     entries = ngx_mp4_get_32value(stts_atom->entries);
+ 
+     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+                    "mp4 time-to-sample entries:%uD", entries);
+ 
+-    atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t);
+-    atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t);
+-
+-    if ((uint64_t) (atom_end - stts_atom->version) > atom_data_size) {
++    if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t)
++        + entries * sizeof(ngx_mp4_stts_entry_t) > atom_data_size)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 stts atom too large",
+-                      mp4->file.name.data);
++                      "\"%s\" mp4 stts atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
++    atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t);
++    atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t);
++
+     trak = ngx_mp4_last_trak(mp4);
+     trak->time_to_sample_entries = entries;
+ 
+@@ -1964,6 +2029,12 @@ ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, 
+     stss_atom = (ngx_http_mp4_stss_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(stss_atom, 's', 't', 's', 's');
+ 
++    if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 stss atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     entries = ngx_mp4_get_32value(stss_atom->entries);
+ 
+     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+@@ -1979,14 +2050,16 @@ ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, 
+     atom->pos = atom_header;
+     atom->last = atom_table;
+ 
+-    atom_end = atom_table + entries * sizeof(uint32_t);
+-
+-    if ((uint64_t) (atom_end - stss_atom->version) > atom_data_size) {
++    if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t)
++        + entries * sizeof(uint32_t) > atom_data_size)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 stss atom too large", mp4->file.name.data);
++                      "\"%s\" mp4 stss atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
++    atom_end = atom_table + entries * sizeof(uint32_t);
++
+     data = &trak->stss_data_buf;
+     data->temporary = 1;
+     data->pos = atom_table;
+@@ -2109,6 +2182,12 @@ ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, 
+     ctts_atom = (ngx_mp4_ctts_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(ctts_atom, 'c', 't', 't', 's');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 ctts atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     entries = ngx_mp4_get_32value(ctts_atom->entries);
+ 
+     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+@@ -2124,14 +2203,16 @@ ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, 
+     atom->pos = atom_header;
+     atom->last = atom_table;
+ 
+-    atom_end = atom_table + entries * sizeof(ngx_mp4_ctts_entry_t);
+-
+-    if ((uint64_t) (atom_end - ctts_atom->version) > atom_data_size) {
++    if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t)
++        + entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 ctts atom too large", mp4->file.name.data);
++                      "\"%s\" mp4 ctts atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
++    atom_end = atom_table + entries * sizeof(ngx_mp4_ctts_entry_t);
++
+     data = &trak->ctts_data_buf;
+     data->temporary = 1;
+     data->pos = atom_table;
+@@ -2242,21 +2323,28 @@ ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, 
+     stsc_atom = (ngx_mp4_stsc_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(stsc_atom, 's', 't', 's', 'c');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 stsc atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     entries = ngx_mp4_get_32value(stsc_atom->entries);
+ 
+     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+                    "sample-to-chunk entries:%uD", entries);
+ 
+-    atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t);
+-    atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t);
+-
+-    if ((uint64_t) (atom_end - stsc_atom->version) > atom_data_size) {
++    if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t)
++        + entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 stsc atom too large",
+-                      mp4->file.name.data);
++                      "\"%s\" mp4 stsc atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
++    atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t);
++    atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t);
++
+     trak = ngx_mp4_last_trak(mp4);
+     trak->sample_to_chunk_entries = entries;
+ 
+@@ -2308,6 +2396,13 @@ ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4
+         return NGX_ERROR;
+     }
+ 
++    if (trak->sample_to_chunk_entries == 0) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "zero number of entries in stsc atom in \"%s\"",
++                      mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     start_sample = (uint32_t) trak->start_sample;
+     entries = trak->sample_to_chunk_entries - 1;
+ 
+@@ -2447,6 +2542,12 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, 
+     stsz_atom = (ngx_mp4_stsz_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(stsz_atom, 's', 't', 's', 'z');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 stsz atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     size = ngx_mp4_get_32value(stsz_atom->uniform_size);
+     entries = ngx_mp4_get_32value(stsz_atom->entries);
+ 
+@@ -2466,15 +2567,17 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, 
+     trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf = atom;
+ 
+     if (size == 0) {
+-        atom_end = atom_table + entries * sizeof(uint32_t);
+-
+-        if ((uint64_t) (atom_end - stsz_atom->version) > atom_data_size) {
++        if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t)
++            + entries * sizeof(uint32_t) > atom_data_size)
++        {
+             ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                          "\"%s\" mp4 stsz atom too large",
++                          "\"%s\" mp4 stsz atom too small",
+                           mp4->file.name.data);
+             return NGX_ERROR;
+         }
+ 
++        atom_end = atom_table + entries * sizeof(uint32_t);
++
+         data = &trak->stsz_data_buf;
+         data->temporary = 1;
+         data->pos = atom_table;
+@@ -2496,7 +2599,7 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, 
+ }
+ 
+ 
+-static void
++static ngx_int_t
+ ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
+     ngx_http_mp4_trak_t *trak)
+ {
+@@ -2517,6 +2620,13 @@ ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4
+     data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf;
+ 
+     if (data) {
++        if (trak->start_sample > trak->sample_sizes_entries) {
++            ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                          "start time is out mp4 stsz samples in \"%s\"",
++                          mp4->file.name.data);
++            return NGX_ERROR;
++        }
++
+         data->pos += trak->start_sample * sizeof(uint32_t);
+         end = (uint32_t *) data->pos;
+ 
+@@ -2537,6 +2647,8 @@ ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4
+         ngx_mp4_set_32value(stsz_atom->entries,
+                             trak->sample_sizes_entries - trak->start_sample);
+     }
++
++    return NGX_OK;
+ }
+ 
+ 
+@@ -2566,19 +2678,27 @@ ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, 
+     stco_atom = (ngx_mp4_stco_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(stco_atom, 's', 't', 'c', 'o');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 stco atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     entries = ngx_mp4_get_32value(stco_atom->entries);
+ 
+     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", 
entries);
+ 
+-    atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t);
+-    atom_end = atom_table + entries * sizeof(uint32_t);
+-
+-    if ((uint64_t) (atom_end - stco_atom->version) > atom_data_size) {
++    if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t)
++        + entries * sizeof(uint32_t) > atom_data_size)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 stco atom too large", mp4->file.name.data);
++                      "\"%s\" mp4 stco atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
++    atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t);
++    atom_end = atom_table + entries * sizeof(uint32_t);
++
+     trak = ngx_mp4_last_trak(mp4);
+     trak->chunks = entries;
+ 
+@@ -2627,6 +2747,13 @@ ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4
+         return NGX_ERROR;
+     }
+ 
++    if (trak->start_chunk > trak->chunks) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "start time is out mp4 stco chunks in \"%s\"",
++                      mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     data->pos += trak->start_chunk * sizeof(uint32_t);
+     atom_size = sizeof(ngx_mp4_stco_atom_t) + (data->last - data->pos);
+     trak->size += atom_size;
+@@ -2702,19 +2829,27 @@ ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, 
+     co64_atom = (ngx_mp4_co64_atom_t *) atom_header;
+     ngx_mp4_set_atom_name(co64_atom, 'c', 'o', '6', '4');
+ 
++    if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) > atom_data_size) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "\"%s\" mp4 co64 atom too small", mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
+     entries = ngx_mp4_get_32value(co64_atom->entries);
+ 
+     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", 
entries);
+ 
+-    atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t);
+-    atom_end = atom_table + entries * sizeof(uint64_t);
+-
+-    if ((uint64_t) (atom_end - co64_atom->version) > atom_data_size) {
++    if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t)
++        + entries * sizeof(uint64_t) > atom_data_size)
++    {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+-                      "\"%s\" mp4 co64 atom too large", mp4->file.name.data);
++                      "\"%s\" mp4 co64 atom too small", mp4->file.name.data);
+         return NGX_ERROR;
+     }
+ 
++    atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t);
++    atom_end = atom_table + entries * sizeof(uint64_t);
++
+     trak = ngx_mp4_last_trak(mp4);
+     trak->chunks = entries;
+ 
+@@ -2759,6 +2894,13 @@ ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4
+     if (data == NULL) {
+         ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
+                       "no mp4 co64 atoms were found in \"%s\"",
++                      mp4->file.name.data);
++        return NGX_ERROR;
++    }
++
++    if (trak->start_chunk > trak->chunks) {
++        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
++                      "start time is out mp4 co64 chunks in \"%s\"",
+                       mp4->file.name.data);
+         return NGX_ERROR;
+     }
Index: patches/patch-src_http_modules_ngx_http_proxy_module_c
===================================================================
RCS file: patches/patch-src_http_modules_ngx_http_proxy_module_c
diff -N patches/patch-src_http_modules_ngx_http_proxy_module_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_http_modules_ngx_http_proxy_module_c      15 Apr 2012 
15:20:14 -0000
@@ -0,0 +1,21 @@
+$OpenBSD$
+
+SECURITY FIX:
+CVE-2012-1180 - Memory disclosure with specially crafted backend responses
+patch from upstream: http://nginx.org/download/patch.2012.memory.txt
+
+--- src/http/modules/ngx_http_proxy_module.c.orig      Wed Dec 14 13:13:25 2011
++++ src/http/modules/ngx_http_proxy_module.c   Sun Apr 15 12:00:09 2012
+@@ -1277,8 +1277,10 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
+             h->value.data = h->key.data + h->key.len + 1;
+             h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
+ 
+-            ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
+-            ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
++            ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
++            h->key.data[h->key.len] = '\0';
++            ngx_memcpy(h->value.data, r->header_start, h->value.len);
++            h->value.data[h->value.len] = '\0';
+ 
+             if (h->key.len == r->lowcase_index) {
+                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
Index: patches/patch-src_http_modules_ngx_http_scgi_module_c
===================================================================
RCS file: patches/patch-src_http_modules_ngx_http_scgi_module_c
diff -N patches/patch-src_http_modules_ngx_http_scgi_module_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_http_modules_ngx_http_scgi_module_c       15 Apr 2012 
15:20:14 -0000
@@ -0,0 +1,21 @@
+$OpenBSD$
+
+SECURITY FIX:
+CVE-2012-1180 - Memory disclosure with specially crafted backend responses
+patch from upstream: http://nginx.org/download/patch.2012.memory.txt
+
+--- src/http/modules/ngx_http_scgi_module.c.orig       Wed Dec 14 13:28:13 2011
++++ src/http/modules/ngx_http_scgi_module.c    Sun Apr 15 12:00:09 2012
+@@ -898,8 +898,10 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
+             h->value.data = h->key.data + h->key.len + 1;
+             h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
+ 
+-            ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
+-            ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
++            ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
++            h->key.data[h->key.len] = '\0';
++            ngx_memcpy(h->value.data, r->header_start, h->value.len);
++            h->value.data[h->value.len] = '\0';
+ 
+             if (h->key.len == r->lowcase_index) {
+                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
Index: patches/patch-src_http_modules_ngx_http_uwsgi_module_c
===================================================================
RCS file: patches/patch-src_http_modules_ngx_http_uwsgi_module_c
diff -N patches/patch-src_http_modules_ngx_http_uwsgi_module_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_http_modules_ngx_http_uwsgi_module_c      15 Apr 2012 
15:20:14 -0000
@@ -0,0 +1,21 @@
+$OpenBSD$
+
+SECURITY FIX:
+CVE-2012-1180 - Memory disclosure with specially crafted backend responses
+patch from upstream: http://nginx.org/download/patch.2012.memory.txt
+
+--- src/http/modules/ngx_http_uwsgi_module.c.orig      Wed Dec 14 13:13:25 2011
++++ src/http/modules/ngx_http_uwsgi_module.c   Sun Apr 15 12:00:09 2012
+@@ -946,8 +946,10 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
+             h->value.data = h->key.data + h->key.len + 1;
+             h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
+ 
+-            ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
+-            ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
++            ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
++            h->key.data[h->key.len] = '\0';
++            ngx_memcpy(h->value.data, r->header_start, h->value.len);
++            h->value.data[h->value.len] = '\0';
+ 
+             if (h->key.len == r->lowcase_index) {
+                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
Index: patches/patch-src_http_ngx_http_parse_c
===================================================================
RCS file: patches/patch-src_http_ngx_http_parse_c
diff -N patches/patch-src_http_ngx_http_parse_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_http_ngx_http_parse_c     15 Apr 2012 15:20:14 -0000
@@ -0,0 +1,57 @@
+$OpenBSD$
+
+SECURITY FIX:
+CVE-2012-1180 - Memory disclosure with specially crafted backend responses
+patch from upstream: http://nginx.org/download/patch.2012.memory.txt
+
+--- src/http/ngx_http_parse.c.orig     Wed Jun 23 13:34:54 2010
++++ src/http/ngx_http_parse.c  Sun Apr 15 12:00:49 2012
+@@ -813,6 +813,10 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_
+                     break;
+                 }
+ 
++                if (ch == '\0') {
++                    return NGX_HTTP_PARSE_INVALID_HEADER;
++                }
++
+                 r->invalid_header = 1;
+ 
+                 break;
+@@ -875,6 +879,10 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_
+                 break;
+             }
+ 
++            if (ch == '\0') {
++                return NGX_HTTP_PARSE_INVALID_HEADER;
++            }
++
+             r->invalid_header = 1;
+ 
+             break;
+@@ -893,6 +901,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_
+                 r->header_start = p;
+                 r->header_end = p;
+                 goto done;
++            case '\0':
++                return NGX_HTTP_PARSE_INVALID_HEADER;
+             default:
+                 r->header_start = p;
+                 state = sw_value;
+@@ -914,6 +924,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_
+             case LF:
+                 r->header_end = p;
+                 goto done;
++            case '\0':
++                return NGX_HTTP_PARSE_INVALID_HEADER;
+             }
+             break;
+ 
+@@ -927,6 +939,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_
+                 break;
+             case LF:
+                 goto done;
++            case '\0':
++                return NGX_HTTP_PARSE_INVALID_HEADER;
+             default:
+                 state = sw_value;
+                 break;

Reply via email to