Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: [email protected] Control: affects -1 + src:aegisub User: [email protected] Usertags: pu
Hi, [ Reason ] Request to upload aegisub to Trixie p-u to address CVE-2026-92705. [ Impact ] - CVE-2026-92705: Aegisub: Arbitrary code execution when opening a crafted ASS subtitle file [ Tests ] Manually tested to be working: a warning dialog is opened for user confirmation when an ASS subtitle file references an automation script to be loaded automatically. [ Risks ] Patch contains changes to add input sanitization and open warning when loading automation scripts. Code changes are local and should not affect other functions. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] 1 patch combining all 3 upstream patches referenced in the CVE, plus adaptions required for older versions. There is also a trivial change to debian-branch in d/gbp.conf for tooling. Please allow me to upload aegisub/3.2.2+dfsg-7.3+deb13u1 to Trixie p-u. -- Regards, Xiyue Deng
diff -Nru aegisub-3.2.2+dfsg/debian/changelog aegisub-3.2.2+dfsg/debian/changelog --- aegisub-3.2.2+dfsg/debian/changelog 2025-03-28 06:58:39.000000000 -0700 +++ aegisub-3.2.2+dfsg/debian/changelog 2026-10-30 17:54:05.000000000 -0700 @@ -1,3 +1,11 @@ +aegisub (3.2.2+dfsg-7.3+deb13u1) trixie-security; urgency=medium + + * Non-maintainer upload + * Add patch for fixing CVE-2026-92705 (Closes: #1150511) + * Update debian-branch in d/gbp.conf + + -- Xiyue Deng <[email protected]> Fri, 30 Oct 2026 17:54:05 -0700 + aegisub (3.2.2+dfsg-7.3) unstable; urgency=medium * Non-maintainer upload. diff -Nru aegisub-3.2.2+dfsg/debian/gbp.conf aegisub-3.2.2+dfsg/debian/gbp.conf --- aegisub-3.2.2+dfsg/debian/gbp.conf 2025-03-28 06:58:39.000000000 -0700 +++ aegisub-3.2.2+dfsg/debian/gbp.conf 2026-10-30 17:54:05.000000000 -0700 @@ -1,2 +1,4 @@ [DEFAULT] +debian-branch = debian/trixie + pristine-tar = True diff -Nru aegisub-3.2.2+dfsg/debian/patches/CVE-2026-92705.patch aegisub-3.2.2+dfsg/debian/patches/CVE-2026-92705.patch --- aegisub-3.2.2+dfsg/debian/patches/CVE-2026-92705.patch 1969-12-31 16:00:00.000000000 -0800 +++ aegisub-3.2.2+dfsg/debian/patches/CVE-2026-92705.patch 2026-10-30 17:54:05.000000000 -0700 @@ -0,0 +1,214 @@ +Description: Fix for CVE-2026-92705 + Adapted patches from upstream for fixing CVE-2026-92705 +Author: Xiyue Deng <[email protected]> +Origin: upstream +Bug: https://github.com/TypesettingTools/Aegisub/security/advisories/GHSA-67hq-5vgg-6f23 +Bug-Debian: https://bugs.debian.org/1150511 +Last-Update: 2026-10-30 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/libaegisub/common/fs.cpp ++++ b/libaegisub/common/fs.cpp +@@ -97,7 +97,7 @@ + } + + bool HasExtension(path const& p, std::string const& ext) { +- auto filename = p.filename().string(); ++ std::string filename = p.filename().string().c_str(); // Be consistent with std::filesystem functions which use C strings internally + if (filename.size() < ext.size() + 1) return false; + if (filename[filename.size() - ext.size() - 1] != '.') return false; + return boost::iends_with(filename, ext); +--- a/src/ass_parser.cpp ++++ b/src/ass_parser.cpp +@@ -29,6 +29,7 @@ + #include <algorithm> + #include <boost/algorithm/string/case_conv.hpp> + #include <boost/algorithm/string/predicate.hpp> ++#include <boost/algorithm/string/replace.hpp> + #include <boost/algorithm/string/trim.hpp> + #include <boost/lexical_cast.hpp> + #include <boost/regex.hpp> +@@ -165,7 +166,9 @@ + target->Info.push_back(*new AssInfo(std::move(key), std::move(value))); + } + +-void AssParser::ParseMetadataLine(std::string const& data) { ++void AssParser::ParseMetadataLine(std::string const& rawdata) { ++ std::string data = SanitizeLine(rawdata); ++ + size_t pos = data.find(':'); + if (pos == data.npos) return; + +@@ -196,7 +199,9 @@ + attach = agi::make_unique<AssAttachment>(data, AssEntryGroup::GRAPHIC); + } + +-void AssParser::ParseExtradataLine(std::string const &data) { ++void AssParser::ParseExtradataLine(std::string const &rawdata) { ++ std::string data = SanitizeLine(rawdata); ++ + static const boost::regex matcher("Data:[[:space:]]*(\\d+),([^,]+),(.)(.*)"); + boost::match_results<std::string::const_iterator> mr; + +@@ -223,6 +228,12 @@ + } + } + ++std::string AssParser::SanitizeLine(std::string const& data) { ++ std::string result = data; ++ boost::replace_all(result, std::string("\0", 1), "\uFFFD"); // Unicode replacement character ++ return result; ++} ++ + void AssParser::AddLine(std::string const& data) { + // Special-case for attachments since a line could theoretically be both a + // valid attachment data line and a valid section header, and if an +--- a/src/ass_parser.h ++++ b/src/ass_parser.h +@@ -35,6 +35,8 @@ + void ParseGraphicsLine(std::string const& data); + void ParseExtradataLine(std::string const &data); + void UnknownLine(std::string const&) { } ++ ++ std::string SanitizeLine(std::string const& data); + public: + AssParser(AssFile *target, int version); + ~AssParser(); +--- a/src/auto4_base.cpp ++++ b/src/auto4_base.cpp +@@ -33,6 +33,7 @@ + #include "ass_style.h" + #include "compat.h" + #include "dialog_progress.h" ++#include "format.h" + #include "include/aegisub/context.h" + #include "options.h" + #include "string_codec.h" +@@ -44,13 +45,17 @@ + #include <libaegisub/path.h> + #include <libaegisub/make_unique.h> + ++#include <boost/algorithm/string/join.hpp> + #include <boost/algorithm/string/replace.hpp> + #include <boost/algorithm/string/trim.hpp> + #include <boost/tokenizer.hpp> + #include <future> ++#include <ranges> ++#include <iterator> + + #include <wx/dcmemory.h> + #include <wx/log.h> ++#include <wx/msgdlg.h> + #include <wx/sizer.h> + + #ifdef __WINDOWS__ +@@ -362,21 +367,23 @@ + + void LocalScriptManager::Reload() + { ++ bool was_empty = scripts.empty(); + scripts.clear(); + + auto const& local_scripts = context->ass->Properties.automation_scripts; +- if (local_scripts.empty()) { +- ScriptsChanged(); +- return; +- } ++ ++ // Tuples of (raw script path, base path, resolved path) ++ using PathTuple = std::tuple<std::string, agi::fs::path, agi::fs::path>; ++ std::vector<PathTuple> resolvedpaths; + + auto autobasefn(OPT_GET("Path/Automation/Base")->GetString()); + + boost::char_separator<char> sep("|"); + for (auto const& cur : boost::tokenizer<boost::char_separator<char>>(local_scripts, sep)) { +- auto trimmed = boost::trim_copy(cur); +- char first_char = trimmed[0]; +- trimmed.erase(0, 1); ++ auto const tok = boost::trim_copy(cur); ++ if (tok.size() == 0) continue; ++ char first_char = tok[0]; ++ std::string trimmed(tok.begin() + 1, tok.end()); + + agi::fs::path basepath; + if (first_char == '~') { +@@ -390,11 +397,54 @@ + continue; + } + auto sfname = basepath/trimmed; ++ ++ resolvedpaths.emplace_back(tok, basepath, sfname); ++ } ++ ++ if (resolvedpaths.empty()) { ++ if (!was_empty) ++ ScriptsChanged(); ++ return; ++ } ++ ++ std::vector<std::string> resolvedpaths_log; ++ std::transform(resolvedpaths.begin(), resolvedpaths.end(), ++ std::back_inserter(resolvedpaths_log), ++ [](PathTuple const &paths) { ++ return from_wx(fmt_tl( ++ " %s (%s)", to_wx(std::get<0>(paths)), ++ std::get<2>(paths).wstring())); ++ }); ++ wxMessageDialog dlg( ++ nullptr, ++ fmt_tl( ++ "The subtitle file you have opened contains local automation scripts. " ++ "Do you want to load the associated automation scripts?\n" ++ "\n" ++ "List of scripts:\n\n%s\n\n" ++ "You should only load associated automation scripts if you trust their authors! " ++ "They are not required to view or edit the subtitle file." ++ , boost::algorithm::join(resolvedpaths_log, "\n")) ++ , _("Load associated automation scripts?") ++ , wxICON_WARNING | wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTRE ++ ); ++ dlg.SetOKCancelLabels(_("Trust the authors && load scripts"), _("No")); ++ auto response = dlg.ShowModal(); ++ ++ if (response != wxID_OK) { ++ if (!was_empty) ++ ScriptsChanged(); ++ else ++ SaveLoadedList(); ++ return; ++ } ++ ++ for (auto const& [tok, basepath, sfname] : resolvedpaths) { + if (agi::fs::FileExists(sfname)) + scripts.emplace_back(Automation4::ScriptFactory::CreateFromFile(sfname, true)); + else { +- wxLogWarning("Automation Script referenced could not be found.\nFilename specified: %c%s\nSearched relative to: %s\nResolved filename: %s", +- first_char, to_wx(trimmed), basepath.wstring(), sfname.wstring()); ++ wxLogWarning(fmt_tl("Automation Script referenced could not be found.\nFilename specified: %s\nSearched relative to: %s\nResolved filename: %s", ++ to_wx(tok), basepath.wstring(), sfname.wstring())); + } + } + +--- a/src/format.h ++++ b/src/format.h +@@ -14,6 +14,8 @@ + // + // Aegisub Project http://www.aegisub.org/ + ++#pragma once ++ + #include <libaegisub/format.h> + + #include <wx/string.h> +--- a/libaegisub/include/libaegisub/format.h ++++ b/libaegisub/include/libaegisub/format.h +@@ -14,6 +14,8 @@ + // + // Aegisub Project http://www.aegisub.org/ + ++#pragma once ++ + #include <libaegisub/fs_fwd.h> + + #include <boost/interprocess/streams/vectorstream.hpp> diff -Nru aegisub-3.2.2+dfsg/debian/patches/series aegisub-3.2.2+dfsg/debian/patches/series --- aegisub-3.2.2+dfsg/debian/patches/series 2025-03-28 06:58:39.000000000 -0700 +++ aegisub-3.2.2+dfsg/debian/patches/series 2026-10-30 17:54:05.000000000 -0700 @@ -29,3 +29,4 @@ fix_boost183.patch aegisub-add-support-for-loong64.patch icu76.patch +CVE-2026-92705.patch
signature.asc
Description: PGP signature

