Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package dcmtk for openSUSE:Factory checked 
in at 2026-04-08 17:15:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dcmtk (Old)
 and      /work/SRC/openSUSE:Factory/.dcmtk.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dcmtk"

Wed Apr  8 17:15:39 2026 rev:37 rq:1345068 version:3.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/dcmtk/dcmtk.changes      2026-01-05 
14:54:53.214589841 +0100
+++ /work/SRC/openSUSE:Factory/.dcmtk.new.21863/dcmtk.changes   2026-04-08 
17:16:03.080712578 +0200
@@ -1,0 +2,6 @@
+Tue Apr  7 19:52:17 UTC 2026 - Christophe Marin <[email protected]>
+
+- Add upstream change (CVE-2026-5663, boo#1261594)
+  * 0001-Sanitize-all-strings-passed-to-the-exec-options.patch
+
+-------------------------------------------------------------------

New:
----
  0001-Sanitize-all-strings-passed-to-the-exec-options.patch

----------(New B)----------
  New:- Add upstream change (CVE-2026-5663, boo#1261594)
  * 0001-Sanitize-all-strings-passed-to-the-exec-options.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dcmtk.spec ++++++
--- /var/tmp/diff_new_pack.RuK3Ds/_old  2026-04-08 17:16:03.816742839 +0200
+++ /var/tmp/diff_new_pack.RuK3Ds/_new  2026-04-08 17:16:03.816742839 +0200
@@ -28,6 +28,8 @@
 Patch0:         dcmtk-fix-DCMTKTargets.cmake.patch
 # PATCH-FIX-UPSTREAM
 Patch1:         0001-dcmimage-Link-privately-to-libtiff-and-libpng.patch
+# PATCH-FIX-UPSTREAM -- CVE-2026-5663
+Patch2:         0001-Sanitize-all-strings-passed-to-the-exec-options.patch
 BuildRequires:  cmake
 BuildRequires:  doxygen
 BuildRequires:  fdupes

++++++ 0001-Sanitize-all-strings-passed-to-the-exec-options.patch ++++++
>From 743b7d56f674bb1d4c3f9a9d53c63b0a39a08d22 Mon Sep 17 00:00:00 2001
From: Marco Eichelberg <[email protected]>
Date: Sat, 21 Mar 2026 18:35:14 +0100
Subject: [PATCH] Sanitize all strings passed to the exec options.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Sanitize the text fields from incoming DICOM associations and DICOM objects
(such as Study Instance UID, SOP Instance UID, Patient's Name) and the
calling SCU's network presentation address by removing special characters
that may be interpreted as shell escape characters when one of the
execution options (e.g. --exec-on-reception) is in use.

Thanks to Machine Spirits UG (haftungsbeschränkt) for the bug report,
detailed analysis and proof of concept.

This closes DCMTK issue #1194.
---
 dcmnet/apps/storescp.cc | 77 +++++++++++++++++++++++++++++++++--------
 ofstd/libsrc/ofstd.cc   | 26 ++++++++------
 2 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/dcmnet/apps/storescp.cc b/dcmnet/apps/storescp.cc
index 7a69a16..183c92f 100644
--- a/dcmnet/apps/storescp.cc
+++ b/dcmnet/apps/storescp.cc
@@ -1,6 +1,6 @@
 /*
  *
- *  Copyright (C) 1994-2025, OFFIS e.V.
+ *  Copyright (C) 1994-2026, OFFIS e.V.
  *  All rights reserved.  See COPYRIGHT file for details.
  *
  *  This software and supporting documentation were developed by
@@ -1601,7 +1601,9 @@ static OFCondition acceptAssociation(T_ASC_Network *net, 
DcmAssociationConfigura
     calledAETitle.clear();
   }
   // store calling presentation address (i.e. remote hostname)
-  callingPresentationAddress = 
OFSTRING_GUARD(assoc->params->DULparams.callingPresentationAddress);
+  callingPresentationAddress = "\"";
+  callingPresentationAddress += 
OFSTRING_GUARD(assoc->params->DULparams.callingPresentationAddress);
+  callingPresentationAddress += "\"";
 
   /* now do the real work, i.e. receive DIMSE commands over the network 
connection */
   /* which was established and handle these commands correspondingly. In case 
of */
@@ -1965,6 +1967,7 @@ storeSCPCallback(
             dateTime.getTime().getHour(), dateTime.getTime().getMinute(), 
dateTime.getTime().getIntSecond(), dateTime.getTime().getMilliSecond());
 
           OFString subdirectoryName;
+          OFString s;
           switch (opt_sortStudyMode)
           {
             case ESM_Timestamp:
@@ -1979,15 +1982,27 @@ storeSCPCallback(
               subdirectoryName = opt_sortStudyDirPrefix;
               if (!subdirectoryName.empty())
                 subdirectoryName += '_';
-              subdirectoryName += currentStudyInstanceUID;
-              OFStandard::sanitizeFilename(subdirectoryName);
+              s = currentStudyInstanceUID;
+              OFStandard::sanitizeFilename(s);
+              if (s != currentStudyInstanceUID)
+              {
+                OFLOG_WARN(storescpLogger, "Sanitized unusual characters in 
Study Instance UID, converted from \"" << currentStudyInstanceUID << "\" to \"" 
<< s << "\".");
+              }
+              subdirectoryName += s;
               break;
             case ESM_PatientName:
               // pattern: "[Patient's Name]_[YYYYMMDD]_[HHMMSSMMM]"
               subdirectoryName = currentPatientName;
+              OFStandard::sanitizeFilename(subdirectoryName);
+              if (subdirectoryName != currentPatientName)
+              {
+                // It is quite normal that we need to sanitize characters in 
PatientName.
+                // Therefore, this is only a debug message and not a warning, 
unlike the other
+                // messages about sanitized fields, which are normally not 
expected.
+                OFLOG_DEBUG(storescpLogger, "Sanitized characters in Patient 
Name, converted from \"" << currentPatientName << "\" to \"" << 
subdirectoryName << "\".");
+              }
               subdirectoryName += '_';
               subdirectoryName += timestamp;
-              OFStandard::sanitizeFilename(subdirectoryName);
               break;
             case ESM_None:
               break;
@@ -2196,8 +2211,13 @@ static OFCondition storeSCP(
     else
     {
       // Use the SOP instance UID as found in the C-STORE request message as 
part of the filename
-      OFString uid(OFSTRING_GUARD(req->AffectedSOPInstanceUID));
+      OFString s(OFSTRING_GUARD(req->AffectedSOPInstanceUID));
+      OFString uid = s;
       OFStandard::sanitizeFilename(uid);
+      if (uid != s)
+      {
+        OFLOG_WARN(storescpLogger, "Sanitized unusual characters in SOP 
Instance UID, converted from \"" << s << "\" to \"" << uid << "\".");
+      }
       OFStandard::snprintf(imageFileName, sizeof(imageFileName), 
"%s%c%s.%s%s", opt_outputDirectory.c_str(), PATH_SEPARATOR, 
dcmSOPClassUIDToModality(req->AffectedSOPClassUID, "UNKNOWN"),
         uid.c_str(), opt_fileNameExtension.c_str());
     }
@@ -2367,16 +2387,19 @@ static void executeOnReception()
   if( !opt_ignore )
   {
     // perform substitution for placeholder #p (depending on presence of any 
--sort-xxx option)
+    // Note: We do not enclose this in quotes because it may be used as part 
of a path expression.
     OFString dir = (opt_sortStudyMode == ESM_None) ? opt_outputDirectory : 
subdirectoryPathAndName;
     cmd = replaceChars( cmd, OFString(PATH_PLACEHOLDER), dir );
 
     // perform substitution for placeholder #f; note that 
outputFileNameArray.back()
     // always contains the name of the file (without path) which was written 
last.
+    // Note: We do not enclose this in quotes because it may be used as part 
of a path expression.
     OFString outputFileName = outputFileNameArray.back();
     cmd = replaceChars( cmd, OFString(FILENAME_PLACEHOLDER), outputFileName );
   }
 
-  // perform substitution for placeholder #a
+  // perform substitution for placeholder #a.
+  // Note that this string is already enclosed in double quotes at this point
   s = callingAETitle;
   sanitizeAETitle(s);
   if (s != callingAETitle)
@@ -2385,7 +2408,8 @@ static void executeOnReception()
   }
   cmd = replaceChars( cmd, OFString(CALLING_AETITLE_PLACEHOLDER), s );
 
-  // perform substitution for placeholder #c
+  // perform substitution for placeholder #c.
+  // Note that this string is already enclosed in double quotes at this point
   s = calledAETitle;
   sanitizeAETitle(s);
   if (s != calledAETitle)
@@ -2394,8 +2418,15 @@ static void executeOnReception()
   }
   cmd = replaceChars( cmd, OFString(CALLED_AETITLE_PLACEHOLDER), s );
 
-  // perform substitution for placeholder #r
-  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), 
callingPresentationAddress );
+  // perform substitution for placeholder #r.
+  // Note that this string is already enclosed in double quotes at this point
+  s = callingPresentationAddress;
+  sanitizeAETitle(s);
+  if (s != callingPresentationAddress)
+  {
+    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in calling 
presentation address, converted from " << callingPresentationAddress << " to " 
<< s << ".");
+  }
+  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), 
s );
 
   // Execute command in a new process
   executeCommand( cmd );
@@ -2500,20 +2531,38 @@ static void executeOnEndOfStudy()
   OFString s;
 
   // perform substitution for placeholder #p; #p will be substituted by 
lastStudySubdirectoryPathAndName
+  // Note: We do not enclose this in quotes because it may be used as part of 
a path expression.
   cmd = replaceChars( cmd, OFString(PATH_PLACEHOLDER), 
lastStudySubdirectoryPathAndName );
 
-  // perform substitution for placeholder #a
+  // perform substitution for placeholder #a.
+  // Note that this string is already enclosed in double quotes at this point
   s = callingAETitle;
   sanitizeAETitle(s);
+  if (s != callingAETitle)
+  {
+    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in calling 
aetitle, converted from " << callingAETitle << " to " << s << ".");
+  }
   cmd = replaceChars( cmd, OFString(CALLING_AETITLE_PLACEHOLDER), s );
 
-  // perform substitution for placeholder #c
+  // perform substitution for placeholder #c.
+  // Note that this string is already enclosed in double quotes at this point
   s = calledAETitle;
   sanitizeAETitle(s);
+  if (s != calledAETitle)
+  {
+    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in called 
aetitle, converted from " << calledAETitle << " to " << s << ".");
+  }
   cmd = replaceChars( cmd, OFString(CALLED_AETITLE_PLACEHOLDER), s );
 
-  // perform substitution for placeholder #r
-  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), 
callingPresentationAddress );
+  // perform substitution for placeholder #r.
+  // Note that this string is already enclosed in double quotes at this point
+  s = callingPresentationAddress;
+  sanitizeAETitle(s);
+  if (s != callingPresentationAddress)
+  {
+    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in calling 
presentation address, converted from " << callingPresentationAddress << " to " 
<< s << ".");
+  }
+  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), 
s );
 
   // Execute command in a new process
   executeCommand( cmd );
diff --git a/ofstd/libsrc/ofstd.cc b/ofstd/libsrc/ofstd.cc
index 3524695..78284b0 100644
--- a/ofstd/libsrc/ofstd.cc
+++ b/ofstd/libsrc/ofstd.cc
@@ -3402,16 +3402,26 @@ void OFStandard::forceSleep(Uint32 seconds)
 }
 
 
+static const char sanitized_filename_charset[] =
+{
+  ' ', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '-', '.', 
'_',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '_', '_', '_', '_', 
'_',
+  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 
'O',
+  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '_', '_', '_', 
'_',
+  '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
'o',
+  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '_', '_', '_', 
'_'
+};
+
+
 void OFStandard::sanitizeFilename(OFString& fname)
 {
     const size_t len = fname.length();
+    char c;
     for (size_t i = 0; i < len; ++i)
     {
-#ifdef _WIN32
-        if ((fname[i] == PATH_SEPARATOR) || (fname[i] == '/')) fname[i] = '_';
-#else
-        if (fname[i] == PATH_SEPARATOR) fname[i] = '_';
-#endif
+        c = fname[i];
+        if (c != 0 && (c < 32 || c >= 127)) c = '_'; else c = 
sanitized_filename_charset[c-32];
+        fname[i] = c;
     }
 }
 
@@ -3423,11 +3433,7 @@ void OFStandard::sanitizeFilename(char *fname)
         char *c = fname;
         while (*c)
         {
-#ifdef _WIN32
-            if ((*c == PATH_SEPARATOR) || (*c == '/')) *c = '_';
-#else
-            if (*c == PATH_SEPARATOR) *c = '_';
-#endif
+            if (*c < 32 || *c >= 127) *c = '_'; else *c = 
sanitized_filename_charset[*c-32];
             ++c;
         }
     }
-- 
2.53.0

Reply via email to