CVE-2015-0228: Improper Input Validation (CWE-20)
value: The lua_websocket_read function in lua_request.c in the mod_lua module in the Apache HTTP Server through 2.4.12 allows remote attackers to cause a denial of service (child-process crash) by sending a crafted WebSocket Ping frame after a Lua script has called the wsupgrade function.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Published: 2015-03-08T02:59Z
Repository: https://github.com/apache/httpd
Language: Other
Files changed: CHANGES, modules/lua/lua_request.c
Commit date: 2015-02-04 14:44:23 +0000
Commit message: *) SECURITY: CVE-2015-0228 (cve.mitre.org)
     mod_lua: A maliciously crafted websockets PING after a script
     calls r:wsupgrade() can cause a child process crash.
     [Edward Lu <Chaosed0 gmail.com>]

Discovered by Guido Vranken <guidovranken gmail.com>

Submitted by: Edward Lu
Committed by: covener



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1657261 13f79535-47bb-0310-9956-ffa450edef68

Diff: diff --git a/CHANGES b/CHANGES
index aa79dac9c..02141ef5b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,13 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) SECURITY: CVE-2015-0228 (cve.mitre.org)
+     mod_lua: A maliciously crafted websockets PING after a script
+     calls r:wsupgrade() can cause a child process crash. 
+     [Edward Lu <Chaosed0 gmail.com>]
+
   *) mod_lua: After a r:wsupgrade(), mod_lua was not properly
      responding to a websockets PING but instead invoking the specified 
      script. PR57524. [Edward Lu <Chaosed0 gmail.com>]
 
   *) mod_macro: Clear macros before initialization to avoid use-after-free
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
index dded599a4..1200c55b3 100644
--- a/modules/lua/lua_request.c
+++ b/modules/lua/lua_request.c
@@ -2225,10 +2225,11 @@ static int lua_websocket_peek(lua_State *L)
 
 static int lua_websocket_read(lua_State *L) 
 {
     apr_socket_t *sock;
     apr_status_t rv;
+    int do_read = 1;
     int n = 0;
     apr_size_t len = 1;
     apr_size_t plen = 0;
     unsigned short payload_short = 0;
     apr_uint64_t payload_long = 0;
@@ -2242,10 +2243,12 @@ static int lua_websocket_read(lua_State *L)
 
     
     mask_bytes = apr_pcalloc(r->pool, 4);
     sock = ap_get_conn_socket(r->connection);
 
+    while (do_read) { 
+    do_read = 0;
     /* Get opcode and FIN bit */
     if (plaintext) {
         rv = apr_socket_recv(sock, &byte, &len);
     }
     else {
@@ -2375,14 +2378,15 @@ static int lua_websocket_read(lua_State *L)
                 char frame[2];
                 plen = 2;
                 frame[0] = 0x8A;
                 frame[1] = 0;
                 apr_socket_send(sock, frame, &plen); /* Pong! */
-                lua_websocket_read(L); /* read the next frame instead */
+                do_read = 1;
             }
         }
     }
+    }
     return 0;
 }
 
 
 static int lua_websocket_write(lua_State *L) 

Vulnerable code:                 lua_websocket_read(L); /* read the next frame instead */
Fixed code:   *) SECURITY: CVE-2015-0228 (cve.mitre.org)
     mod_lua: A maliciously crafted websockets PING after a script
     calls r:wsupgrade() can cause a child process crash. 
     [Edward Lu <Chaosed0 gmail.com>]

    int do_read = 1;
    while (do_read) { 
    do_read = 0;
                do_read = 1;
    }