From b37677f7e40276bd8f504584bcba2c092f1146a8 Mon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <hpa@zytor.com>
Date: Mon, 7 Nov 2022 10:26:03 -0800
Subject: [PATCH] quote_for_pmake: fix counter underrun resulting in segfault

while (nbs--) { ... } ends with nbs == -1. Rather than a minimal fix,
introduce mempset() to make these kinds of errors less likely in the
future.

Fixes: https://bugzilla.nasm.us/show_bug.cgi?id=3392815
Reported-by: <13579and24680@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>

Upstream-Status: Backport
CVE: CVE-2022-4437

Reference to upstream patch:
[https://github.com/netwide-assembler/nasm/commit/2d4e6952417ec6f08b6f135d2b5d0e19b7dae30d]

Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
---
 asm/nasm.c         | 12 +++++-------
 configure.ac       |  1 +
 include/compiler.h |  7 +++++++
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/asm/nasm.c b/asm/nasm.c
index 7a7f8b4..675cff4 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 1996-2020 The NASM Authors - All Rights Reserved
+ *   Copyright 1996-2022 The NASM Authors - All Rights Reserved
  *   See the file AUTHORS included with the NASM distribution for
  *   the specific copyright holders.
  *
@@ -814,8 +814,7 @@ static char *quote_for_pmake(const char *str)
     }

     /* Convert N backslashes at the end of filename to 2N backslashes */
-    if (nbs)
-        n += nbs;
+    n += nbs;

     os = q = nasm_malloc(n);

@@ -824,10 +823,10 @@ static char *quote_for_pmake(const char *str)
         switch (*p) {
         case ' ':
         case '\t':
-            while (nbs--)
-                *q++ = '\\';
+            q = mempset(q, '\\', nbs);
             *q++ = '\\';
             *q++ = *p;
+            nbs = 0;
             break;
         case '$':
             *q++ = *p;
@@ -849,9 +848,8 @@ static char *quote_for_pmake(const char *str)
             break;
         }
     }
-    while (nbs--)
-        *q++ = '\\';

+    q = mempset(q, '\\', nbs);
     *q = '\0';

     return os;
diff --git a/configure.ac b/configure.ac
index 39680b1..940ebe2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -199,6 +199,7 @@ AC_CHECK_FUNCS(strrchrnul)
 AC_CHECK_FUNCS(iscntrl)
 AC_CHECK_FUNCS(isascii)
 AC_CHECK_FUNCS(mempcpy)
+AC_CHECK_FUNCS(mempset)

 AC_CHECK_FUNCS(getuid)
 AC_CHECK_FUNCS(getgid)
diff --git a/include/compiler.h b/include/compiler.h
index db3d6d6..b64da6a 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -256,6 +256,13 @@ static inline void *mempcpy(void *dst, const void *src, size_t n)
 }
 #endif

+#ifndef HAVE_MEMPSET
+static inline void *mempset(void *dst, int c, size_t n)
+{
+    return (char *)memset(dst, c, n) + n;
+}
+#endif
+
 /*
  * Hack to support external-linkage inline functions
  */
--
2.40.0
