From 682f1d4cea6d8a8e8f249040725490917d3db9bd Mon Sep 17 00:00:00 2001 From: guofengjie Date: Mon, 10 Oct 2022 16:54:23 +0800 Subject: [PATCH 1/2] CVE-2022-41556 modified: lighttpd.spec modified: lighttpd.spec --- .lighttpd.spec.swp | Bin 0 -> 20480 bytes CVE-2022-41556.patch | 194 +++++++++++++++++++++++++++++++++++++++++++ lighttpd.spec | 7 +- 3 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 .lighttpd.spec.swp create mode 100644 CVE-2022-41556.patch diff --git a/.lighttpd.spec.swp b/.lighttpd.spec.swp new file mode 100644 index 0000000000000000000000000000000000000000..ed9bdf8793fedf980b0d0de507eee0dc2b9e379d GIT binary patch literal 20480 zcmeI3d5k1g9mk(?DwlvDL@*Deo!N1!dwOPPcN~^unLSwC*&SzgmKepcy6SazG1XPI zb?>Lfp|qB0*WzW2n5CR5Alc^*YEGu(bYB8GrNc( zBsIw=-Tm(Od++_;@%v3}VE?XhK2jcJ_ z9Z&`bMwCq>_!!R5aUB&{F^xvk_Z>a?QuZ97<>x3u3kehwcwHnA_;qFElHwAZ z-U~0_XPz z1l|A%s5)csLcL$23qS1t@%{h#(-?aknBZzK1}fkjaQIZleh;1lPk{Tu7r-Y#6YK+9 zz(wE`@aQRw-34w0HmHJEPiE{8Xn@PWdEjp+G4=?!9n6BQ;9PJV`0d*n`w{pWxD|W` z)WIM)4V(yGc^hM&1XG{~96ph;AA>uA55~ax;5={|c`Kift$dm!2&oR z{OUNyz7Li_88C1dk0CFE+rh^{6}%Jt9FHJB1K$DHf?;qxcm|D1Do2P1V90R(V~_vwcmZ zjHf&1n6Da^ht(>$=cx0RQr8*=Zwk{9ZpVV|LHU7ix3J>1FsWfRI;VFX4M*yfTeEj?*PUUNAmAW5K$b)yluQd6}@ByKB%C~KyGD4F3)F`(mh8isjM^Mnhv zqj+}RpI6;b!C@u3i#&`8l^o>h1@*dcArOocwzl4=vHcw5*e^9wKi?bpPT(tJcFTdD zBVE?drzdwSlVaXAe9B8rZmHHHR*ow+;Onel7(N?=mBksjBmRhS)`6DU+O z<^$%Gs?VvGMzcz&e&7nl6Fwv5+=LIDLjAK{)T0S5tU1HAtrm1S%_W~VRb=O~i>5u# zTLMj4#5}Nl2i@}_&6a~Ybv7k5l-$orj{P#&G*l#@w#n>uQ!E&eEHxYrAVKo^rlB=u z9W@~=ZeuTK8A~WFy*DscTE1-F@S8JcppIr#B!WU^xRRto8#PsHifqz2T+e1`=(Sch zF@g)Iz;i1#!>XwBv;EkdYpU$pQk)%KRsWoTAMW4!pV#7lDszfDWdLmyK-lFG=mfl%TT>0wARKr$Brdkk3 zmW(PV#O0~SPJiH0BL+)`j7EuLLcHnAaV`siNTR9%- zFjb~+Nh)k?J`0m%I^{H-vaX~PM(HwLN>Z5EL~UR7MU*bnA#xWUtyFY--jcdC$!Cd_ zJ8^Uv^<=LX67OOhQ=#$XiM8yjZn?32NBBRC+p$(xy~;ew0++=_o3Rt~{AG&bqbXY#8>YY!LK&Hi$H8Hf&b7HR0Oc zsv;w8oJ~(kJR3$^K{hNrm1A?Q8dL61&?sQ? zR##RKb3wQfr=lQ_Fcuqd!?bHSl+H9&R~MGhXKHkx;Z@qsWsMLw`QG!&oa$EQ=jW3d z&FKFBAnwBV;l51w|JZ*267Kmgf@i>;paFWpsetbOzXMN$2Y?NxK^Z9EZ18W~@t+0H zfNz7lz!F#lI=Bjyz(wE;K<@!hf-i%c!2-A#41>eC|NjGg7u*Uy3vK{opbQl7XWak4 z2_6JXU;^v~X8{HdqkoS8>gU&~uf<;>fkFa>1PTch5-224NZ?H(0fkRQmH>JG>f<|H zgI}due1zk|S;Z5huo_DS9vbZdn}Iqn47%1_$`vlJ7DGxEXD7bHSZLo@<=v9C zORa9CVh8!6YA+ZlGW;AG$S)87M5^#<2aoRZxih@L$lFgnU5UKvqLQoeGBza~j%IhM zM8O-EZ{c#((eO>}hKmI)kWY5uZCvwB?%|f_Cl{pnGRuYQ+HTY{s&r`JXe*Vy>yVbb z-J{HLm|phcrLr28*$C`9hT&R6@Gb4{ms^@|D2*Z!!WMFI26;J zqIY2PzyQ77g#Rkr{)YR4Zn*SV5uWH*DoKXnZW)$maOz*Fp!DR}k6htPhx4A@X9*6wN^6u0J2^p zR+5)n`DPzI@!*AX2G3}nb#@ry%ATE6y((o~Vn+^oTwSZs(CT%R<;JG6wTqUQ(W5Lm zyufyCbIPQ$PQf$=Mx)ol!@6Ut8eZ4Y*xW&lMk`%31wqcX#z6%)VA3>tMJADRpzJUB zX>q4AcNaLlk-%E=dN({SHf;2|{g#hr$&@CuQBF^zGW)2XQU;+R*Q{T~ayhx`3k!A-yg zbnkx^clcj}=fQK}C*T2aH@E}b0&WK6127M+1>3>0 z8~_HG20h>ca1wYLJ_b*L9{}<_cnsVJ?gTEl9Gn1tih=t)5TGCY6}|>9fXBhZ;12LP za2*%}TR;yu8T=jN{VX7#ghj9m$T<+6gGwdrtYpum<+)0uwKZ8vO&wVVxgzCKTQ7ZT z?H*D3c)gJ-UaRcBvWe%xoL*5NSvorOyh0XRGdC*PL)Tr~@eYR_D&DhjpdnqBy9-8J zbEjT(HRPr*=S1SYV2eij=sQT z109c7{iwdK8L3=UglSc7=ShuWZf$WUa^MJk6C#-&Va9mAP&si6k78fyi)ssHawHk! z9JGIhxhfqx+;w%b)G2T%aGFw&Q_8K=`>xzOImIWpZ{0S&ot4bc{=mofPJDRRo}H1h zhmsFxP2FJhzTRPvOU{v0tqz;FJR!gD(hBT}6)P}Je()e4WtfW};TKi80vClUzvf~x z!dvkai{{QuXcv?wf|UvUAp0JY0b*drX8rfY%<2|uN$xafvIP@e1t?slm zE=waV>`yMWNb#a6VA)v8xVb6gTyeRgV-3bv2mVobVUROL+n5>8BAP;_WobnqyTM9k z#dpoP+n; z6%A5F>lB*1f396@m5L=-BOa&QwtZ^fwq28#q^B9?ekfZOriIaP#%nnHW>z0D0L6K-xqWUkGPqxY5E2r}H}M!@Wx8!k_%af||o2YMp7q$lTW*+UaPTy}8Q z!VmJ)fsY}Ei7RlsDM>woT}FC}3}Mm0b}PRRroLlqPQnN99n^R^<=w$ba4-w7;0{R5 z?%?_cXESmsM8l*Dt0CZD7YD{VDt4kXqzfat4N#WY3leT>EknA=dGJ{ji4spa!Q{I! z!tWLyigC@0+*B8FWyh^H<$j#ndt&$7UhGM55n8pUg`PoMU9Fk+hOlfEA^C0))Y|+; yz>%))Ax)AFovTx=IXZXaiLK)~ZnGHV$WQx +Date: Sat, 22 Feb 2020 16:57:10 -0500 +Subject: [PATCH] [mod_proxy] stream request using HTTP/1.1 chunked (fixes + #3006) + +stream request body using HTTP/1.1 Transfer-Encoding: chunked + +(Note: if backend proxy target does not support HTTP/1.1, + then do not use server.stream-request-body = 1 or 2) + +If not streaming to backend, collect request body +(now supporting Transfer-Encoding: chunked from client + and then sending with Content-Length to backend) + +x-ref: + "Lighty returns HTTP 411 Length Required with proxy and streaming requests/reponses body" + https://redmine.lighttpd.net/issues/3006 +--- + src/gw_backend.c | 35 +++++++++++++++----------------- + src/http-header-glue.c | 8 -------- + src/mod_cgi.c | 4 +++- + src/mod_proxy.c | 46 +++++++++++++++++++++++++++++++++++++++++- + 4 files changed, 64 insertions(+), 29 deletions(-) + +diff --git a/src/gw_backend.c b/src/gw_backend.c +index d8b880868..aa98a8e48 100644 +--- a/src/gw_backend.c ++++ b/src/gw_backend.c +@@ -2052,43 +2052,40 @@ handler_t gw_handle_subrequest(request_st * const r, void *p_d) { + } + else { + handler_t rc = connection_handle_read_post_state(r); +- chunkqueue *req_cq = r->reqbody_queue; +- #if 0 /*(not reached since we send 411 Length Required below)*/ ++ ++ /* XXX: create configurable flag */ ++ /* CGI environment requires that Content-Length be set. ++ * Send 411 Length Required if Content-Length missing. ++ * (occurs here if client sends Transfer-Encoding: chunked ++ * and module is flagged to stream request body to backend) */ ++ if (-1 == r->reqbody_length && hctx->opts.backend != BACKEND_PROXY){ ++ return (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST) ++ ? connection_handle_read_post_error(r, 411) ++ : HANDLER_WAIT_FOR_EVENT; ++ } ++ + if (hctx->wb_reqlen < -1 && r->reqbody_length >= 0) { + /* (completed receiving Transfer-Encoding: chunked) */ +- hctx->wb_reqlen = -hctx->wb_reqlen + r->reqbody_length; ++ hctx->wb_reqlen = -hctx->wb_reqlen; + if (hctx->stdin_append) { + handler_t rca = hctx->stdin_append(hctx); + if (HANDLER_GO_ON != rca) return rca; + } + } +- #endif ++ + if ((0 != hctx->wb->bytes_in || -1 == hctx->wb_reqlen) +- && !chunkqueue_is_empty(req_cq)) { ++ && !chunkqueue_is_empty(r->reqbody_queue)) { + if (hctx->stdin_append) { + handler_t rca = hctx->stdin_append(hctx); + if (HANDLER_GO_ON != rca) return rca; + } + else +- chunkqueue_append_chunkqueue(hctx->wb, req_cq); ++ chunkqueue_append_chunkqueue(hctx->wb, r->reqbody_queue); + if (fdevent_fdnode_interest(hctx->fdn) & FDEVENT_OUT) { + return (rc == HANDLER_GO_ON) ? HANDLER_WAIT_FOR_EVENT : rc; + } + } + if (rc != HANDLER_GO_ON) return rc; +- +- +- /* XXX: create configurable flag */ +- /* CGI environment requires that Content-Length be set. +- * Send 411 Length Required if Content-Length missing. +- * (occurs here if client sends Transfer-Encoding: chunked +- * and module is flagged to stream request body to backend) */ +- /* proxy currently sends HTTP/1.0 request and ideally should send +- * Content-Length with request if request body is present, so +- * send 411 Length Required if Content-Length missing. */ +- if (-1 == r->reqbody_length) { +- return connection_handle_read_post_error(r, 411); +- } + } + } + +diff --git a/src/http-header-glue.c b/src/http-header-glue.c +index 72a328e71..cf77ae1a8 100644 +--- a/src/http-header-glue.c ++++ b/src/http-header-glue.c +@@ -1036,14 +1036,6 @@ static int http_response_process_headers(request_st * const r, http_response_opt + r->content_length = strtoul(value, NULL, 10); + break; + case HTTP_HEADER_TRANSFER_ENCODING: +- if (opts->backend == BACKEND_PROXY) { +- log_error(r->conf.errh, __FILE__, __LINE__, +- "proxy backend sent invalid response header " +- "(Transfer-Encoding) to HTTP/1.0 request"); +- r->http_status = 502; /* Bad Gateway */ +- r->handler_module = NULL; +- return -1; +- } + break; + default: + break; +diff --git a/src/mod_cgi.c b/src/mod_cgi.c +index 5e14df178..78e89ce8f 100644 +--- a/src/mod_cgi.c ++++ b/src/mod_cgi.c +@@ -982,7 +982,9 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) { + * (occurs here if client sends Transfer-Encoding: chunked + * and module is flagged to stream request body to backend) */ + if (-1 == r->reqbody_length) { +- return connection_handle_read_post_error(r, 411); ++ return (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST) ++ ? connection_handle_read_post_error(r, 411) ++ : HANDLER_WAIT_FOR_EVENT; + } + } + } +diff --git a/src/mod_proxy.c b/src/mod_proxy.c +index 31a4f930b..e0d2cf5e7 100644 +--- a/src/mod_proxy.c ++++ b/src/mod_proxy.c +@@ -813,6 +813,42 @@ static void proxy_set_Forwarded(connection * const con, request_st * const r, co + } + + ++static handler_t proxy_stdin_append(gw_handler_ctx *hctx) { ++ /*handler_ctx *hctx = (handler_ctx *)gwhctx;*/ ++ chunkqueue * const req_cq = hctx->r->reqbody_queue; ++ const off_t req_cqlen = req_cq->bytes_in - req_cq->bytes_out; ++ if (req_cqlen) { ++ /* XXX: future: use http_chunk_len_append() */ ++ buffer * const tb = hctx->r->tmp_buf; ++ buffer_clear(tb); ++ buffer_append_uint_hex_lc(tb, (uintmax_t)req_cqlen); ++ buffer_append_string_len(tb, CONST_STR_LEN("\r\n")); ++ ++ const off_t len = (off_t)buffer_string_length(tb) ++ + 2 /*(+2 end chunk "\r\n")*/ ++ + req_cqlen; ++ if (-1 != hctx->wb_reqlen) ++ hctx->wb_reqlen += (hctx->wb_reqlen >= 0) ? len : -len; ++ ++ (chunkqueue_is_empty(hctx->wb) || hctx->wb->first->type == MEM_CHUNK) ++ /* else FILE_CHUNK for temp file */ ++ ? chunkqueue_append_mem(hctx->wb, CONST_BUF_LEN(tb)) ++ : chunkqueue_append_mem_min(hctx->wb, CONST_BUF_LEN(tb)); ++ chunkqueue_steal(hctx->wb, req_cq, req_cqlen); ++ ++ chunkqueue_append_mem_min(hctx->wb, CONST_STR_LEN("\r\n")); ++ } ++ ++ if (hctx->wb->bytes_in == hctx->wb_reqlen) {/*hctx->r->reqbody_length >= 0*/ ++ /* terminate STDIN */ ++ chunkqueue_append_mem(hctx->wb, CONST_STR_LEN("0\r\n\r\n")); ++ hctx->wb_reqlen += (int)sizeof("0\r\n\r\n"); ++ } ++ ++ return HANDLER_GO_ON; ++} ++ ++ + static handler_t proxy_create_env(gw_handler_ctx *gwhctx) { + handler_ctx *hctx = (handler_ctx *)gwhctx; + request_st * const r = hctx->gw.r; +@@ -831,7 +867,13 @@ static handler_t proxy_create_env(gw_handler_ctx *gwhctx) { + buffer_append_string_buffer(b, &r->target); + if (remap_headers) + http_header_remap_uri(b, buffer_string_length(b) - buffer_string_length(&r->target), &hctx->conf.header, 1); +- if (!upgrade) ++ ++ int stream_chunked = 0; ++ if (-1 == r->reqbody_length && r->conf.stream_request_body) { ++ stream_chunked = 1; ++ hctx->gw.stdin_append = proxy_stdin_append; ++ } ++ if (!stream_chunked && !upgrade) + buffer_append_string_len(b, CONST_STR_LEN(" HTTP/1.0\r\n")); + else + buffer_append_string_len(b, CONST_STR_LEN(" HTTP/1.1\r\n")); +@@ -869,6 +911,8 @@ static handler_t proxy_create_env(gw_handler_ctx *gwhctx) { + buf, li_itostrn(buf, sizeof(buf), r->reqbody_length)); + } + } ++ else if (stream_chunked) ++ buffer_append_string_len(b, CONST_STR_LEN("Transfer-Encoding: chunked\r\n")); + + /* request header */ + for (size_t i = 0, used = r->rqst_headers.used; i < used; ++i) { diff --git a/lighttpd.spec b/lighttpd.spec index 51b6b04..5f6d720 100644 --- a/lighttpd.spec +++ b/lighttpd.spec @@ -20,7 +20,7 @@ Summary: Lightning fast webserver with light system requirements Name: lighttpd Version: 1.4.56 -Release: 2 +Release: 3 License: BSD-3-Clause and OML and GPLv3 and GPLv2 URL: https://github.com/lighttpd/lighttpd1.4 Source0: http://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-%{version}.tar.gz @@ -31,6 +31,7 @@ Source4: lighttpd.service Patch0: lighttpd-1.4.56-defaultconf.patch Patch1: CVE-2022-22707.patch Patch2: CVE-2022-37797.patch +Patch3: CVE-2022-41556.patch Requires: %{name}-filesystem %if %{with systemd} Requires(post): systemd @@ -110,6 +111,7 @@ for the directories. %patch0 -p0 -b .defaultconf %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build autoreconf -if @@ -256,6 +258,9 @@ fi %attr(0700, lighttpd, lighttpd) %dir %{webroot}/ %changelog +* Mon Oct 10 2022 guofengjie -1:1.4.56-3 +- Fix CVE-2022-41556 + * Fri Sep 30 2022 yaoxin - 1.4.56-2 - Fix excuting systemctl start lighttpd.service error -- Gitee From c25545d49a08da7332b61f3df2a9367ae907bfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E5=87=A4=E6=9D=B0?= Date: Mon, 10 Oct 2022 09:46:11 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20.lig?= =?UTF-8?q?httpd.spec.swp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .lighttpd.spec.swp | Bin 20480 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .lighttpd.spec.swp diff --git a/.lighttpd.spec.swp b/.lighttpd.spec.swp deleted file mode 100644 index ed9bdf8793fedf980b0d0de507eee0dc2b9e379d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 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 yz>%))Ax)AFovTx=IXZXaiLK)~ZnGHV$WQx