diff --git a/pkgs/development/libraries/libxml2/CVE-2025-6021.patch b/pkgs/development/libraries/libxml2/CVE-2025-6021.patch new file mode 100644 index 0000000000000..7d20a17c70381 --- /dev/null +++ b/pkgs/development/libraries/libxml2/CVE-2025-6021.patch @@ -0,0 +1,40 @@ +diff --git a/tree.c b/tree.c +index f097cf87..4d966ec9 100644 +--- a/tree.c ++++ b/tree.c +@@ -47,6 +47,10 @@ + #include "private/error.h" + #include "private/tree.h" + ++#ifndef SIZE_MAX ++ #define SIZE_MAX ((size_t) -1) ++#endif ++ + int __xmlRegisterCallbacks = 0; + + /************************************************************************ +@@ -167,10 +168,10 @@ xmlGetParameterEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) { + xmlChar * + xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix, + xmlChar *memory, int len) { +- int lenn, lenp; ++ size_t lenn, lenp; + xmlChar *ret; + +- if (ncname == NULL) return(NULL); ++ if ((ncname == NULL) || (len < 0)) return(NULL); + if (prefix == NULL) return((xmlChar *) ncname); + + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +@@ -181,8 +182,10 @@ xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix, + + lenn = strlen((char *) ncname); + lenp = strlen((char *) prefix); ++ if (lenn >= SIZE_MAX - lenp - 1) ++ return(NULL); + +- if ((memory == NULL) || (len < lenn + lenp + 2)) { ++ if ((memory == NULL) || ((size_t) len < lenn + lenp + 2)) { + ret = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); + if (ret == NULL) + return(NULL); diff --git a/pkgs/development/libraries/libxml2/CVE-2025-6170.patch b/pkgs/development/libraries/libxml2/CVE-2025-6170.patch new file mode 100644 index 0000000000000..b66f24e305e0d --- /dev/null +++ b/pkgs/development/libraries/libxml2/CVE-2025-6170.patch @@ -0,0 +1,112 @@ +diff --git a/result/scripts/long_command b/result/scripts/long_command +new file mode 100644 +index 000000000..e6f00708b +--- /dev/null ++++ b/result/scripts/long_command +@@ -0,0 +1,8 @@ ++/ > b > b > Object is a Node Set : ++Set contains 1 nodes: ++1 ELEMENT a:c ++b > Unknown command This_is_a_really_long_command_string_designed_to_test_the_limits_of_the_memory_that_stores_the_comm ++b > b > Unknown command ess_currents_of_time_and_existence ++b > ++Navigating_the_labyrinthine_corridors_of_human_cognition_one_often_encounters_the_perplexing_paradox_that_the_more_we_delve_into_the_intricate_dance_of_neural_pathways_and_synaptic_firings_the_further_we_seem_to_stray_from_a_truly_holistic_understanding_of_consciousness_a_phenomenon_that_remains_as_elusive_as_a_moonbeam_caught_in_a_spiderweb_yet_undeniably_shapes_every_fleeting_thought_every_prof ++b > +\ No newline at end of file +diff --git a/debugXML.c b/debugXML.c +index ed56b0f8..aeeea3c0 100644 +--- a/debugXML.c ++++ b/debugXML.c +@@ -2780,6 +2780,10 @@ xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer, + return (0); + } + ++#define MAX_PROMPT_SIZE 500 ++#define MAX_ARG_SIZE 400 ++#define MAX_COMMAND_SIZE 100 ++ + /** + * xmlShell: + * @doc: the initial document +@@ -2795,10 +2795,10 @@ void + xmlShell(xmlDocPtr doc, const char *filename, xmlShellReadlineFunc input, + FILE * output) + { +- char prompt[500] = "/ > "; ++ char prompt[MAX_PROMPT_SIZE] = "/ > "; + char *cmdline = NULL, *cur; +- char command[100]; +- char arg[400]; ++ char command[MAX_COMMAND_SIZE]; ++ char arg[MAX_ARG_SIZE]; + int i; + xmlShellCtxtPtr ctxt; + xmlXPathObjectPtr list; +@@ -2856,7 +2856,8 @@ xmlShell(xmlDocPtr doc, const char *filename, xmlShellReadlineFunc input, + cur++; + i = 0; + while ((*cur != ' ') && (*cur != '\t') && +- (*cur != '\n') && (*cur != '\r')) { ++ (*cur != '\n') && (*cur != '\r') && ++ (i < (MAX_COMMAND_SIZE - 1))) { + if (*cur == 0) + break; + command[i++] = *cur++; +@@ -2871,7 +2872,7 @@ xmlShell(xmlDocPtr doc, const char *filename, xmlShellReadlineFunc input, + while ((*cur == ' ') || (*cur == '\t')) + cur++; + i = 0; +- while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) { ++ while ((*cur != '\n') && (*cur != '\r') && (*cur != 0) && (i < (MAX_ARG_SIZE-1))) { + if (*cur == 0) + break; + arg[i++] = *cur++; +diff --git a/xmllint.c b/xmllint.c +index c6273477..3d90272c 100644 +--- a/xmllint.c ++++ b/xmllint.c +@@ -724,6 +724,9 @@ xmlHTMLValidityWarning(void *ctx, const char *msg, ...) + ************************************************************************/ + #ifdef LIBXML_DEBUG_ENABLED + #ifdef LIBXML_XPATH_ENABLED ++ ++#define MAX_PROMPT_SIZE 500 ++ + /** + * xmlShellReadline: + * @prompt: the prompt value +@@ -754,9 +754,9 @@ xmlShellReadline(char *prompt) { + if (prompt != NULL) + fprintf(stdout, "%s", prompt); + fflush(stdout); +- if (!fgets(line_read, 500, stdin)) ++ if (!fgets(line_read, MAX_PROMPT_SIZE, stdin)) + return(NULL); +- line_read[500] = 0; ++ line_read[MAX_PROMPT_SIZE] = 0; + len = strlen(line_read); + ret = (char *) malloc(len + 1); + if (ret != NULL) { +-- +diff --git a/test/scripts/long_command.script b/test/scripts/long_command.script +new file mode 100644 +index 000000000..00f6df09f +--- /dev/null ++++ b/test/scripts/long_command.script +@@ -0,0 +1,6 @@ ++cd a/b ++set ++xpath //*[namespace-uri()="foo"] ++This_is_a_really_long_command_string_designed_to_test_the_limits_of_the_memory_that_stores_the_command_please_dont_crash foo ++set Navigating_the_labyrinthine_corridors_of_human_cognition_one_often_encounters_the_perplexing_paradox_that_the_more_we_delve_into_the_intricate_dance_of_neural_pathways_and_synaptic_firings_the_further_we_seem_to_stray_from_a_truly_holistic_understanding_of_consciousness_a_phenomenon_that_remains_as_elusive_as_a_moonbeam_caught_in_a_spiderweb_yet_undeniably_shapes_every_fleeting_thought_every_profound_emotion_and_every_grand_aspiration_that_propels_our_species_ever_onward_through_the_relentless_currents_of_time_and_existence ++save - +diff --git a/test/scripts/long_command.xml b/test/scripts/long_command.xml +new file mode 100644 +index 000000000..1ba44016e +--- /dev/null ++++ b/test/scripts/long_command.xml +@@ -0,0 +1 @@ ++ +-- +GitLab + diff --git a/pkgs/development/libraries/libxml2/common.nix b/pkgs/development/libraries/libxml2/common.nix new file mode 100644 index 0000000000000..7ab55b3f10bbd --- /dev/null +++ b/pkgs/development/libraries/libxml2/common.nix @@ -0,0 +1,166 @@ +{ + stdenv, + darwin, + lib, + pkg-config, + autoreconfHook, + python3, + ncurses, + findXMLCatalogs, + libiconv, + # Python limits cross-compilation to an allowlist of host OSes. + # https://github.com/python/cpython/blob/dfad678d7024ab86d265d84ed45999e031a03691/configure.ac#L534-L562 + pythonSupport ? + enableShared + && ( + stdenv.hostPlatform == stdenv.buildPlatform + || stdenv.hostPlatform.isCygwin + || stdenv.hostPlatform.isLinux + || stdenv.hostPlatform.isWasi + ), + icuSupport ? false, + icu, + zlibSupport ? false, + zlib, + enableShared ? !stdenv.hostPlatform.isMinGW && !stdenv.hostPlatform.isStatic, + enableStatic ? !enableShared, + gnome, + testers, + enableHttp ? false, + + version, + extraPatches ? [ ], + src, + extraMeta ? { }, + freezeUpdateScript ? false, +}: + +let + # libxml2 is a dependency of xcbuild. Avoid an infinite recursion by using a bootstrap stdenv + # that does not propagate xcrun. + stdenv' = if stdenv.hostPlatform.isDarwin then darwin.bootstrapStdenv else stdenv; +in +stdenv'.mkDerivation (finalAttrs: { + inherit + version + src + ; + + pname = "libxml2"; + + outputs = + [ + "bin" + "dev" + "out" + "devdoc" + ] + ++ lib.optional pythonSupport "py" + ++ lib.optional (enableStatic && enableShared) "static"; + outputMan = "bin"; + + patches = [ + # Unmerged ABI-breaking patch required to fix the following security issues: + # - https://gitlab.gnome.org/GNOME/libxslt/-/issues/139 + # - https://gitlab.gnome.org/GNOME/libxslt/-/issues/140 + # See also https://gitlab.gnome.org/GNOME/libxml2/-/issues/906 + # Source: https://github.com/chromium/chromium/blob/4fb4ae8ce3daa399c3d8ca67f2dfb9deffcc7007/third_party/libxml/chromium/xml-attr-extra.patch + ./xml-attr-extra.patch + ] ++ extraPatches; + + strictDeps = true; + + nativeBuildInputs = [ + pkg-config + autoreconfHook + ]; + + buildInputs = + lib.optionals pythonSupport [ + ncurses + python3 + ] + ++ lib.optionals zlibSupport [ + zlib + ]; + + propagatedBuildInputs = + [ + findXMLCatalogs + ] + ++ lib.optionals (stdenv.hostPlatform.isDarwin || stdenv.hostPlatform.isMinGW) [ + libiconv + ] + ++ lib.optionals icuSupport [ + icu + ]; + + configureFlags = + [ + "--exec-prefix=${placeholder "dev"}" + (lib.enableFeature enableStatic "static") + (lib.enableFeature enableShared "shared") + (lib.withFeature icuSupport "icu") + (lib.withFeature pythonSupport "python") + (lib.optionalString pythonSupport "PYTHON=${python3.pythonOnBuildForHost.interpreter}") + ] + # avoid rebuilds, can be merged into list in version bumps + ++ lib.optional enableHttp "--with-http" + ++ lib.optional zlibSupport "--with-zlib"; + + installFlags = lib.optionals pythonSupport [ + "pythondir=\"${placeholder "py"}/${python3.sitePackages}\"" + "pyexecdir=\"${placeholder "py"}/${python3.sitePackages}\"" + ]; + + enableParallelBuilding = true; + + doCheck = (stdenv.hostPlatform == stdenv.buildPlatform) && stdenv.hostPlatform.libc != "musl"; + preCheck = lib.optional stdenv.hostPlatform.isDarwin '' + export DYLD_LIBRARY_PATH="$PWD/.libs:$DYLD_LIBRARY_PATH" + ''; + + preConfigure = lib.optionalString (lib.versionAtLeast stdenv.hostPlatform.darwinMinVersion "11") '' + MACOSX_DEPLOYMENT_TARGET=10.16 + ''; + + preInstall = lib.optionalString pythonSupport '' + substituteInPlace python/libxml2mod.la --replace-fail "$dev/${python3.sitePackages}" "$py/${python3.sitePackages}" + ''; + + postFixup = + '' + moveToOutput bin/xml2-config "$dev" + moveToOutput lib/xml2Conf.sh "$dev" + '' + + lib.optionalString (enableStatic && enableShared) '' + moveToOutput lib/libxml2.a "$static" + ''; + + passthru = { + inherit pythonSupport; + + updateScript = gnome.updateScript { + packageName = "libxml2"; + versionPolicy = "none"; + freeze = freezeUpdateScript; + }; + tests = { + pkg-config = testers.hasPkgConfigModules { + package = finalAttrs.finalPackage; + }; + cmake-config = testers.hasCmakeConfigModules { + moduleNames = [ "LibXml2" ]; + package = finalAttrs.finalPackage; + }; + }; + }; + + meta = { + homepage = "https://gitlab.gnome.org/GNOME/libxml2"; + description = "XML parsing library for C"; + license = lib.licenses.mit; + platforms = lib.platforms.all; + pkgConfigModules = [ "libxml-2.0" ]; + } // extraMeta; +}) diff --git a/pkgs/development/libraries/libxml2/default.nix b/pkgs/development/libraries/libxml2/default.nix index 1a411f3b2130d..52889102febc9 100644 --- a/pkgs/development/libraries/libxml2/default.nix +++ b/pkgs/development/libraries/libxml2/default.nix @@ -1,169 +1,62 @@ { - stdenv, lib, + callPackage, fetchFromGitLab, - pkg-config, - autoreconfHook, - libintl, - python, - gettext, - ncurses, - findXMLCatalogs, - libiconv, - # Python limits cross-compilation to an allowlist of host OSes. - # https://github.com/python/cpython/blob/dfad678d7024ab86d265d84ed45999e031a03691/configure.ac#L534-L562 - pythonSupport ? - enableShared - && ( - stdenv.hostPlatform == stdenv.buildPlatform - || stdenv.hostPlatform.isCygwin - || stdenv.hostPlatform.isLinux - || stdenv.hostPlatform.isWasi - ), - icuSupport ? false, - icu, - zlibSupport ? false, - zlib, - enableShared ? !stdenv.hostPlatform.isMinGW && !stdenv.hostPlatform.isStatic, - enableStatic ? !enableShared, - gnome, - testers, - enableHttp ? false, + fetchpatch2, }: -stdenv.mkDerivation (finalAttrs: { - pname = "libxml2"; - version = "2.14.5"; - - outputs = - [ - "bin" - "dev" - "out" - "devdoc" - ] - ++ lib.optional pythonSupport "py" - ++ lib.optional (enableStatic && enableShared) "static"; - outputMan = "bin"; - - src = fetchFromGitLab { - domain = "gitlab.gnome.org"; - owner = "GNOME"; - repo = "libxml2"; - tag = "v${finalAttrs.version}"; - hash = "sha256-vxKlw8Kz+fgUP6bhWG2+4346WJVzqG0QvPG/BT7RftQ="; - }; - - patches = [ - # Unmerged ABI-breaking patch required to fix the following security issues: - # - https://gitlab.gnome.org/GNOME/libxslt/-/issues/139 - # - https://gitlab.gnome.org/GNOME/libxslt/-/issues/140 - # See also https://gitlab.gnome.org/GNOME/libxml2/-/issues/906 - # Source: https://github.com/chromium/chromium/blob/4fb4ae8ce3daa399c3d8ca67f2dfb9deffcc7007/third_party/libxml/chromium/xml-attr-extra.patch - ./xml-attr-extra.patch - ]; - - strictDeps = true; - - nativeBuildInputs = [ - pkg-config - autoreconfHook - ]; - - buildInputs = - lib.optionals pythonSupport [ - python - ] - ++ lib.optionals (pythonSupport && python ? isPy2 && python.isPy2) [ - gettext - ] - ++ lib.optionals (pythonSupport && python ? isPy3 && python.isPy3) [ - ncurses - ] - ++ lib.optionals (stdenv.hostPlatform.isDarwin && pythonSupport && python ? isPy2 && python.isPy2) [ - libintl - ] - ++ lib.optionals zlibSupport [ - zlib - ]; - - propagatedBuildInputs = - [ - findXMLCatalogs - ] - ++ lib.optionals (stdenv.hostPlatform.isDarwin || stdenv.hostPlatform.isMinGW) [ - libiconv - ] - ++ lib.optionals icuSupport [ - icu - ]; - - configureFlags = - [ - "--exec-prefix=${placeholder "dev"}" - (lib.enableFeature enableStatic "static") - (lib.enableFeature enableShared "shared") - (lib.withFeature icuSupport "icu") - (lib.withFeature pythonSupport "python") - (lib.optionalString pythonSupport "PYTHON=${python.pythonOnBuildForHost.interpreter}") - ] - # avoid rebuilds, can be merged into list in version bumps - ++ lib.optional enableHttp "--with-http" - ++ lib.optional zlibSupport "--with-zlib"; - - installFlags = lib.optionals pythonSupport [ - "pythondir=\"${placeholder "py"}/${python.sitePackages}\"" - "pyexecdir=\"${placeholder "py"}/${python.sitePackages}\"" - ]; - - enableParallelBuilding = true; - - doCheck = (stdenv.hostPlatform == stdenv.buildPlatform) && stdenv.hostPlatform.libc != "musl"; - preCheck = lib.optional stdenv.hostPlatform.isDarwin '' - export DYLD_LIBRARY_PATH="$PWD/.libs:$DYLD_LIBRARY_PATH" - ''; - - preConfigure = lib.optionalString (lib.versionAtLeast stdenv.hostPlatform.darwinMinVersion "11") '' - MACOSX_DEPLOYMENT_TARGET=10.16 - ''; - - preInstall = lib.optionalString pythonSupport '' - substituteInPlace python/libxml2mod.la --replace-fail "$dev/${python.sitePackages}" "$py/${python.sitePackages}" - ''; - - postFixup = - '' - moveToOutput bin/xml2-config "$dev" - moveToOutput lib/xml2Conf.sh "$dev" - '' - + lib.optionalString (enableStatic && enableShared) '' - moveToOutput lib/libxml2.a "$static" - ''; - - passthru = { - inherit pythonSupport; - - updateScript = gnome.updateScript { - packageName = "libxml2"; - versionPolicy = "none"; +let + packages = { + libxml2_13 = callPackage ./common.nix { + version = "2.13.8"; + src = fetchFromGitLab { + domain = "gitlab.gnome.org"; + owner = "GNOME"; + repo = "libxml2"; + tag = "v${packages.libxml2_13.version}"; + hash = "sha256-acemyYs1yRSTSLH7YCGxnQzrEDm8YPTK4HtisC36LsY="; + }; + extraPatches = [ + # same as upstream patch but fixed conflict and added required import: + # https://gitlab.gnome.org/GNOME/libxml2/-/commit/acbbeef9f5dcdcc901c5f3fa14d583ef8cfd22f0.diff + ./CVE-2025-6021.patch + (fetchpatch2 { + name = "CVE-2025-49794-49796.patch"; + url = "https://gitlab.gnome.org/GNOME/libxml2/-/commit/f7ebc65f05bffded58d1e1b2138eb124c2e44f21.patch"; + hash = "sha256-k+IGq6pbv9EA7o+uDocEAUqIammEjLj27Z+2RF5EMrs="; + }) + (fetchpatch2 { + name = "CVE-2025-49795.patch"; + url = "https://gitlab.gnome.org/GNOME/libxml2/-/commit/c24909ba2601848825b49a60f988222da3019667.patch"; + hash = "sha256-r7PYKr5cDDNNMtM3ogNLsucPFTwP/uoC7McijyLl4kU="; + excludes = [ "runtest.c" ]; # tests were rewritten in C and are on schematron for 2.13.x, meaning this does not apply + }) + # same as upstream, fixed conflicts + # https://gitlab.gnome.org/GNOME/libxml2/-/commit/c340e419505cf4bf1d9ed7019a87cc00ec200434 + ./CVE-2025-6170.patch + ]; + freezeUpdateScript = true; + extraMeta = { + maintainers = with lib.maintainers; [ + gepbird + ]; + }; }; - tests = { - pkg-config = testers.hasPkgConfigModules { - package = finalAttrs.finalPackage; + libxml2 = callPackage ./common.nix { + version = "2.14.5"; + src = fetchFromGitLab { + domain = "gitlab.gnome.org"; + owner = "GNOME"; + repo = "libxml2"; + tag = "v${packages.libxml2.version}"; + hash = "sha256-vxKlw8Kz+fgUP6bhWG2+4346WJVzqG0QvPG/BT7RftQ="; }; - cmake-config = testers.hasCmakeConfigModules { - moduleNames = [ "LibXml2" ]; - package = finalAttrs.finalPackage; + extraMeta = { + maintainers = with lib.maintainers; [ + jtojnar + ]; }; }; }; - - meta = with lib; { - homepage = "https://gitlab.gnome.org/GNOME/libxml2"; - description = "XML parsing library for C"; - license = licenses.mit; - platforms = platforms.all; - maintainers = with maintainers; [ jtojnar ]; - pkgConfigModules = [ "libxml-2.0" ]; - }; -}) +in +packages diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index b33f85874c218..422c103ad83f1 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -8835,13 +8835,11 @@ with pkgs; libxcrypt-legacy = libxcrypt.override { enableHashes = "all"; }; libxkbcommon = libxkbcommon_8; - libxml2 = callPackage ../development/libraries/libxml2 { - python = python3; - stdenv = - # libxml2 is a dependency of xcbuild. Avoid an infinite recursion by using a bootstrap stdenv - # that does not propagate xcrun. - if stdenv.hostPlatform.isDarwin then darwin.bootstrapStdenv else stdenv; - }; + + inherit (callPackage ../development/libraries/libxml2 { }) + libxml2_13 + libxml2 + ; libxml2Python = let diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index d231cd21957da..9a82087429b62 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -8234,7 +8234,7 @@ self: super: with self; { (toPythonModule ( pkgs.libxml2.override { pythonSupport = true; - inherit python; + python3 = python; } )).py;