Bug#1092774: libfcgi: CVE-2025-23016 (5/5)
From
Bastian Germann@21:1/5 to
All on Mon Apr 14 20:50:01 2025
[continued from previous message]
+ return EOF;
+ been_here = 1;
+ }
+ else {
+ FCGX_Request *fcgx_req = request->requestPtr;
+ int acceptResult;
+
+ FCGI_Finish(request);
+#if defined(USE_ITHREADS)
+ MUTEX_LOCK(&accept_mutex);
+#endif
+ acceptResult = FCGX_Accept_r(fcgx_req);
+#if defined(USE_ITHREADS)
+ MUTEX_UNLOCK(&accept_mutex);
+#endif
+ if(acceptResult < 0) {
+ return acceptResult;
+ }
+
+ populate_env(fcgx_req->envp, request->hvEnv);
+
+ if (!request->svout) {
+ newSVrv(request->svout = newSV(0), "FCGI::Stream");
+ newSVrv(request->sverr = newSV(0), "FCGI::Stream");
+ newSVrv(request->svin = newSV(0), "FCGI::Stream");
+ }
+ sv_setiv(SvRV(request->svout), INT2PTR(IV, fcgx_req->out));
+ sv_setiv(SvRV(request->sverr), INT2PTR(IV, fcgx_req->err));
+ sv_setiv(SvRV(request->svin), INT2PTR(IV, fcgx_req->in));
+ FCGI_Bind(request);
+ request->accepted = TRUE;
+ }
+ return 0;
+}
+
+static void
+FCGI_Finish(FCGP_Request* request) {
+ int was_bound;
+ dTHX;
+
+ if(!request->accepted)
+ return;
+
+ if (was_bound = request->bound)
+ FCGI_UndoBinding(request);
+ if (was_bound)
+ FCGX_Finish_r(request->requestPtr);
+ else
+ FCGX_Free(request->requestPtr, 1);
+ request->accepted = FALSE;
+}
+
+static int
+FCGI_StartFilterData(FCGP_Request* request) {
+ return request->requestPtr->in ?
+ FCGX_StartFilterData(request->requestPtr->in) : -1;
+}
+
+static FCGP_Request *
+FCGI_Request(GV *in, GV *out, GV *err, HV *env, int socket, int flags) {
+ FCGX_Request* fcgx_req;
+ FCGP_Request* req;
+
+ Newz(551, fcgx_req, 1, FCGX_Request);
+ FCGX_InitRequest(fcgx_req, socket, flags);
+ Newz(551, req, 1, FCGP_Request);
+ req->requestPtr = fcgx_req;
+ SvREFCNT_inc(in);
+ req->gv[0] = in;
+ SvREFCNT_inc(out);
+ req->gv[1] = out;
+ SvREFCNT_inc(err);
+ req->gv[2] = err;
+ SvREFCNT_inc(env);
+ req->hvEnv = env;
+
+ return req;
+}
+
+static void
+FCGI_Release_Request(FCGP_Request *req) {
+ SvREFCNT_dec(req->gv[0]);
+ SvREFCNT_dec(req->gv[1]);
+ SvREFCNT_dec(req->gv[2]);
+ SvREFCNT_dec(req->hvEnv);
+ FCGI_Finish(req);
+ Safefree(req->requestPtr);
+ Safefree(req);
+}
+
+static void
+FCGI_Init() {
+#if defined(USE_ITHREADS)
+ dTHX;
+ MUTEX_INIT(&accept_mutex);
+#endif
+ FCGX_Init();
+}
+
+typedef FCGX_Stream* FCGI__Stream;
+typedef FCGP_Request* FCGI;
+typedef GV* GLOBREF;
+typedef HV* HASHREF;
+
+MODULE = FCGI PACKAGE = FCGI PREFIX = FCGI_
+
+BOOT:
+ FCGI_Init();
+
+SV *
+RequestX(in, out, err, env, socket, flags)
+ GLOBREF in;
+ GLOBREF out;
+ GLOBREF err;
+ HASHREF env;
+ int socket;
+ int flags;
+ PROTOTYPE: ***$$$
+ CODE:
+ RETVAL = sv_setref_pv(newSV(0), "FCGI",
+ FCGI_Request(in, out, err, env, socket, flags));
+ OUTPUT:
+ RETVAL
+
+int
+OpenSocket(path, backlog)
+ char* path;
+ int backlog;
+ PROTOTYPE: $$
+ CODE:
+ RETVAL = FCGX_OpenSocket(path, backlog);
+ OUTPUT:
+ RETVAL
+
+void
+CloseSocket(socket)
+ int socket;
+ PROTOTYPE: $
+ CODE:
+ close(socket);
+
+int
+FCGI_Accept(request)
+ FCGI request;
+ PROTOTYPE: $
+
+void
+FCGI_Finish(request)
+ FCGI request;
+ PROTOTYPE: $
+
+void
+FCGI_Flush(request)
+ FCGI request;
+ PROTOTYPE: $
+
+HV *
+GetEnvironment(request)
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
+ RETVAL = request->hvEnv;
+ OUTPUT:
+ RETVAL
+
+void
+GetHandles(request)
+ FCGI request;
+ PROTOTYPE: $
+ PREINIT:
+ int i;
+ PPCODE:
+ EXTEND(sp,3);
+ for (i = 0; i < 3; ++i)
+ PUSHs(sv_2mortal(newRV((SV *) request->gv[i])));
+
+int
+FCGI_IsFastCGI(request)
+ FCGI request;
+ PROTOTYPE: $
+
+void
+Detach(request)
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
+ if (request->accepted && request->bound) {
+ FCGI_UndoBinding(request);
+ FCGX_Detach(request->requestPtr);
+ }
+
+void
+Attach(request)
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
+ if (request->accepted && !request->bound) {
+ FCGI_Bind(request);
+ FCGX_Attach(request->requestPtr);
+ }
+
+void
+LastCall(request)
+ FCGI request;
+ PROTOTYPE: $
+ CODE:
+ FCGX_ShutdownPending();
+
+int
+FCGI_StartFilterData(request)
+ FCGI request;
+ PROTOTYPE: $
+
+void
+DESTROY(request)
+ FCGI request;
+ CODE:
+ FCGI_Release_Request(request);
+
+MODULE = FCGI PACKAGE = FCGI::Stream
+
+SV *
+PRINT(stream, ...)
+ FCGI::Stream stream;
+ PREINIT:
+ int n;
+ STRLEN len;
+ register char *str;
+ bool ok = TRUE;
+ CODE:
+ for (n = 1; ok && n < items; ++n) {
+#ifdef DO_UTF8
+ if (DO_UTF8(ST(n)) && !sv_utf8_downgrade(ST(n), 1) && ckWARN_d(WARN_UTF8))
+ Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG,
+ "FCGI::Stream::PRINT");
+#endif
+ str = (char *)SvPV(ST(n),len);
+ if (FCGX_PutStr(str, len, stream) < 0)
+ ok = FALSE;
+ }
+ if (ok && SvTRUEx(perl_get_sv("|", FALSE)) && FCGX_FFlush(stream) < 0)
+ ok = FALSE;
+ RETVAL = ok ? &PL_sv_yes : &PL_sv_undef;
+ OUTPUT:
+ RETVAL
+
+int
+WRITE(stream, bufsv, len, ...)
+ FCGI::Stream stream;
+ SV *bufsv;
+ int len;
+ PREINIT:
+ int offset;
+ char *buf;
+ STRLEN blen;
+ int n;
+ CODE:
+ offset = (items == 4) ? (int)SvIV(ST(3)) : 0;
+#ifdef DO_UTF8
+ if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1) && ckWARN_d(WARN_UTF8)) + Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG,
+ "FCGI::Stream::WRITE");
+#endif
+ buf = SvPV(bufsv, blen);
+ if (offset < 0) offset += blen;
+ if (len > blen - offset)
+ len = blen - offset;
+ if (offset < 0 || offset >= blen ||
+ (n = FCGX_PutStr(buf+offset, len, stream)) < 0)
+ ST(0) = &PL_sv_undef;
+ else {
+ ST(0) = sv_newmortal();
+ sv_setiv(ST(0), n);
+ }
+
+void
+READ(stream, bufsv, len, ...)
+ FCGI::Stream stream;
+ SV *bufsv;
+ int len;
+ PREINIT:
+ int offset = 0;
+ char *buf;
+ STRLEN blen;
+ CODE:
+ if (items < 3 || items > 4)
+ croak("Usage: FCGI::Stream::READ(STREAM, SCALAR, LENGTH [, OFFSET ])");
+ if (len < 0)
+ croak("Negative length");
+ if (!SvOK(bufsv))
+ sv_setpvn(bufsv, "", 0);
+#ifdef DO_UTF8
+ if (DO_UTF8(bufsv) && !sv_utf8_downgrade(bufsv, 1) && ckWARN_d(WARN_UTF8)) + Perl_warner(aTHX_ WARN_UTF8, WIDE_CHAR_DEPRECATION_MSG,
+ "FCGI::Stream::READ");
+#endif
+ buf = SvPV_force(bufsv, blen);
+ if (items == 4) {
+ offset = SvIV(ST(3));
+ if (offset < 0) {
+ if (-offset > (int)blen)
+ croak("Offset outside string");
+ offset += blen;
+ }
+ }
+ buf = SvGROW(bufsv, len + offset + 1);
+ if (offset > blen)
+ Zero(buf + blen, offset - blen, char);
+ len = FCGX_GetStr(buf + offset, len, stream);
+ SvCUR_set(bufsv, len + offset);
+ *SvEND(bufsv) = '\0';
+ (void)SvPOK_only(bufsv);
+ SvSETMAGIC(bufsv);
+ XSRETURN_IV(len);
+
+SV *
+GETC(stream)
+ FCGI::Stream stream;
+ PREINIT:
+ int retval;
+ CODE:
+ if ((retval = FCGX_GetChar(stream)) != -1) {
+ ST(0) = sv_newmortal();
+ sv_setpvf(ST(0), "%c", retval);
+ }
+ else
+ ST(0) = &PL_sv_undef;
+
+SV *
+EOF(stream, called=0)
+ FCGI::Stream stream;
+ IV called;
+ CODE:
+ RETVAL = boolSV(FCGX_HasSeenEOF(stream));
+ OUTPUT:
+ RETVAL
+
+void
+FILENO(stream)
+ FCGI::Stream stream;
+ CODE:
+ if (FCGX_HasSeenEOF(stream) != 0)
+ XSRETURN_UNDEF;
+ else
+ XSRETURN_IV(-1);
+
+bool
+CLOSE(stream)
+ FCGI::Stream stream;
+ CODE:
+ RETVAL = FCGX_FClose(stream) != -1;
+ OUTPUT:
+ RETVAL
diff -Nru libfcgi-2.4.2/perl/.gitignore libfcgi-2.4.5/perl/.gitignore
--- libfcgi-2.4.2/perl/.gitignore 2019-02-19 12:19:19.000000000 +0100
+++ libfcgi-2.4.5/perl/.gitignore 2025-04-14 19:35:59.000000000 +0200
@@ -8,3 +8,7 @@
pm_to_blib
fcgi_config.*
fcgi_config_x86.h
+Makefile
+config.log
+config.status
+MYMETA.*
diff -Nru libfcgi-2.4.2/perl/Makefile.PL libfcgi-2.4.5/perl/Makefile.PL
--- libfcgi-2.4.2/perl/Makefile.PL 2019-02-19 12:19:19.000000000 +0100
+++ libfcgi-2.4.5/perl/Makefile.PL 2025-04-14 19:35:59.000000000 +0200
@@ -1,64 +1,60 @@
# $Id: Makefile.PL,v 1.33 2002/12/15 19:40:19 skimo Exp $
+use 5.006;
use ExtUtils::MakeMaker;
use IO::File;
use Config;
use Cwd 'cwd';
use Getopt::Long;
+use File::Copy qw(copy);
@h1 = qw(fastcgi.h fcgiapp.h fcgimisc.h fcgios.h);
@h = (@h1, 'fcgi_config.h');
@o = qw(FCGI.o);
-@dist1 = qw(LICENSE.TERMS);
+@dist1 = qw(LICENSE);
@dist2 = qw(fcgiapp.c os_unix.c os_win32.c);
@dist3 = (@h1, qw(fcgi_config_x86.h));
-GetOptions ("pure-perl!" => \$pure,
- "use-installed:s" => \$useinstalled);
-