changeset 670:ad45b044f1e5 NGINX_1_1_19

nginx 1.1.19 *) Security: specially crafted mp4 file might allow to overwrite memory locations in a worker process if the ngx_http_mp4_module was used, potentially resulting in arbitrary code execution (CVE-2012-2089). Thanks to Matthew Daley. *) Bugfix: nginx/Windows might be terminated abnormally. Thanks to Vincent Lee. *) Bugfix: nginx hogged CPU if all servers in an upstream were marked as "backup". *) Bugfix: the "allow" and "deny" directives might be inherited incorrectly if they were used with IPv6 addresses. *) Bugfix: the "modern_browser" and "ancient_browser" directives might be inherited incorrectly. *) Bugfix: timeouts might be handled incorrectly on Solaris/SPARC. *) Bugfix: in the ngx_http_mp4_module.
author Igor Sysoev <http://sysoev.ru>
date Thu, 12 Apr 2012 00:00:00 +0400
parents 3f5d0be5ee74
children 47cb3497fbab
files CHANGES CHANGES.ru src/core/nginx.h src/core/ngx_conf_file.h src/core/ngx_connection.c src/core/ngx_file.c src/core/ngx_inet.c src/core/ngx_murmurhash.h src/core/ngx_rbtree.c src/core/ngx_times.c src/event/modules/ngx_epoll_module.c src/event/modules/ngx_eventport_module.c src/event/modules/ngx_kqueue_module.c src/event/ngx_event_openssl.c src/event/ngx_event_timer.c src/http/modules/ngx_http_access_module.c src/http/modules/ngx_http_browser_module.c src/http/modules/ngx_http_degradation_module.c src/http/modules/ngx_http_mp4_module.c src/http/modules/ngx_http_ssi_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http.c src/http/ngx_http_core_module.c src/http/ngx_http_parse.c src/http/ngx_http_upstream.c src/http/ngx_http_upstream_round_robin.c src/http/ngx_http_variables.c src/os/unix/ngx_daemon.c src/os/unix/ngx_freebsd_rfork_thread.c src/os/unix/ngx_freebsd_sendfile_chain.c src/os/unix/ngx_gcc_atomic_sparc64.h src/os/unix/ngx_setproctitle.c
diffstat 32 files changed, 340 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES	Wed Mar 28 00:00:00 2012 +0400
+++ b/CHANGES	Thu Apr 12 00:00:00 2012 +0400
@@ -1,4 +1,28 @@
 
+Changes with nginx 1.1.19                                        12 Apr 2012
+
+    *) Security: specially crafted mp4 file might allow to overwrite memory
+       locations in a worker process if the ngx_http_mp4_module was used,
+       potentially resulting in arbitrary code execution (CVE-2012-2089).
+       Thanks to Matthew Daley.
+
+    *) Bugfix: nginx/Windows might be terminated abnormally.
+       Thanks to Vincent Lee.
+
+    *) Bugfix: nginx hogged CPU if all servers in an upstream were marked as
+       "backup".
+
+    *) Bugfix: the "allow" and "deny" directives might be inherited
+       incorrectly if they were used with IPv6 addresses.
+
+    *) Bugfix: the "modern_browser" and "ancient_browser" directives might
+       be inherited incorrectly.
+
+    *) Bugfix: timeouts might be handled incorrectly on Solaris/SPARC.
+
+    *) Bugfix: in the ngx_http_mp4_module.
+
+
 Changes with nginx 1.1.18                                        28 Mar 2012
 
     *) Change: keepalive connections are no longer disabled for Safari by
--- a/CHANGES.ru	Wed Mar 28 00:00:00 2012 +0400
+++ b/CHANGES.ru	Thu Apr 12 00:00:00 2012 +0400
@@ -1,4 +1,29 @@
 
+Изменения в nginx 1.1.19                                          12.04.2012
+
+    *) Безопасность: при обработке специально созданного mp4 файла модулем
+       ngx_http_mp4_module могли перезаписываться области памяти рабочего
+       процесса, что могло приводить к выполнению произвольного кода
+       (CVE-2012-2089).
+       Спасибо Matthew Daley.
+
+    *) Исправление: nginx/Windows мог завершаться аварийно.
+       Спасибо Vincent Lee.
+
+    *) Исправление: nginx нагружал процессор, если все серверы в upstream'е
+       были помечены флагом backup.
+
+    *) Исправление: директивы allow и deny могли наследоваться некорректно,
+       если в них использовались IPv6 адреса.
+
+    *) Исправление: директивы modern_browser и ancient_browser могли
+       наследоваться некорректно.
+
+    *) Исправление: таймауты могли работать некорректно на Solaris/SPARC.
+
+    *) Исправление: в модуле ngx_http_mp4_module.
+
+
 Изменения в nginx 1.1.18                                          28.03.2012
 
     *) Изменение: теперь keepalive соединения не запрещены для Safari по
--- a/src/core/nginx.h	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/nginx.h	Thu Apr 12 00:00:00 2012 +0400
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1001018
-#define NGINX_VERSION      "1.1.18"
+#define nginx_version      1001019
+#define NGINX_VERSION      "1.1.19"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_conf_file.h	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_conf_file.h	Thu Apr 12 00:00:00 2012 +0400
@@ -14,7 +14,7 @@
 
 
 /*
- *        AAAA  number of agruments
+ *        AAAA  number of arguments
  *      FF      command flags
  *    TT        command type, i.e. HTTP "location" or "server" command
  */
--- a/src/core/ngx_connection.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_connection.c	Thu Apr 12 00:00:00 2012 +0400
@@ -708,7 +708,7 @@
                     /*
                      * it seems that Linux-2.6.x OpenVZ sends events
                      * for closed shared listening sockets unless
-                     * the events was explicity deleted
+                     * the events was explicitly deleted
                      */
 
                     ngx_del_event(c->read, NGX_READ_EVENT, 0);
--- a/src/core/ngx_file.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_file.c	Thu Apr 12 00:00:00 2012 +0400
@@ -808,7 +808,7 @@
  *     reallocated if ctx->alloc is nonzero
  *
  * ctx->alloc - a size of data structure that is allocated at every level
- *     and is initilialized by ctx->init_handler()
+ *     and is initialized by ctx->init_handler()
  *
  * ctx->log - a log
  *
--- a/src/core/ngx_inet.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_inet.c	Thu Apr 12 00:00:00 2012 +0400
@@ -44,11 +44,7 @@
         return INADDR_NONE;
     }
 
-    if (n != 3) {
-        return INADDR_NONE;
-    }
-
-    if (octet < 256) {
+    if (n == 3 && octet < 256) {
         addr = (addr << 8) + octet;
         return htonl(addr);
     }
@@ -407,6 +403,10 @@
 
 #if (NGX_HAVE_INET6)
     case AF_INET6:
+        if (shift > 128) {
+            return NGX_ERROR;
+        }
+
         addr = cidr->u.in6.addr.s6_addr;
         mask = cidr->u.in6.mask.s6_addr;
         rc = NGX_OK;
@@ -416,7 +416,7 @@
             s = (shift > 8) ? 8 : shift;
             shift -= s;
 
-            mask[i] = (u_char) (0 - (1 << (8 - s)));
+            mask[i] = (u_char) (0xffu << (8 - s));
 
             if (addr[i] != (addr[i] & mask[i])) {
                 rc = NGX_DONE;
@@ -428,9 +428,12 @@
 #endif
 
     default: /* AF_INET */
+        if (shift > 32) {
+            return NGX_ERROR;
+        }
 
         if (shift) {
-            cidr->u.in.mask = htonl((ngx_uint_t) (0 - (1 << (32 - shift))));
+            cidr->u.in.mask = htonl((uint32_t) (0xffffffffu << (32 - shift)));
 
         } else {
             /* x86 compilers use a shl instruction that shifts by modulo 32 */
@@ -459,7 +462,7 @@
     struct sockaddr_in6  *sin6;
 
     /*
-     * prevent MSVC8 waring:
+     * prevent MSVC8 warning:
      *    potentially uninitialized local variable 'inaddr6' used
      */
     ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr));
--- a/src/core/ngx_murmurhash.h	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_murmurhash.h	Thu Apr 12 00:00:00 2012 +0400
@@ -16,4 +16,4 @@
 uint32_t ngx_murmur_hash2(u_char *data, size_t len);
 
 
-#endif /* _NGX_CRC_H_INCLUDED_ */
+#endif /* _NGX_MURMURHASH_H_INCLUDED_ */
--- a/src/core/ngx_rbtree.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_rbtree.c	Thu Apr 12 00:00:00 2012 +0400
@@ -136,8 +136,7 @@
 
         /*  node->key < temp->key */
 
-        p = ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key
-              < 0)
+        p = ((ngx_rbtree_key_int_t) (node->key - temp->key) < 0)
             ? &temp->left : &temp->right;
 
         if (*p == sentinel) {
--- a/src/core/ngx_times.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/core/ngx_times.c	Thu Apr 12 00:00:00 2012 +0400
@@ -33,7 +33,7 @@
 #if !(NGX_WIN32)
 
 /*
- * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
+ * localtime() and localtime_r() are not Async-Signal-Safe functions, therefore,
  * they must not be called by a signal handler, so we use the cached
  * GMT offset value. Fortunately the value is changed only two times a year.
  */
@@ -308,7 +308,7 @@
     /*
      * The "days" should be adjusted to 1 only, however, some March 1st's go
      * to previous year, so we adjust them to 2.  This causes also shift of the
-     * last Feburary days to next year, but we catch the case when "yday"
+     * last February days to next year, but we catch the case when "yday"
      * becomes negative.
      */
 
--- a/src/event/modules/ngx_epoll_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/event/modules/ngx_epoll_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -445,7 +445,7 @@
 
     /*
      * when the file descriptor is closed, the epoll automatically deletes
-     * it from its queue, so we do not need to delete explicity the event
+     * it from its queue, so we do not need to delete explicitly the event
      * before the closing the file descriptor
      */
 
@@ -524,7 +524,7 @@
 
     /*
      * when the file descriptor is closed the epoll automatically deletes
-     * it from its queue so we do not need to delete explicity the event
+     * it from its queue so we do not need to delete explicitly the event
      * before the closing the file descriptor
      */
 
--- a/src/event/modules/ngx_eventport_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/event/modules/ngx_eventport_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -322,7 +322,7 @@
 
     /*
      * when the file descriptor is closed, the event port automatically
-     * dissociates it from the port, so we do not need to dissociate explicity
+     * dissociates it from the port, so we do not need to dissociate explicitly
      * the event before the closing the file descriptor
      */
 
--- a/src/event/modules/ngx_kqueue_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/event/modules/ngx_kqueue_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -377,7 +377,7 @@
 
     /*
      * when the file descriptor is closed the kqueue automatically deletes
-     * its filters so we do not need to delete explicity the event
+     * its filters so we do not need to delete explicitly the event
      * before the closing the file descriptor.
      */
 
--- a/src/event/ngx_event_openssl.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/event/ngx_event_openssl.c	Thu Apr 12 00:00:00 2012 +0400
@@ -489,7 +489,7 @@
 
     /*
      * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
-     * from RFC 4492 section 5.1.1, or explicitely described curves over
+     * from RFC 4492 section 5.1.1, or explicitly described curves over
      * binary fields. OpenSSL only supports the "named curves", which provide
      * maximum interoperability.
      */
--- a/src/event/ngx_event_timer.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/event/ngx_event_timer.c	Thu Apr 12 00:00:00 2012 +0400
@@ -67,7 +67,7 @@
 
     ngx_mutex_unlock(ngx_event_timer_mutex);
 
-    timer = (ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec;
+    timer = (ngx_msec_int_t) (node->key - ngx_current_msec);
 
     return (ngx_msec_t) (timer > 0 ? timer : 0);
 }
@@ -95,8 +95,7 @@
 
         /* node->key <= ngx_current_time */
 
-        if ((ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec <= 0)
-        {
+        if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) {
             ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
 
 #if (NGX_THREADS)
--- a/src/http/modules/ngx_http_access_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/modules/ngx_http_access_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -351,14 +351,19 @@
     ngx_http_access_loc_conf_t  *prev = parent;
     ngx_http_access_loc_conf_t  *conf = child;
 
+#if (NGX_HAVE_INET6)
+
+    if (conf->rules == NULL && conf->rules6 == NULL) {
+        conf->rules = prev->rules;
+        conf->rules6 = prev->rules6;
+    }
+
+#else
+
     if (conf->rules == NULL) {
         conf->rules = prev->rules;
     }
 
-#if (NGX_HAVE_INET6)
-    if (conf->rules6 == NULL) {
-        conf->rules6 = prev->rules6;
-    }
 #endif
 
     return NGX_CONF_OK;
--- a/src/http/modules/ngx_http_browser_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/modules/ngx_http_browser_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -458,10 +458,11 @@
      * with a real skip value.  The zero value means Opera.
      */
 
-    if (conf->modern_browsers == NULL) {
+    if (conf->modern_browsers == NULL && conf->modern_unlisted_browsers == 0) {
         conf->modern_browsers = prev->modern_browsers;
+        conf->modern_unlisted_browsers = prev->modern_unlisted_browsers;
 
-    } else {
+    } else if (conf->modern_browsers != NULL) {
         browsers = conf->modern_browsers->elts;
 
         for (i = 0; i < conf->modern_browsers->nelts; i++) {
@@ -501,8 +502,9 @@
         }
     }
 
-    if (conf->ancient_browsers == NULL) {
+    if (conf->ancient_browsers == NULL && conf->netscape4 == 0) {
         conf->ancient_browsers = prev->ancient_browsers;
+        conf->netscape4 = prev->netscape4;
     }
 
     if (conf->modern_browser_value == NULL) {
--- a/src/http/modules/ngx_http_degradation_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/modules/ngx_http_degradation_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -126,7 +126,7 @@
              * ELF/i386 is loaded at 0x08000000, 128M
              * ELF/amd64 is loaded at 0x00400000, 4M
              *
-             * use a function address to substract the loading address
+             * use a function address to subtract the loading address
              */
 
             sbrk_size = (size_t) sbrk(0) - ((uintptr_t) ngx_palloc & ~0x3FFFFF);
--- a/src/http/modules/ngx_http_mp4_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/modules/ngx_http_mp4_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -156,6 +156,7 @@
 
 #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
 
 
@@ -204,7 +205,7 @@
 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,
@@ -265,7 +266,7 @@
     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);
@@ -701,7 +702,9 @@
             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) {
@@ -752,7 +755,7 @@
                  - start_offset;
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
-                   "mp4 adjustment:%D", adjustment);
+                   "mp4 adjustment:%O", adjustment);
 
     for (i = 0; i < mp4->trak.nelts; i++) {
         if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) {
@@ -793,10 +796,8 @@
 
     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;
@@ -813,17 +814,14 @@
 
             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);
 
@@ -835,20 +833,26 @@
             }
         }
 
-        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) {
@@ -875,14 +879,24 @@
 
 
 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) {
@@ -890,7 +904,6 @@
         }
 
         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,
@@ -900,11 +913,15 @@
         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;
 }
@@ -919,7 +936,9 @@
 
     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);
@@ -1168,6 +1187,12 @@
     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);
@@ -1175,6 +1200,14 @@
 
     } 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);
     }
@@ -1345,12 +1378,26 @@
     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);
     }
 
@@ -1474,6 +1521,12 @@
     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);
@@ -1481,6 +1534,14 @@
 
     } 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);
     }
@@ -1756,12 +1817,9 @@
     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;
     }
 
@@ -1825,21 +1883,28 @@
     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);
 
+    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 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);
 
-    if ((uint64_t) (atom_end - stts_atom->version) > atom_data_size) {
-        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
-                      "\"%s\" mp4 stts atom too large",
-                      mp4->file.name.data);
-        return NGX_ERROR;
-    }
-
     trak = ngx_mp4_last_trak(mp4);
     trak->time_to_sample_entries = entries;
 
@@ -1910,7 +1975,7 @@
 
         if (start_time < (uint64_t) count * duration) {
             start_sample += (ngx_uint_t) (start_time / duration);
-            count -= start_sample;
+            count -= (uint32_t) (start_time / duration);
             ngx_mp4_set_32value(entry->count, count);
             goto found;
         }
@@ -1973,6 +2038,12 @@
     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,
@@ -1988,14 +2059,16 @@
     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;
@@ -2118,6 +2191,12 @@
     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,
@@ -2133,14 +2212,16 @@
     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;
@@ -2251,21 +2332,28 @@
     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);
 
+    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 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);
 
-    if ((uint64_t) (atom_end - stsc_atom->version) > atom_data_size) {
-        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
-                      "\"%s\" mp4 stsc atom too large",
-                      mp4->file.name.data);
-        return NGX_ERROR;
-    }
-
     trak = ngx_mp4_last_trak(mp4);
     trak->sample_to_chunk_entries = entries;
 
@@ -2317,6 +2405,13 @@
         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;
 
@@ -2458,6 +2553,12 @@
     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);
 
@@ -2477,15 +2578,17 @@
     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;
@@ -2507,7 +2610,7 @@
 }
 
 
-static void
+static ngx_int_t
 ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
     ngx_http_mp4_trak_t *trak)
 {
@@ -2528,6 +2631,13 @@
     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;
 
@@ -2548,6 +2658,8 @@
         ngx_mp4_set_32value(stsz_atom->entries,
                             trak->sample_sizes_entries - trak->start_sample);
     }
+
+    return NGX_OK;
 }
 
 
@@ -2577,19 +2689,27 @@
     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);
 
+    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 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);
 
-    if ((uint64_t) (atom_end - stco_atom->version) > atom_data_size) {
-        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
-                      "\"%s\" mp4 stco atom too large", mp4->file.name.data);
-        return NGX_ERROR;
-    }
-
     trak = ngx_mp4_last_trak(mp4);
     trak->chunks = entries;
 
@@ -2638,6 +2758,13 @@
         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;
@@ -2713,19 +2840,27 @@
     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);
 
+    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 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);
 
-    if ((uint64_t) (atom_end - co64_atom->version) > atom_data_size) {
-        ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
-                      "\"%s\" mp4 co64 atom too large", mp4->file.name.data);
-        return NGX_ERROR;
-    }
-
     trak = ngx_mp4_last_trak(mp4);
     trak->chunks = entries;
 
@@ -2774,6 +2909,13 @@
         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;
+    }
+
     data->pos += trak->start_chunk * sizeof(uint64_t);
     atom_size = sizeof(ngx_mp4_co64_atom_t) + (data->last - data->pos);
     trak->size += atom_size;
--- a/src/http/modules/ngx_http_ssi_filter_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/modules/ngx_http_ssi_filter_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -714,7 +714,7 @@
 
                 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                                  "too many SSI command paramters: \"%V\"",
+                                  "too many SSI command parameters: \"%V\"",
                                   &ctx->command);
                     goto ssi_error;
                 }
--- a/src/http/modules/perl/nginx.pm	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/modules/perl/nginx.pm	Thu Apr 12 00:00:00 2012 +0400
@@ -50,7 +50,7 @@
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '1.1.18';
+our $VERSION = '1.1.19';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/ngx_http.c	Thu Apr 12 00:00:00 2012 +0400
@@ -1417,7 +1417,7 @@
 
         /*
          * check whether all name-based servers have the same
-         * configuraiton as a default server for given address:port
+         * configuration as a default server for given address:port
          */
 
         addr = port[p].addrs.elts;
--- a/src/http/ngx_http_core_module.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/ngx_http_core_module.c	Thu Apr 12 00:00:00 2012 +0400
@@ -1228,20 +1228,29 @@
             len = tf->name.len;
         }
 
-        /* 16 bytes are preallocation */
-        reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16;
+        if (!alias) {
+            reserve = len > r->uri.len ? len - r->uri.len : 0;
+
+#if (NGX_PCRE)
+        } else if (clcf->regex) {
+            reserve = len;
+#endif
+
+        } else {
+            reserve = len > r->uri.len - alias ? len - (r->uri.len - alias) : 0;
+        }
 
         if (reserve > allocated) {
 
-            /* we just need to allocate path and to copy a root */
-
-            if (ngx_http_map_uri_to_path(r, &path, &root, reserve) == NULL) {
+            /* 16 bytes are preallocation */
+            allocated = reserve + 16;
+
+            if (ngx_http_map_uri_to_path(r, &path, &root, allocated) == NULL) {
                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
                 return NGX_OK;
             }
 
             name = path.data + root;
-            allocated = path.len - root - (r->uri.len - alias);
          }
 
         if (tf->values == NULL) {
--- a/src/http/ngx_http_parse.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/ngx_http_parse.c	Thu Apr 12 00:00:00 2012 +0400
@@ -1097,7 +1097,7 @@
 
         /*
          * we use "ch = *p++" inside the cycle, but this operation is safe,
-         * because after the URI there is always at least one charcter:
+         * because after the URI there is always at least one character:
          * the line feed
          */
 
--- a/src/http/ngx_http_upstream.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/ngx_http_upstream.c	Thu Apr 12 00:00:00 2012 +0400
@@ -1196,7 +1196,7 @@
     {
         /*
          * the r->request_body->buf can be reused for one request only,
-         * the subrequests should allocate their own temporay bufs
+         * the subrequests should allocate their own temporary bufs
          */
 
         u->output.free = ngx_alloc_chain_link(r->pool);
--- a/src/http/ngx_http_upstream_round_robin.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/ngx_http_upstream_round_robin.c	Thu Apr 12 00:00:00 2012 +0400
@@ -49,6 +49,13 @@
             n += server[i].naddrs;
         }
 
+        if (n == 0) {
+            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                          "no servers in upstream \"%V\" in %s:%ui",
+                          &us->host, us->file_name, us->line);
+            return NGX_ERROR;
+        }
+
         peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
                               + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
         if (peers == NULL) {
--- a/src/http/ngx_http_variables.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/http/ngx_http_variables.c	Thu Apr 12 00:00:00 2012 +0400
@@ -112,7 +112,7 @@
 /*
  * the $http_host, $http_user_agent, $http_referer, $http_via,
  * and $http_x_forwarded_for variables may be handled by generic
- * ngx_http_variable_unknown_header_in(), but for perfomance reasons
+ * ngx_http_variable_unknown_header_in(), but for performance reasons
  * they are handled using dedicated entries
  */
 
--- a/src/os/unix/ngx_daemon.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/os/unix/ngx_daemon.c	Thu Apr 12 00:00:00 2012 +0400
@@ -9,7 +9,8 @@
 #include <ngx_core.h>
 
 
-ngx_int_t ngx_daemon(ngx_log_t *log)
+ngx_int_t
+ngx_daemon(ngx_log_t *log)
 {
     int  fd;
 
--- a/src/os/unix/ngx_freebsd_rfork_thread.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c	Thu Apr 12 00:00:00 2012 +0400
@@ -11,14 +11,14 @@
 /*
  * The threads implementation uses the rfork(RFPROC|RFTHREAD|RFMEM) syscall
  * to create threads.  All threads use the stacks of the same size mmap()ed
- * below the main stack.  Thus the current thread id is determinated via
+ * below the main stack.  Thus the current thread id is determined via
  * the stack pointer value.
  *
  * The mutex implementation uses the ngx_atomic_cmp_set() operation
  * to acquire a mutex and the SysV semaphore to wait on a mutex and to wake up
  * the waiting threads.  The light mutex does not use semaphore, so after
  * spinning in the lock the thread calls sched_yield().  However the light
- * mutecies are intended to be used with the "trylock" operation only.
+ * mutexes are intended to be used with the "trylock" operation only.
  * The SysV semop() is a cheap syscall, particularly if it has little sembuf's
  * and does not use SEM_UNDO.
  *
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c	Thu Apr 12 00:00:00 2012 +0400
@@ -18,7 +18,7 @@
  * as the 11 full 1460-bytes packets, then one incomplete 324-bytes packet,
  * and then again the 11 full 1460-bytes packets.
  *
- * Threfore we use the TCP_NOPUSH option (similar to Linux's TCP_CORK)
+ * Therefore we use the TCP_NOPUSH option (similar to Linux's TCP_CORK)
  * to postpone the sending - it not only sends a header and the first part of
  * the file in one packet, but also sends the file pages in the full packets.
  *
--- a/src/os/unix/ngx_gcc_atomic_sparc64.h	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/os/unix/ngx_gcc_atomic_sparc64.h	Thu Apr 12 00:00:00 2012 +0400
@@ -15,7 +15,7 @@
  *         r0 = [r1];
  *     }
  *
- * so "r0 == r2" means that the operation was successfull.
+ * so "r0 == r2" means that the operation was successful.
  *
  *
  * The "r" means the general register.
--- a/src/os/unix/ngx_setproctitle.c	Wed Mar 28 00:00:00 2012 +0400
+++ b/src/os/unix/ngx_setproctitle.c	Thu Apr 12 00:00:00 2012 +0400
@@ -21,7 +21,7 @@
  * from argv[0] for our process title.
  *
  * The Solaris's standard /bin/ps does not show the changed process title.
- * You have to use "/usr/ucb/ps -w" instead.  Besides, the UCB ps dos not
+ * You have to use "/usr/ucb/ps -w" instead.  Besides, the UCB ps does not
  * show a new title if its length less than the origin command line length.
  * To avoid it we append to a new title the origin command line in the
  * parenthesis.