BUG/MEDIUM: lua: somme HTTP manipulation functions are called without valid requests

Somme HTTP manipulation functions are executed without valid and parsed
requests or responses. This causes a segmentation fault when the executed
code tries to change an empty buffer.

This patch must be backported in the 1.6 version
This commit is contained in:
Thierry FOURNIER / OZON.IO 2016-08-02 23:44:58 +02:00 committed by Willy Tarreau
parent 53e381c3a0
commit b84ae92615

View File

@ -4155,6 +4155,10 @@ __LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, str
if (!htxn->s->txn) if (!htxn->s->txn)
return 1; return 1;
/* Check if a valid response is parsed */
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
return 1;
/* Build array of headers. */ /* Build array of headers. */
old_idx = 0; old_idx = 0;
cur_next = msg->chn->buf->p + hdr_idx_first_pos(&htxn->s->txn->hdr_idx); cur_next = msg->chn->buf->p + hdr_idx_first_pos(&htxn->s->txn->hdr_idx);
@ -4269,6 +4273,10 @@ __LJMP static inline int hlua_http_rep_hdr(lua_State *L, struct hlua_txn *htxn,
const char *value = MAY_LJMP(luaL_checkstring(L, 4)); const char *value = MAY_LJMP(luaL_checkstring(L, 4));
struct my_regex re; struct my_regex re;
/* Check if a valid response is parsed */
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
return 0;
if (!regex_comp(reg, &re, 1, 1, NULL)) if (!regex_comp(reg, &re, 1, 1, NULL))
WILL_LJMP(luaL_argerror(L, 3, "invalid regex")); WILL_LJMP(luaL_argerror(L, 3, "invalid regex"));
@ -4327,6 +4335,10 @@ __LJMP static inline int hlua_http_del_hdr(lua_State *L, struct hlua_txn *htxn,
struct hdr_ctx ctx; struct hdr_ctx ctx;
struct http_txn *txn = htxn->s->txn; struct http_txn *txn = htxn->s->txn;
/* Check if a valid response is parsed */
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
return 0;
ctx.idx = 0; ctx.idx = 0;
while (http_find_header2(name, len, msg->chn->buf->p, &txn->hdr_idx, &ctx)) while (http_find_header2(name, len, msg->chn->buf->p, &txn->hdr_idx, &ctx))
http_remove_header2(msg, &txn->hdr_idx, &ctx); http_remove_header2(msg, &txn->hdr_idx, &ctx);
@ -4364,6 +4376,10 @@ __LJMP static inline int hlua_http_add_hdr(lua_State *L, struct hlua_txn *htxn,
const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len)); const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
char *p; char *p;
/* Check if a valid message is parsed */
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
return 0;
/* Check length. */ /* Check length. */
trash.len = value_len + name_len + 2; trash.len = value_len + name_len + 2;
if (trash.len > trash.size) if (trash.len > trash.size)
@ -4434,6 +4450,12 @@ static int hlua_http_req_set_meth(lua_State *L)
size_t name_len; size_t name_len;
const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len)); const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
/* Check if a valid request is parsed */
if (unlikely(htxn->s->txn->req.msg_state < HTTP_MSG_BODY)) {
lua_pushboolean(L, 0);
return 1;
}
lua_pushboolean(L, http_replace_req_line(0, name, name_len, htxn->p, htxn->s) != -1); lua_pushboolean(L, http_replace_req_line(0, name, name_len, htxn->p, htxn->s) != -1);
return 1; return 1;
} }
@ -4444,6 +4466,13 @@ static int hlua_http_req_set_path(lua_State *L)
struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1)); struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
size_t name_len; size_t name_len;
const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len)); const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
/* Check if a valid request is parsed */
if (unlikely(htxn->s->txn->req.msg_state < HTTP_MSG_BODY)) {
lua_pushboolean(L, 0);
return 1;
}
lua_pushboolean(L, http_replace_req_line(1, name, name_len, htxn->p, htxn->s) != -1); lua_pushboolean(L, http_replace_req_line(1, name, name_len, htxn->p, htxn->s) != -1);
return 1; return 1;
} }
@ -4455,6 +4484,12 @@ static int hlua_http_req_set_query(lua_State *L)
size_t name_len; size_t name_len;
const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len)); const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
/* Check if a valid request is parsed */
if (unlikely(htxn->s->txn->req.msg_state < HTTP_MSG_BODY)) {
lua_pushboolean(L, 0);
return 1;
}
/* Check length. */ /* Check length. */
if (name_len > trash.size - 1) { if (name_len > trash.size - 1) {
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
@ -4478,6 +4513,12 @@ static int hlua_http_req_set_uri(lua_State *L)
size_t name_len; size_t name_len;
const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len)); const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
/* Check if a valid request is parsed */
if (unlikely(htxn->s->txn->req.msg_state < HTTP_MSG_BODY)) {
lua_pushboolean(L, 0);
return 1;
}
lua_pushboolean(L, http_replace_req_line(3, name, name_len, htxn->p, htxn->s) != -1); lua_pushboolean(L, http_replace_req_line(3, name, name_len, htxn->p, htxn->s) != -1);
return 1; return 1;
} }
@ -4488,6 +4529,10 @@ static int hlua_http_res_set_status(lua_State *L)
struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1)); struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
unsigned int code = MAY_LJMP(luaL_checkinteger(L, 2)); unsigned int code = MAY_LJMP(luaL_checkinteger(L, 2));
/* Check if a valid response is parsed */
if (unlikely(htxn->s->txn->rsp.msg_state < HTTP_MSG_BODY))
return 0;
http_set_status(code, htxn->s); http_set_status(code, htxn->s);
return 0; return 0;
} }