1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-05 16:55:50 +03:00

Fix bit-shifting of websockets frame fields that would yield wrong opcodes

when the FIN bit was set.  Results in PING not being recognized
by mod_lua.  PR57524

Submitted By: Edward Lu
Committed By: covener



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1657256 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Covener
2015-02-04 14:33:51 +00:00
parent e454f1a48b
commit 8f40799093
2 changed files with 16 additions and 5 deletions

View File

@@ -1,6 +1,10 @@
-*- coding: utf-8 -*- -*- coding: utf-8 -*-
Changes with Apache 2.5.0 Changes with Apache 2.5.0
*) 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 *) mod_macro: Clear macros before initialization to avoid use-after-free
on startup or restart when the module is linked statically. PR 57525 on startup or restart when the module is linked statically. PR 57525
[apache.org tech.futurequest.net, Yann Ylavic] [apache.org tech.futurequest.net, Yann Ylavic]

View File

@@ -2252,9 +2252,12 @@ static int lua_websocket_read(lua_State *L)
rv = lua_websocket_readbytes(r->connection, &byte, 1); rv = lua_websocket_readbytes(r->connection, &byte, 1);
} }
if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) {
unsigned char fin, opcode, mask, payload; unsigned char ubyte, fin, opcode, mask, payload;
fin = byte >> 7; ubyte = (unsigned char)byte;
opcode = (byte << 4) >> 4; /* fin bit is the first bit */
fin = ubyte >> (CHAR_BIT - 1);
/* opcode is the last four bits (there's 3 reserved bits we don't care about) */
opcode = ubyte & 0xf;
/* Get the payload length and mask bit */ /* Get the payload length and mask bit */
if (plaintext) { if (plaintext) {
@@ -2264,14 +2267,18 @@ static int lua_websocket_read(lua_State *L)
rv = lua_websocket_readbytes(r->connection, &byte, 1); rv = lua_websocket_readbytes(r->connection, &byte, 1);
} }
if (rv == APR_SUCCESS) { if (rv == APR_SUCCESS) {
mask = byte >> 7; ubyte = (unsigned char)byte;
payload = byte - 128; /* Mask is the first bit */
mask = ubyte >> (CHAR_BIT - 1);
/* Payload is the last 7 bits */
payload = ubyte & 0x7f;
plen = payload; plen = payload;
/* Extended payload? */ /* Extended payload? */
if (payload == 126) { if (payload == 126) {
len = 2; len = 2;
if (plaintext) { if (plaintext) {
/* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
rv = apr_socket_recv(sock, (char*) &payload_short, &len); rv = apr_socket_recv(sock, (char*) &payload_short, &len);
} }
else { else {