Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: x...@packages.debian.org
Control: affects -1 + src:xfpt
User: release.debian....@packages.debian.org
Usertags: pu

Hello,

I would like to fix a minor security issue (#1080219 CVE-2024-43700) in
stable, no DSA is planned.

[ 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

This is pretty straightforward cherry-pick of the upstream change, just
dropping some noise (copyright year and version bump.)

cu Andreas
-- 
`What a good friend you are to him, Dr. Maturin. His other friends are
so grateful to you.'
`I sew his ears on from time to time, sure'
diff -Nru xfpt-0.11/debian/changelog xfpt-0.11/debian/changelog
--- xfpt-0.11/debian/changelog	2020-09-18 11:13:36.000000000 +0200
+++ xfpt-0.11/debian/changelog	2024-10-19 13:32:57.000000000 +0200
@@ -1,3 +1,11 @@
+xfpt (0.11-1+deb12u1) bookworm; urgency=medium
+
+  * Cherry-pick 30-Diagnose-error-if-macro-expansion-makes-a-line-too-l.patch
+    from upstream GIT master to fix buffer overflow CVE-2024-43700.
+    Closes: #1080219
+
+ -- Andreas Metzler <ametz...@debian.org>  Sat, 19 Oct 2024 13:32:57 +0200
+
 xfpt (0.11-1) unstable; urgency=low
 
   * Fix watchfile (report functionality).
diff -Nru xfpt-0.11/debian/patches/30-Diagnose-error-if-macro-expansion-makes-a-line-too-l.patch xfpt-0.11/debian/patches/30-Diagnose-error-if-macro-expansion-makes-a-line-too-l.patch
--- xfpt-0.11/debian/patches/30-Diagnose-error-if-macro-expansion-makes-a-line-too-l.patch	1970-01-01 01:00:00.000000000 +0100
+++ xfpt-0.11/debian/patches/30-Diagnose-error-if-macro-expansion-makes-a-line-too-l.patch	2024-10-19 13:32:57.000000000 +0200
@@ -0,0 +1,280 @@
+From a690304bbd3fd19e9dfdad50dcc87ad829f744e4 Mon Sep 17 00:00:00 2001
+From: Philip Hazel <philip.ha...@gmail.com>
+Date: Sun, 11 Aug 2024 17:43:41 +0100
+Subject: [PATCH] Diagnose error if macro expansion makes a line too long for
+ its buffer
+
+---
+ ChangeLog                |  7 +++++++
+ src/dot.c                |  9 +++++++--
+ src/error.c              |  7 ++++---
+ src/functions.h          |  4 ++--
+ src/globals.c            |  4 ++--
+ src/para.c               |  5 +++--
+ src/read.c               | 27 +++++++++++++++++++++------
+ src/structs.h            |  3 ++-
+ testing/infiles/07       |  5 +++++
+ testing/outfiles/07      |  1 +
+ testing/outfiles/07.err  |  4 ++++
+ testing/outfiles/cmd.err |  2 +-
+ 12 files changed, 59 insertions(+), 19 deletions(-)
+ create mode 100644 testing/infiles/07
+ create mode 100644 testing/outfiles/07
+ create mode 100644 testing/outfiles/07.err
+
+--- a/src/dot.c
++++ b/src/dot.c
+@@ -467,10 +467,11 @@ while (*p != 0)
+   argstr *as = misc_malloc(sizeof(argstr));
+   as->next = NULL;
+   *pp = as;
+   pp = &(as->next);
+   as->string = misc_readitem(p, NULL, &length, NULL, 0);
++  as->length = length;
+   p += length;
+   }
+ 
+ pp = &(md->lines);
+ for (;;)
+@@ -488,21 +489,24 @@ for (;;)
+ 
+   as = misc_malloc(sizeof(argstr));
+   as->next = NULL;
+   *pp = as;
+   pp = &(as->next);
+-  as->string = misc_copystring(line, Ustrlen(line));
++  length = Ustrlen(line);
++  as->string = misc_copystring(line, length);
++  as->length = length;
+   }
+ 
+ /* If there aren't any replacement lines, fake up a comment so that there's
+ always something for a macro to generate. */
+ 
+ if (md->lines == NULL)
+   {
+   md->lines = misc_malloc(sizeof(argstr));
+   md->lines->next = NULL;
+   md->lines->string = misc_copystring(US". Dummy line\n", 13);
++  md->lines->length = 13;
+   }
+ }
+ 
+ 
+ 
+@@ -900,10 +904,11 @@ while (*p != 0)
+   argstr *as = misc_malloc(sizeof(argstr));
+   as->next = NULL;
+   *pp = as;
+   pp = &(as->next);
+   as->string = misc_readitem(p, NULL, &length, NULL, 0);
++  as->length = length;
+   p += length;
+   }
+ }
+ 
+ /* End of dot.c */
+--- a/src/error.c
++++ b/src/error.c
+@@ -78,11 +78,12 @@ static error_struct error_data[] = {
+ { ec_serious,  "\".nest end\" incorrectly nested" },
+ { ec_serious,  "missing delimiter after $=%d at end of line" },
+ /* 30-34 */
+ { ec_serious,  "bad macro argument substitution: %s follows \"%s\"" },
+ { ec_serious,  "binary zero in input ignored" },
+-{ ec_disaster, "input sources too deeply nested" }
++{ ec_disaster, "input sources too deeply nested" },
++{ ec_disaster, "maximum line length exceeded during macro substitution" }
+ };
+ 
+ #define error_maxerror (int)(sizeof(error_data)/sizeof(error_struct))
+ 
+ 
+--- a/src/functions.h
++++ b/src/functions.h
+@@ -20,11 +20,11 @@ extern uschar     *misc_readstring(uscha
+ 
+ extern void        para_process(uschar *);
+ 
+ extern uschar     *read_nextline(void);
+ extern uschar     *read_paragraph(uschar *, int *);
+-extern void        read_process_macroline(uschar *, uschar *);
++extern void        read_process_macroline(uschar *, uschar *, int);
+ 
+ extern int         tree_insertnode(tree_node **, tree_node *);
+ extern tree_node  *tree_search(tree_node *, uschar *);
+ 
+ /* End of functions.h */
+--- a/src/para.c
++++ b/src/para.c
+@@ -66,10 +66,11 @@ while (*q != 0 && *q != ')')
+   argstr *as = misc_malloc(sizeof(argstr));
+   as->next = NULL;
+   *pp = as;
+   pp = &(as->next);
+   as->string = misc_readitem(q, US",)", &length, NULL, 0);
++  as->length = length; 
+   q += length;
+   if (*q == ',') while (isspace(*(++q)));
+   }
+ 
+ if (*q != ')')
+@@ -88,11 +89,11 @@ para_inline_macro++;
+ 
+ for (;;)
+   {
+   uschar buffer[INBUFFSIZE];
+ 
+-  read_process_macroline(macrocurrent->nextline->string, buffer);
++  read_process_macroline(macrocurrent->nextline->string, buffer, INBUFFSIZE);
+ 
+   /* A directive such as .eacharg can skip to the end of the macro if there
+   is no .endeach. Detect this by looking for a change of macrocurrent value,
+   because there may be an enclosing macro. */
+ 
+--- a/src/read.c
++++ b/src/read.c
+@@ -29,11 +29,11 @@ Arguments:
+ 
+ Returns:    nothing
+ */
+ 
+ void
+-read_process_macroline(uschar *p, uschar *b)
++read_process_macroline(uschar *p, uschar *b, int blen)
+ {
+ int optend = 0;
+ 
+ while (*p != 0)
+   {
+@@ -49,21 +49,27 @@ while (*p != 0)
+     optend = 0;
+     p++;
+     continue;
+     }
+ 
++  /* Ensure at least 3 bytes left in the buffer because all cases except an
++  argument substitution (which does its own test) add no more than two bytes,
++  and the third is for the terminating zero. */
++
++  if (blen < 3) error(33);   /* Hard error; does not return. */
++
+   /* Until we hit a dollar, just copy verbatim */
+ 
+-  if (*p != '$') { *b++ = *p++; continue; }
++  if (*p != '$') { *b++ = *p++; blen--; continue; }
+ 
+   /* If dollar is at the end of the string, treat as literal. */
+ 
+   if (p[1] == 0) { *b++ = '$'; break; }
+ 
+   /* If the character after $ is another $, insert a literal $. */
+ 
+-  if (p[1] == '$') { p++; *b++ = *p++; continue; }
++  if (p[1] == '$') { p++; *b++ = *p++; blen--; continue; }
+ 
+   /* If the character after $ is +, we are dealing with arguments
+   relative to macro_arg0 in a ".eacharg" section. Otherwise, we are dealing
+   with an absolute argument number. */
+ 
+@@ -73,10 +79,11 @@ while (*p != 0)
+     if (macro_argbase == NULL)       /* Not in a .eacharg section */
+       {
+       error(18);
+       *b++ = '$';
+       *b++ = *p++;
++      blen -= 2;
+       continue;
+       }
+     argbase = macro_argbase;
+     }
+   else argbase = macrocurrent->args;
+@@ -90,10 +97,11 @@ while (*p != 0)
+       {
+       if (p[1] == 0 || p[1] == '\n') error(30, "end of line", "$=");
+         else error(17, p[1], "$=");
+       *b++ = '$';
+       *b++ = *p++;
++      blen -= 2;
+       continue;
+       }
+     while (isdigit(*(++p))) argn = argn * 10 + *p - '0';
+ 
+     if (*p == 0 || *p == '\n')
+@@ -126,10 +134,11 @@ while (*p != 0)
+   if (!isdigit(p[1]))
+     {
+     if (*p == 0 || *p == '\n') error(30, "end of line", "$");
+       else error(17, p[1], "$");
+     *b++ = *p++;
++    blen--;
+     continue;
+     }
+   while (isdigit(*(++p))) argn = argn * 10 + *p - '0';
+ 
+   /* Handle $0 - currently no meaning */
+@@ -161,11 +170,16 @@ while (*p != 0)
+       }
+     }
+ 
+   /* If we have found an argument, substitute it. */
+ 
+-  if (arg != NULL) b += sprintf(CS b, "%s", arg->string);
++  if (arg != NULL)
++    {
++    blen -= arg->length;
++    if (blen < 1) error(33);  /* Hard; does not return */
++    b += sprintf(CS b, "%s", arg->string);
++    }
+   }
+ 
+ *b = 0;
+ }
+ 
+@@ -294,11 +308,12 @@ for (;;)
+       macrocurrent = macrocurrent->prev;
+       macro_free(temp);
+       }
+     else
+       {
+-      read_process_macroline(macrocurrent->nextline->string, inbuffer);
++      read_process_macroline(macrocurrent->nextline->string, inbuffer,
++        INBUFFSIZE);
+       macrocurrent->nextline = macrocurrent->nextline->next;
+       break;
+       }
+     }
+ 
+--- a/src/structs.h
++++ b/src/structs.h
+@@ -42,10 +42,11 @@ typedef struct pushstr {
+ /* Macro content and argument item */
+ 
+ typedef struct argstr {
+   struct argstr *next;
+   uschar *string;
++  int length; 
+ } argstr;
+ 
+ /* Macro definition item */
+ 
+ typedef struct macrodef {
+--- /dev/null
++++ b/testing/infiles/07
+@@ -0,0 +1,5 @@
++.macro m1 one
++$1
++.endmacro
++&m1(111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)
++
+--- /dev/null
++++ b/testing/outfiles/07
+@@ -0,0 +1 @@
++<para>
+--- /dev/null
++++ b/testing/outfiles/07.err
+@@ -0,0 +1,4 @@
++** Error: maximum line length exceeded during macro substitution
++   Processing macro m1
++   Detected near line 6 of infiles/07
++** xfpt abandoned
diff -Nru xfpt-0.11/debian/patches/series xfpt-0.11/debian/patches/series
--- xfpt-0.11/debian/patches/series	2014-09-28 08:12:44.000000000 +0200
+++ xfpt-0.11/debian/patches/series	2024-10-19 13:32:57.000000000 +0200
@@ -1,2 +1,3 @@
 10_destdirsupport.diff
 20_ld_and_cppflags.diff
+30-Diagnose-error-if-macro-expansion-makes-a-line-too-l.patch

Attachment: signature.asc
Description: PGP signature

Reply via email to