902636
From 5dc50c6bca059a9cda6677b1fd0187df1de78ed7 Mon Sep 17 00:00:00 2001
255e5e
From: jmaloy <jmaloy@redhat.com>
902636
Date: Thu, 13 Feb 2020 15:50:48 +0000
902636
Subject: [PATCH 2/7] util: add slirp_fmt() helpers
255e5e
MIME-Version: 1.0
255e5e
Content-Type: text/plain; charset=UTF-8
255e5e
Content-Transfer-Encoding: 8bit
255e5e
255e5e
RH-Author: jmaloy <jmaloy@redhat.com>
902636
Message-id: <20200213155049.3936-2-jmaloy@redhat.com>
902636
Patchwork-id: 93824
902636
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 1/2] util: add slirp_fmt() helpers
902636
Bugzilla: 1798994
902636
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
902636
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
255e5e
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
255e5e
255e5e
From: Marc-André Lureau <marcandre.lureau@redhat.com>
255e5e
255e5e
Various calls to snprintf() in libslirp assume that snprintf() returns
255e5e
"only" the number of bytes written (excluding terminating NUL).
255e5e
255e5e
https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html#tag_16_159_04
255e5e
255e5e
"Upon successful completion, the snprintf() function shall return the
255e5e
number of bytes that would be written to s had n been sufficiently
255e5e
large excluding the terminating null byte."
255e5e
255e5e
Introduce slirp_fmt() that handles several pathological cases the
255e5e
way libslirp usually expect:
255e5e
255e5e
- treat error as fatal (instead of silently returning -1)
255e5e
255e5e
- fmt0() will always \0 end
255e5e
255e5e
- return the number of bytes actually written (instead of what would
902636
have been written, which would usually result in OOB later), including
902636
the ending \0 for fmt0()
255e5e
255e5e
- warn if truncation happened (instead of ignoring)
255e5e
902636
Other less common cases can still be handled with strcpy/snprintf() etc.
255e5e
255e5e
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
255e5e
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
255e5e
Message-Id: <20200127092414.169796-2-marcandre.lureau@redhat.com>
902636
(cherry picked from libslirp commit 30648c03b27fb8d9611b723184216cd3174b6775)
255e5e
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
902636
255e5e
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
255e5e
---
902636
 slirp/src/util.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
902636
 slirp/src/util.h |  3 +++
902636
 2 files changed, 65 insertions(+)
902636
902636
diff --git a/slirp/src/util.c b/slirp/src/util.c
902636
index e596087..e3b6257 100644
902636
--- a/slirp/src/util.c
902636
+++ b/slirp/src/util.c
902636
@@ -364,3 +364,65 @@ void slirp_pstrcpy(char *buf, int buf_size, const char *str)
255e5e
     }
902636
     *q = '\0';
255e5e
 }
255e5e
+
255e5e
+static int slirp_vsnprintf(char *str, size_t size,
255e5e
+                           const char *format, va_list args)
255e5e
+{
255e5e
+    int rv = vsnprintf(str, size, format, args);
255e5e
+
255e5e
+    if (rv < 0) {
255e5e
+        g_error("vsnprintf() failed: %s", g_strerror(errno));
255e5e
+    }
255e5e
+
255e5e
+    return rv;
255e5e
+}
255e5e
+
255e5e
+/*
255e5e
+ * A snprintf()-like function that:
255e5e
+ * - returns the number of bytes written (excluding optional \0-ending)
255e5e
+ * - dies on error
255e5e
+ * - warn on truncation
255e5e
+ */
255e5e
+int slirp_fmt(char *str, size_t size, const char *format, ...)
255e5e
+{
255e5e
+    va_list args;
255e5e
+    int rv;
255e5e
+
255e5e
+    va_start(args, format);
255e5e
+    rv = slirp_vsnprintf(str, size, format, args);
255e5e
+    va_end(args);
255e5e
+
255e5e
+    if (rv > size) {
255e5e
+        g_critical("vsnprintf() truncation");
255e5e
+    }
255e5e
+
255e5e
+    return MIN(rv, size);
255e5e
+}
255e5e
+
255e5e
+/*
255e5e
+ * A snprintf()-like function that:
255e5e
+ * - always \0-end (unless size == 0)
255e5e
+ * - returns the number of bytes actually written, including \0 ending
255e5e
+ * - dies on error
255e5e
+ * - warn on truncation
255e5e
+ */
255e5e
+int slirp_fmt0(char *str, size_t size, const char *format, ...)
255e5e
+{
255e5e
+    va_list args;
255e5e
+    int rv;
255e5e
+
255e5e
+    va_start(args, format);
255e5e
+    rv = slirp_vsnprintf(str, size, format, args);
255e5e
+    va_end(args);
255e5e
+
255e5e
+    if (rv >= size) {
255e5e
+        g_critical("vsnprintf() truncation");
255e5e
+        if (size > 0)
255e5e
+            str[size - 1] = '\0';
255e5e
+        rv = size;
255e5e
+    } else {
255e5e
+        rv += 1; /* include \0 */
255e5e
+    }
255e5e
+
255e5e
+    return rv;
255e5e
+}
902636
diff --git a/slirp/src/util.h b/slirp/src/util.h
902636
index 3c6223c..0558dfc 100644
902636
--- a/slirp/src/util.h
902636
+++ b/slirp/src/util.h
902636
@@ -177,4 +177,7 @@ static inline int slirp_socket_set_fast_reuse(int fd)
902636
 
902636
 void slirp_pstrcpy(char *buf, int buf_size, const char *str);
902636
 
255e5e
+int slirp_fmt(char *str, size_t size, const char *format, ...);
255e5e
+int slirp_fmt0(char *str, size_t size, const char *format, ...);
902636
+
255e5e
 #endif
255e5e
-- 
255e5e
1.8.3.1
255e5e