import Oracle_OSS xmlrpc-c-1.51.0-17.el9_8

This commit is contained in:
AlmaLinux RelEng Bot 2026-09-02 01:43:03 -04:00
parent 204a1aca57
commit 3c6afbe199
2 changed files with 292 additions and 2 deletions

View File

@ -0,0 +1,285 @@
From d96aa99815b26058353964fd2c72145a9e748c51 Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Fri, 14 Aug 2026 08:42:22 +0200
Subject: [PATCH] Fix HTML injection in Abyss error responses and directory
listings
Backport of upstream SVN r3342. User-supplied URIs and filenames were
inserted unescaped into HTML documents generated by the Abyss server
(error pages and directory listings), allowing reflected XSS via
crafted request URIs or filenames containing HTML control characters.
Add html_escapedForHtml() to replace &, <, >, ", ' with their HTML
entity equivalents before embedding user-derived strings in HTML output.
Resolves: CVE-2026-15928
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
lib/abyss/src/Makefile | 1 +
lib/abyss/src/handler.c | 42 +++++++++++++++++--
lib/abyss/src/html.c | 87 +++++++++++++++++++++++++++++++++++++++
lib/abyss/src/html.h | 7 ++++
lib/abyss/src/meson.build | 1 +
lib/abyss/src/response.c | 15 ++++---
6 files changed, 144 insertions(+), 9 deletions(-)
create mode 100644 lib/abyss/src/html.c
create mode 100644 lib/abyss/src/html.h
diff --git a/lib/abyss/src/Makefile b/lib/abyss/src/Makefile
index 86f2552..133bf61 100644
--- a/lib/abyss/src/Makefile
+++ b/lib/abyss/src/Makefile
@@ -45,6 +45,7 @@ TARGET_MODS = \
date \
file \
handler \
+ html \
http \
init \
response \
diff --git a/lib/abyss/src/handler.c b/lib/abyss/src/handler.c
index 80a2914..98431eb 100644
--- a/lib/abyss/src/handler.c
+++ b/lib/abyss/src/handler.c
@@ -36,6 +36,7 @@
#include "file.h"
#include "conn.h"
#include "http.h"
+#include "html.h"
#include "date.h"
#include "abyss_info.h"
@@ -291,11 +292,15 @@ sendDirectoryDocumentHeading(TSession * const sessionP,
"------------------------------------"
"--------------------------------------------\r\n");
} else {
+ const char * const escapedUri = html_escapedForHtml(uri);
+
sprintf(z, "<HTML><HEAD><TITLE>Index of %s</TITLE></HEAD><BODY>"
"<H1>Index of %s</H1><PRE>",
- uri, uri);
+ escapedUri, escapedUri);
strcat(z, "Name Size "
"Date-Time Type<HR WIDTH=100%>\r\n");
+
+ xmlrpc_strfree(escapedUri);
}
HTTPWriteBodyChunk(sessionP, z, strlen(z));
@@ -303,6 +308,37 @@ sendDirectoryDocumentHeading(TSession * const sessionP,
+static void
+formatHtmlForDirEntry(char * const buffer,
+ const char * const name,
+ int const attrib,
+ const char * const z1,
+ const char * const z2,
+ const char * const z3,
+ const char * const z4,
+ const char * const p) {
+
+ const char * const escapedName = html_escapedForHtml(name);
+ const char * const escapedZ1 = html_escapedForHtml(z1);
+ const char * const escapedZ2 = html_escapedForHtml(z2);
+ const char * const escapedZ3 = html_escapedForHtml(z3);
+ const char * const escapedZ4 = html_escapedForHtml(z4);
+ const char * const escapedP = html_escapedForHtml(p);
+
+ sprintf(buffer, "<A HREF=\"%s%s\">%s</A>%s %s %s %s\r\n",
+ escapedName, attrib & A_SUBDIR ? "/" : "",
+ escapedZ1, escapedP, escapedZ3, escapedZ2, escapedZ4);
+
+ xmlrpc_strfree(escapedP);
+ xmlrpc_strfree(escapedZ1);
+ xmlrpc_strfree(escapedZ2);
+ xmlrpc_strfree(escapedZ3);
+ xmlrpc_strfree(escapedZ4);
+ xmlrpc_strfree(escapedName);
+}
+
+
+
static void
sendDirectoryDocument(TList * const listP,
bool const ascending,
@@ -405,9 +441,7 @@ sendDirectoryDocument(TList * const listP,
if (text)
sprintf(z, "%s%s %s %s %s\r\n", z1, p, z3, z2, z4);
else
- sprintf(z, "<A HREF=\"%s%s\">%s</A>%s %s %s %s\r\n",
- fi->name, fi->attrib & A_SUBDIR ? "/" : "",
- z1, p, z3, z2, z4);
+ formatHtmlForDirEntry(z, fi->name, fi->attrib, z1, z2, z3, z4, p);
HTTPWriteBodyChunk(sessionP, z, strlen(z));
}
diff --git a/lib/abyss/src/html.c b/lib/abyss/src/html.c
new file mode 100644
index 0000000..eeb8b60
--- /dev/null
+++ b/lib/abyss/src/html.c
@@ -0,0 +1,87 @@
+/*=============================================================================
+ html
+===============================================================================
+ This module contains utilities for processing HTML.
+=============================================================================*/
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <xmlrpc-c/string_int.h>
+
+#include "html.h"
+
+
+
+static void
+insertCharEntity(char * const buffer,
+ unsigned int * const cursorP,
+ const char * const name) {
+
+ size_t i;
+
+ buffer[(*cursorP)++] = '&';
+
+ for (i = 0; i < strlen(name); ++i)
+ buffer[(*cursorP)++] = name[i];
+
+ buffer[(*cursorP)++] = ';';
+}
+
+
+
+const char *
+html_escapedForHtml(const char * const plainText) {
+/*----------------------------------------------------------------------------
+ The text 'plainText' with HTML control characters replaced with
+ HTML character entities so that the result can be used inside an HTML
+ document without any chance of interfering with HTML controls.
+
+ In particular, we substitute one of the following for each associated
+ character:
+
+ &amp;
+ &lt;
+ &gt;
+ &quot;
+ &apos;
+
+ We return newly malloced storage or a constant if we can't get allocate
+ enough, like 'xmlrpc_strdupsol', which must be freed with 'xmlrpc_strfree'.
+-----------------------------------------------------------------------------*/
+
+ size_t const maxPossibleReturnSz = strlen(plainText) * 6 + 1;
+
+ const char * retval;
+ char * buffer; /* malloc'ed */
+
+ buffer = malloc(maxPossibleReturnSz);
+
+ if (!buffer)
+ retval = xmlrpc_strnomemval();
+ else {
+ unsigned int inCursor, outCursor;
+
+ for (inCursor = 0, outCursor = 0;
+ inCursor < strlen(plainText);
+ ++inCursor) {
+
+ switch (plainText[inCursor]) {
+ case '&': insertCharEntity(buffer, &outCursor, "amp"); break;
+ case '<': insertCharEntity(buffer, &outCursor, "lt"); break;
+ case '>': insertCharEntity(buffer, &outCursor, "gt"); break;
+ case '"': insertCharEntity(buffer, &outCursor, "quot"); break;
+ case '\'': insertCharEntity(buffer, &outCursor, "apos"); break;
+ default:
+ buffer[outCursor++] = plainText[inCursor];
+ }
+ }
+
+ buffer[outCursor++] = '\0'; /* string-terminating NUL */
+
+ assert(outCursor <= maxPossibleReturnSz);
+
+ retval = buffer;
+ }
+ return retval;
+}
diff --git a/lib/abyss/src/html.h b/lib/abyss/src/html.h
new file mode 100644
index 0000000..97235f6
--- /dev/null
+++ b/lib/abyss/src/html.h
@@ -0,0 +1,7 @@
+#ifndef HTML_H_INCLUDED
+#define HTML_H_INCLUDED
+
+const char *
+html_escapedForHtml(const char * const plainText);
+
+#endif
diff --git a/lib/abyss/src/meson.build b/lib/abyss/src/meson.build
index daa91fc..73c94d9 100644
--- a/lib/abyss/src/meson.build
+++ b/lib/abyss/src/meson.build
@@ -30,6 +30,7 @@ libxmlrpc_abyss = library(
'date.c',
'file.c',
'handler.c',
+ 'html.c',
'http.c',
'init.c',
'response.c',
diff --git a/lib/abyss/src/response.c b/lib/abyss/src/response.c
index cc0980a..7024d32 100644
--- a/lib/abyss/src/response.c
+++ b/lib/abyss/src/response.c
@@ -34,6 +34,7 @@
#include "data.h"
#include "abyss_info.h"
#include "http.h"
+#include "html.h"
@@ -41,24 +42,28 @@ void
ResponseError2(TSession * const sessionP,
const char * const explanation) {
+ const char * const escapedExplanation = html_escapedForHtml(explanation);
+
const char * errorDocument;
ResponseAddField(sessionP, "Content-type", "text/html");
ResponseWriteStart(sessionP);
-
+
xmlrpc_asprintf(&errorDocument,
"<HTML><HEAD><TITLE>Error %d</TITLE></HEAD>"
"<BODY>"
"<H1>Error %d</H1>"
- "<P>%s</P>" SERVER_HTML_INFO
+ "<P>%s</P>" SERVER_HTML_INFO
"</BODY>"
"</HTML>",
- sessionP->status, sessionP->status, explanation);
-
- ConnWrite(sessionP->connP, errorDocument, strlen(errorDocument));
+ sessionP->status, sessionP->status, escapedExplanation);
+
+ ConnWrite(sessionP->connP, errorDocument, strlen(errorDocument));
xmlrpc_strfree(errorDocument);
+
+ xmlrpc_strfree(escapedExplanation);
}
--
2.55.0

View File

@ -6,7 +6,7 @@
Name: xmlrpc-c
Version: 1.51.0
Release: 16%{?dist}
Release: 17%{?dist}
Summary: Lightweight RPC library based on XML and HTTP
# See doc/COPYING for details.
# The Python 1.5.2 license used by a few files is just BSD.
@ -35,6 +35,8 @@ Patch201: 0001-Remove-trace-statements-accidentally-committed-with-.patch
Patch1001: 0001-add-meson-buildsystem-definitions.patch
Patch1002: 0002-chmod-x-xml-rpc-api2txt.patch
Patch1010: 1010-Fix-HTML-injection-in-Abyss-error-responses-and-dire.patch
BuildRequires: git-core
BuildRequires: meson >= 0.36.0
BuildRequires: gcc
@ -197,9 +199,12 @@ rm -Rf lib/expat
%{_bindir}/xmlrpc_dumpserver
%changelog
* Fri Aug 14 2026 Michal Srb <michal@redhat.com> - 1.51.0-17
- Fix HTML injection in Abyss error responses and directory listings
- Resolves: CVE-2026-15928
* Thu Mar 17 2022 Michal Srb <michal@redhat.com> - 1.51.0-16
- Drop bundled expat and build against libxml2
- Resolves: CVE-2022-25235
- Resolves: CVE-2022-25236
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1.51.0-15