CVE-2023-52266 (published 2023-12-31T00:15Z)

ehttp 1.0.6 before 17405b9 has an epoll_socket.cpp read_func use-after-free. An attacker can make many connections over a short time to trigger this.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/hongliuliao/ehttp
commit_details: repo_url: https://github.com/hongliuliao/ehttp
author: harleyliao
author_date: 2023-10-08 06:54:01+00:00
msg: fix log overflow & epoll_context use after free bug
repository: repo_url: https://github.com/hongliuliao/ehttp
repo_name: hongliuliao/ehttp
description: simple http server base on epoll
repo_language: C++
owner: hongliuliao
file_changes: filename: Makefile
change_type: ModificationType.MODIFY
diff: @@ -5,8 +5,8 @@ CXXFLAGS += -g -Wall
 LDFLAGS += -pthread
 
 ifdef ACOV
-	CXXFLAGS += -fprofile-arcs -ftest-coverage
-	LDFLAGS += -lgcov --coverage
+	CXXFLAGS += -fprofile-arcs -ftest-coverage -fsanitize=address
+	LDFLAGS += -lgcov --coverage -fsanitize=address
 endif
 
 MULTIPART_PARSER_INC_PATH=-I deps/multipart-parser-c/

programming_language: Shell
filename: epoll_socket.cpp
change_type: ModificationType.MODIFY
diff: @@ -228,11 +228,6 @@ int EpollSocket::handle_accept_event(int &epollfd, epoll_event &event, EpollSock
 void read_func(void *data) {
     TaskData *td = (TaskData *) data;
     td->es->handle_readable_event(td->event);
-
-    EpollContext *hc = (EpollContext *) td->event.data.ptr;
-    if (hc != NULL) {
-        hc->_ctx_status = CONTEXT_READ_OVER;
-    }
     delete td;
 }
 
@@ -248,6 +243,9 @@ int EpollSocket::handle_readable_event(epoll_event &event) {
     if (ret == READ_CLOSE) {
         return close_and_release(event);
     }
+    if (epoll_context != NULL) {
+        epoll_context->_ctx_status = CONTEXT_READ_OVER;
+    }
 
     if (ret == READ_CONTINUE) {
         event.events = EPOLLIN | EPOLLONESHOT;

programming_language: C++
filename: sim_parser.cpp
change_type: ModificationType.MODIFY
diff: @@ -577,7 +577,7 @@ int Request::parse_request(const char *read_buffer, int read_size) {
         LOG_INFO("TOO BIG REQUEST WE WILL REFUSE IT! MAX_REQ_SIZE:%d", MAX_REQ_SIZE);
         return -1;
     }
-    LOG_DEBUG("read from client: size:%d, content:%s", read_size, read_buffer);
+    LOG_DEBUG("read from client: size:%d, content:%.4096s", read_size, read_buffer);
     ssize_t nparsed = http_parser_execute(&_parser, &_settings, read_buffer, read_size);
     if (nparsed != read_size) {
         std::string err_msg = "unkonw";

programming_language: C++
filename: poc.py
change_type: ModificationType.ADD
diff: @@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+
+import socket
+
+sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+sock.connect(("localhost", 8080))
+sock.send(b"GET"*5000+b" /hello"*5000+b" HTTP/1.1\r\nHost:localhost:8080\r\n\r\n")
+response = sock.recv(4096)
+sock.close()

programming_language: Lua