Bug#973884: make-dfsg: fix for extraordinarily-long command lines (#688601) has gone missing

2024-06-18 Thread Patrick Verkaik
Package: make
Version: 4.3-4.1
Followup-For: Bug #973884
X-Debbugs-Cc: patr...@meraki.com

Dear Maintainer,

I've run into this same bug while building embedded software and
basically went down the same road as the original submitter of this bug,
leading to pretty much the same patch.

It appears that upstream GNU make has not merged a proposed port of the
original Debian fix (https://savannah.gnu.org/bugs/index.php?45763), and
so I would really like Debian to fix this in make-dfsg.

The issue is very easy to reproduce. Here is a Makefile that
demonstrates the problem:

--
repeated_string := $(foreach n,$(shell seq 1 7),a)

all:
@echo "$(repeated_string)"; echo
--

In the breaking case, make will fail with:

make: /bin/sh: Argument list too long

Note that the breaking length of repeated_string may depend on system
parameters and thus the length may need to be increased for a successful
reproduction.

Thanks,
Patrick Verkaik

-- System Information:
Debian Release: 11.9
  APT prefers oldstable-updates
  APT policy: (500, 'oldstable-updates'), (500, 'oldstable-security'), (500, 
'oldstable')
Architecture: amd64 (x86_64)

Kernel: Linux 5.3.0-51-generic (SMP w/112 CPU threads)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_WARN, TAINT_OOT_MODULE, 
TAINT_UNSIGNED_MODULE
Locale: LANG=C, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: unable to detect

Versions of packages make depends on:
ii  libc6  2.31-13+deb11u10

make recommends no packages.

Versions of packages make suggests:
pn  make-doc  

-- no debconf information



Bug#973884: make-dfsg: fix for extraordinarily-long command lines (#688601) has gone missing

2020-11-06 Thread Mike Crowe
Source: make-dfsg
Severity: normal

Dear Maintainer,

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=688601 was fixed back in
2014 by applying a patch (dgit:407e2fb3130d4540482a04987222dead70936122)
and this fix worked well for us for several years.

Unfortunately, this change appears to have been removed as part of:

 commit 0e957340243587eeffb525aff3200b5e143ac274
 Author: Manoj Srivastava 
 Date:   Mon Feb 12 16:26:34 2018 -0800

 [master]: revert debian specific patches that have been integrated 
differently upstream.

 Signed-off-by: Manoj Srivastava 

so this fix is no longer present in Buster, and apparently Bullseye. I've
been unable to find any other information about reverting the fix.

The main part of the original patch still applied and the conflicts in the
configure.ac file appeared to be straightforward to resolve. The resulting
patch is attached. Applying it fixed the problem for me.

-- System Information:
Debian Release: bullseye/sid
  APT prefers testing
  APT policy: (400, 'testing'), (50, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.9.0-1-amd64 (SMP w/8 CPU threads)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_GB:en
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
commit f079489160d620e5eb50dc09e51f09f71a7dcffb
Author: Mike Crowe 
Date:   Fri Nov 6 15:22:37 2020 +

Resurrect fix for large command line

This patch was originally applied by Manoj Srivastava to fix Debian bug
other changes that had apparently been fixed differently upstream. That
turns out not to have been true for this particular fix.

The original patch description follows.

---8<---
[handle_excessive_command_length]: Patch to fix large cmmand line

When presented with a very very long command line (e.g. WebKit's linking
of libWebCore.la in current git), make fails to execute the command as
it doesn't split the command line to fit within the limits.

This patch provides a POSIX specific fix.
--->8---

diff --git a/configure.ac b/configure.ac
index a1d41640..98dd2309 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,7 +75,7 @@ AC_HEADER_STAT
 AC_HEADER_TIME
 AC_CHECK_HEADERS([stdlib.h locale.h unistd.h limits.h fcntl.h string.h \
   memory.h sys/param.h sys/resource.h sys/time.h sys/timeb.h \
-  sys/select.h sys/file.h spawn.h])
+  sys/select.h sys/file.h spawn.h sys/user.h linux/binfmts.h])
 
 AM_PROG_CC_C_O
 AC_C_CONST
diff --git a/src/job.c b/src/job.c
index ae1f18b9..3abba81a 100644
--- a/src/job.c
+++ b/src/job.c
@@ -26,6 +26,14 @@ this program.  If not, see .  */
 #include "variable.h"
 #include "os.h"
 
+#if defined (HAVE_LINUX_BINFMTS_H) && defined (HAVE_SYS_USER_H)
+#include 
+#include 
+#endif
+#ifndef PAGE_SIZE
+# define PAGE_SIZE (sysconf(_SC_PAGESIZE))
+#endif
+
 /* Default shell to use.  */
 #ifdef WINDOWS32
 # ifdef HAVE_STRINGS_H
@@ -3217,6 +3225,7 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
 #ifdef WINDOWS32
 char *command_ptr = NULL; /* used for batch_mode_shell mode */
 #endif
+char *args_ptr;
 
 # ifdef __EMX__ /* is this necessary? */
 if (!unixy_shell && shellflags)
@@ -3382,8 +3391,17 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
 return new_argv;
   }
 
+#ifdef MAX_ARG_STRLEN
+static char eval_line[] = "eval\\ \\\"set\\ x\\;\\ shift\\;\\ ";
+#define ARG_NUMBER_DIGITS 5
+#define EVAL_LEN (sizeof(eval_line)-1 + shell_len + 4   \
+  + (7 + ARG_NUMBER_DIGITS) * 2 * line_len / (MAX_ARG_STRLEN - 2))
+#else
+#define EVAL_LEN 0
+#endif
+
 new_line = xmalloc ((shell_len*2) + 1 + sflags_len + 1
-+ (line_len*2) + 1);
++ (line_len*2) + 1 + EVAL_LEN);
 ap = new_line;
 /* Copy SHELL, escaping any characters special to the shell.  If
we don't escape them, construct_command_argv_internal will
@@ -3403,6 +3421,30 @@ construct_command_argv_internal (char *line, char **restp, const char *shell,
 #ifdef WINDOWS32
 command_ptr = ap;
 #endif
+
+#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN)
+if (unixy_shell && line_len > MAX_ARG_STRLEN)
+  {
+   unsigned j;
+   memcpy (ap, eval_line, sizeof (eval_line) - 1);
+   ap += sizeof (eval_line) - 1;
+   for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++)
+ ap += sprintf (ap, "\\$\\{%u\\}", j);
+   *ap++ = '\\';
+   *ap++ = '"';
+   *ap++ = ' ';
+   /* Copy only the first word of SHELL to $0.  */
+   for (p = shell; *p != '\0'; ++p)
+ {
+   if (isspace ((unsigned char)*p))
+ break;
+   *ap++ = *p;
+ }
+   *ap++ = ' ';
+  }
+#endif
+args_ptr = ap;
+
 for