Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: exuberant-ct...@packages.debian.org
Control: affects -1 + src:exuberant-ctags

[ Reason ]
I'd like to belatedly fix CVE-2022-4515 in bullseye.

[ Impact ]
Security vulnerability as described in
https://security-tracker.debian.org/tracker/CVE-2022-4515, though the
security team has marked it no-dsa and asked that any fix go via a point
release instead.

[ Tests ]
I tested this manually by calling ctags with various -o options, e.g.
"ctags -o 'a b' -R", and checking that it produces the requested output
file names.

[ Risks ]
The fix is just a straight cherry-pick from bookworm (which in turn was
backported as closely as possible from universal-ctags upstream), and
while I hate the continued use of system(3) here it's probably better
than introducing a novel rewrite for a security update.

[ 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 ]
As attached.  git-dpm has introduced a small amount of additional noise;
I didn't think it was worth the effort to persuade it to avoid that in
this case.

Thanks,

-- 
Colin Watson (he/him)                              [cjwat...@debian.org]
diff --git a/debian/.git-dpm b/debian/.git-dpm
index be86f1e84..e26b5ab8c 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,6 +1,6 @@
 # see git-dpm(1) from git-dpm package
-ed1d00e4c005ecc20f298630cce7635d88f5b669
-ed1d00e4c005ecc20f298630cce7635d88f5b669
+5c9ca1167f9eebf78bf28763e3604b1af79c967d
+5c9ca1167f9eebf78bf28763e3604b1af79c967d
 4b0ebb9d344fd369c889291478986c65a5a36ea8
 4b0ebb9d344fd369c889291478986c65a5a36ea8
 exuberant-ctags_5.9~svn20110310.orig.tar.gz
diff --git a/debian/changelog b/debian/changelog
index 62ccf7654..75c7d8e08 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+exuberant-ctags (1:5.9~svn20110310-14+deb11u1) UNRELEASED; urgency=medium
+
+  * Backport from universal-ctags:
+    - CVE-2022-4515: main: quote output file name before passing it to
+      system(3) function (closes: #1026995).
+
+ -- Colin Watson <cjwat...@debian.org>  Sun, 24 Dec 2023 12:41:53 +0000
+
 exuberant-ctags (1:5.9~svn20110310-14) unstable; urgency=low
 
   [ Debian Janitor ]
diff --git a/debian/patches/gcc-no-common.patch 
b/debian/patches/gcc-no-common.patch
index 024422c9e..308f7d9c9 100644
--- a/debian/patches/gcc-no-common.patch
+++ b/debian/patches/gcc-no-common.patch
@@ -14,7 +14,7 @@ Patch-Name: gcc-no-common.patch
  2 files changed, 11 insertions(+), 11 deletions(-)
 
 diff --git a/objc.c b/objc.c
-index 2a5de58..a5811ec 100644
+index 2a5de58ab..a5811ec59 100644
 --- a/objc.c
 +++ b/objc.c
 @@ -432,16 +432,16 @@ typedef void (*parseNext) (vString * const ident, 
objcToken what);
@@ -38,7 +38,7 @@ index 2a5de58..a5811ec 100644
  
  /********** Grammar */
 diff --git a/ocaml.c b/ocaml.c
-index 104a777..235862f 100644
+index 104a77706..235862fd3 100644
 --- a/ocaml.c
 +++ b/ocaml.c
 @@ -514,26 +514,26 @@ typedef void (*parseNext) (vString * const ident, 
ocaToken what);
diff --git a/debian/patches/go.patch b/debian/patches/go.patch
index 760f47bd0..bce44fd73 100644
--- a/debian/patches/go.patch
+++ b/debian/patches/go.patch
@@ -17,7 +17,7 @@ Patch-Name: go.patch
 
 diff --git a/go.c b/go.c
 new file mode 100644
-index 0000000..6bd3a36
+index 000000000..6bd3a369a
 --- /dev/null
 +++ b/go.c
 @@ -0,0 +1,670 @@
@@ -692,7 +692,7 @@ index 0000000..6bd3a36
 +      return def;
 +}
 diff --git a/parsers.h b/parsers.h
-index 600f636..3a24d6e 100644
+index 600f63614..3a24d6e09 100644
 --- a/parsers.h
 +++ b/parsers.h
 @@ -31,6 +31,7 @@
@@ -704,7 +704,7 @@ index 600f636..3a24d6e 100644
        JavaParser, \
        JavaScriptParser, \
 diff --git a/source.mak b/source.mak
-index c97617f..985d56c 100644
+index c97617f34..985d56cfc 100644
 --- a/source.mak
 +++ b/source.mak
 @@ -24,6 +24,7 @@ SOURCES = \
diff --git a/debian/patches/jscript-set-tag-scope.patch 
b/debian/patches/jscript-set-tag-scope.patch
index baf036ffc..a0958b573 100644
--- a/debian/patches/jscript-set-tag-scope.patch
+++ b/debian/patches/jscript-set-tag-scope.patch
@@ -17,7 +17,7 @@ Patch-Name: jscript-set-tag-scope.patch
  1 file changed, 51 insertions(+), 3 deletions(-)
 
 diff --git a/jscript.c b/jscript.c
-index 5de3367..a790355 100644
+index 5de3367f9..a790355b8 100644
 --- a/jscript.c
 +++ b/jscript.c
 @@ -215,6 +215,7 @@ static void deleteToken (tokenInfo *const token)
diff --git a/debian/patches/memmove.patch b/debian/patches/memmove.patch
index d23551a4b..b3e0ad9e1 100644
--- a/debian/patches/memmove.patch
+++ b/debian/patches/memmove.patch
@@ -16,7 +16,7 @@ Patch-Name: memmove.patch
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/routines.c b/routines.c
-index 83bcdcc..8ebe2e0 100644
+index 83bcdccda..8ebe2e0ad 100644
 --- a/routines.c
 +++ b/routines.c
 @@ -757,13 +757,13 @@ extern char* absoluteFilename (const char *file)
diff --git a/debian/patches/python-disable-imports.patch 
b/debian/patches/python-disable-imports.patch
index 99c4e20fb..f77909746 100644
--- a/debian/patches/python-disable-imports.patch
+++ b/debian/patches/python-disable-imports.patch
@@ -18,7 +18,7 @@ Patch-Name: python-disable-imports.patch
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/python.c b/python.c
-index a90d072..bf797de 100644
+index a90d072b3..bf797de7c 100644
 --- a/python.c
 +++ b/python.c
 @@ -56,7 +56,7 @@ static kindOption PythonKinds[] = {
diff --git a/debian/patches/quote-output-file-name.patch 
b/debian/patches/quote-output-file-name.patch
new file mode 100644
index 000000000..25e52fbc7
--- /dev/null
+++ b/debian/patches/quote-output-file-name.patch
@@ -0,0 +1,115 @@
+From 5c9ca1167f9eebf78bf28763e3604b1af79c967d Mon Sep 17 00:00:00 2001
+From: Masatake YAMATO <yam...@redhat.com>
+Date: Mon, 24 Oct 2016 23:52:23 +0900
+Subject: main: quote output file name before passing it to system(3) function
+
+Following command line doesn't work:
+
+      $ ctags -o 'a b' ...
+
+because a shell lauched from system(3) deals a whitespace between 'a'
+and 'b' as a separator. The output file name is passed to system(3)
+to run external sort command.
+
+This commit adds code to put double and single quoets around the output
+file name before passing it to system(3).
+
+The issue is reported by Lorenz Hipp <lh...@idealbonn.de> in a private mail.
+
+Signed-off-by: Masatake YAMATO <yam...@redhat.com>
+
+Origin: backport, 
https://github.com/universal-ctags/ctags/commit/e00c55d7a0204dc1d0ae316141323959e1e16162
+Bug-Debian: https://bugs.debian.org/1026995
+Last-Update: 2022-12-26
+
+Patch-Name: quote-output-file-name.patch
+---
+ sort.c | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 42 insertions(+), 11 deletions(-)
+
+diff --git a/sort.c b/sort.c
+index c58defc34..260fbbd21 100644
+--- a/sort.c
++++ b/sort.c
+@@ -53,17 +53,44 @@ extern void catFile (const char *const name)
+ # define PE_CONST const
+ #endif
+ 
++/*
++   Output file name should not be evaluated in system(3) function.
++   The name must be used as is. Quotations are required to block the
++   evaluation.
++
++   Normal single-quotes are used to quote a cstring:
++   a => 'a'
++   " => '"'
++
++   If a single-quote is included in the cstring, use double quotes for 
quoting it.
++   ' => ''"'"''
++*/
++static void appendCstringWithQuotes (vString *dest, const char* cstr)
++{
++      const char* o;
++
++      vStringPut (dest, '\'');
++      for (o = cstr; *o; o++)
++      {
++              if (*o == '\'')
++                      vStringCatS (dest, "'\"'\"'");
++              else
++                      vStringPut (dest, *o);
++      }
++      vStringPut (dest, '\'');
++}
++
+ extern void externalSortTags (const boolean toStdout)
+ {
+       const char *const sortNormalCommand = "sort -u -o";
+       const char *const sortFoldedCommand = "sort -u -f -o";
+       const char *sortCommand =
+               Option.sorted == SO_FOLDSORTED ? sortFoldedCommand : 
sortNormalCommand;
++# ifndef HAVE_SETENV
+       PE_CONST char *const sortOrder1 = "LC_COLLATE=C";
+       PE_CONST char *const sortOrder2 = "LC_ALL=C";
+-      const size_t length = 4 + strlen (sortOrder1) + strlen (sortOrder2) +
+-                      strlen (sortCommand) + (2 * strlen (tagFileName ()));
+-      char *const cmd = (char *) malloc (length + 1);
++# endif
++      vString *cmd = vStringNew ();
+       int ret = -1;
+ 
+       if (cmd != NULL)
+@@ -73,21 +100,25 @@ extern void externalSortTags (const boolean toStdout)
+ #ifdef HAVE_SETENV
+               setenv ("LC_COLLATE", "C", 1);
+               setenv ("LC_ALL", "C", 1);
+-              sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), 
tagFileName ());
+ #else
+ # ifdef HAVE_PUTENV
+               putenv (sortOrder1);
+               putenv (sortOrder2);
+-              sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), 
tagFileName ());
+ # else
+-              sprintf (cmd, "%s %s %s %s %s", sortOrder1, sortOrder2, 
sortCommand,
+-                              tagFileName (), tagFileName ());
++              vStringCatS (cmd, sortOrder1);
++              vStringPut (cmd, ' ');
++              vStringCatS (cmd, sortOrder2);
++              vStringPut (cmd, ' ');
+ # endif
+ #endif
+-              verbose ("system (\"%s\")\n", cmd);
+-              ret = system (cmd);
+-              free (cmd);
+-
++              vStringCatS (cmd, sortCommand);
++              vStringPut (cmd, ' ');
++              appendCstringWithQuotes (cmd, tagFileName ());
++              vStringPut (cmd, ' ');
++              appendCstringWithQuotes (cmd, tagFileName ());
++              verbose ("system (\"%s\")\n", vStringValue (cmd));
++              ret = system (vStringValue (cmd));
++              vStringDelete (cmd);
+       }
+       if (ret != 0)
+               error (FATAL | PERROR, "cannot sort tag file");
diff --git a/debian/patches/reproducible.patch 
b/debian/patches/reproducible.patch
index 7d0bae4b0..3571259e8 100644
--- a/debian/patches/reproducible.patch
+++ b/debian/patches/reproducible.patch
@@ -13,7 +13,7 @@ Patch-Name: reproducible.patch
  1 file changed, 1 deletion(-)
 
 diff --git a/options.c b/options.c
-index d26627f..ae773ef 100644
+index d26627feb..ae773ef1e 100644
 --- a/options.c
 +++ b/options.c
 @@ -924,7 +924,6 @@ static void printProgramIdentification (void)
diff --git a/debian/patches/series b/debian/patches/series
index 526a4e48f..a718557cd 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -5,3 +5,4 @@ go.patch
 jscript-set-tag-scope.patch
 reproducible.patch
 gcc-no-common.patch
+quote-output-file-name.patch
diff --git a/debian/patches/vim-command-loop.patch 
b/debian/patches/vim-command-loop.patch
index 44cfaadc6..1d02302d3 100644
--- a/debian/patches/vim-command-loop.patch
+++ b/debian/patches/vim-command-loop.patch
@@ -17,7 +17,7 @@ Patch-Name: vim-command-loop.patch
  1 file changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/vim.c b/vim.c
-index 4e6fba8..d17a1ba 100644
+index 4e6fba84f..d17a1baed 100644
 --- a/vim.c
 +++ b/vim.c
 @@ -405,7 +405,9 @@ static boolean parseCommand (const unsigned char *line)

Reply via email to