Blame SOURCES/kvm-util-add-slirp_fmt-helpers.patch

e3b251
From 8f130c9462750f2ec8205b0749ecd64b799144b5 Mon Sep 17 00:00:00 2001
e3b251
From: jmaloy <jmaloy@redhat.com>
e3b251
Date: Wed, 19 Feb 2020 16:29:22 +0100
e3b251
Subject: [PATCH 1/2] util: add slirp_fmt() helpers
e3b251
MIME-Version: 1.0
e3b251
Content-Type: text/plain; charset=UTF-8
e3b251
Content-Transfer-Encoding: 8bit
e3b251
e3b251
Message-id: <20200219162923.18327-2-jmaloy@redhat.com>
e3b251
Patchwork-id: 93976
e3b251
O-Subject: [RHEL-7.8 qemu-kvm-rhev PATCH v2 1/2] util: add slirp_fmt() helpers
e3b251
Bugzilla: 1798974
e3b251
RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
e3b251
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
e3b251
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
e3b251
e3b251
From: Marc-André Lureau <marcandre.lureau@redhat.com>
e3b251
e3b251
Various calls to snprintf() in libslirp assume that snprintf() returns
e3b251
"only" the number of bytes written (excluding terminating NUL).
e3b251
e3b251
https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html#tag_16_159_04
e3b251
e3b251
"Upon successful completion, the snprintf() function shall return the
e3b251
number of bytes that would be written to s had n been sufficiently
e3b251
large excluding the terminating null byte."
e3b251
e3b251
Introduce slirp_fmt() that handles several pathological cases the
e3b251
way libslirp usually expect:
e3b251
e3b251
- treat error as fatal (instead of silently returning -1)
e3b251
e3b251
- fmt0() will always \0 end
e3b251
e3b251
- return the number of bytes actually written (instead of what would
e3b251
  have been written, which would usually result in OOB later), including
e3b251
  the ending \0 for fmt0()
e3b251
e3b251
- warn if truncation happened (instead of ignoring)
e3b251
e3b251
  Other less common cases can still be handled with strcpy/snprintf() etc.
e3b251
e3b251
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
e3b251
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
e3b251
Message-Id: <20200127092414.169796-2-marcandre.lureau@redhat.com>
e3b251
e3b251
(cherry picked from libslirp commit 30648c03b27fb8d9611b723184216cd3174b6775)
e3b251
e3b251
Manually re-adapted, since there is no util.c file in this code version.
e3b251
We add the two functions as static functions in the file where they
e3b251
are going to be used.
e3b251
e3b251
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
e3b251
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
e3b251
---
e3b251
 slirp/tcp_subr.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
e3b251
 1 file changed, 65 insertions(+)
e3b251
e3b251
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
e3b251
index b95ba23..c5196a4 100644
e3b251
--- a/slirp/tcp_subr.c
e3b251
+++ b/slirp/tcp_subr.c
e3b251
@@ -45,6 +45,9 @@
e3b251
 /* Don't do rfc1323 performance enhancements */
e3b251
 #define TCP_DO_RFC1323 0
e3b251
 
e3b251
+static int slirp_fmt(char *str, size_t size, const char *format, ...);
e3b251
+static int slirp_fmt0(char *str, size_t size, const char *format, ...);
e3b251
+
e3b251
 /*
e3b251
  * Tcp initialization
e3b251
  */
e3b251
@@ -990,3 +993,65 @@ int tcp_ctl(struct socket *so)
e3b251
     sb->sb_wptr += sb->sb_cc;
e3b251
     return 0;
e3b251
 }
e3b251
+
e3b251
+static int slirp_vsnprintf(char *str, size_t size,
e3b251
+                           const char *format, va_list args)
e3b251
+{
e3b251
+    int rv = vsnprintf(str, size, format, args);
e3b251
+
e3b251
+    if (rv < 0) {
e3b251
+        g_error("vsnprintf() failed: %s", g_strerror(errno));
e3b251
+    }
e3b251
+
e3b251
+    return rv;
e3b251
+}
e3b251
+
e3b251
+/*
e3b251
+ * A snprintf()-like function that:
e3b251
+ * - returns the number of bytes written (excluding optional \0-ending)
e3b251
+ * - dies on error
e3b251
+ * - warn on truncation
e3b251
+ */
e3b251
+static int slirp_fmt(char *str, size_t size, const char *format, ...)
e3b251
+{
e3b251
+    va_list args;
e3b251
+    int rv;
e3b251
+
e3b251
+    va_start(args, format);
e3b251
+    rv = slirp_vsnprintf(str, size, format, args);
e3b251
+    va_end(args);
e3b251
+
e3b251
+    if (rv > size) {
e3b251
+        g_critical("vsnprintf() truncation");
e3b251
+    }
e3b251
+
e3b251
+    return MIN(rv, size);
e3b251
+}
e3b251
+
e3b251
+/*
e3b251
+ * A snprintf()-like function that:
e3b251
+ * - always \0-end (unless size == 0)
e3b251
+ * - returns the number of bytes actually written, including \0 ending
e3b251
+ * - dies on error
e3b251
+ * - warn on truncation
e3b251
+ */
e3b251
+static int slirp_fmt0(char *str, size_t size, const char *format, ...)
e3b251
+{
e3b251
+    va_list args;
e3b251
+    int rv;
e3b251
+
e3b251
+    va_start(args, format);
e3b251
+    rv = slirp_vsnprintf(str, size, format, args);
e3b251
+    va_end(args);
e3b251
+
e3b251
+    if (rv >= size) {
e3b251
+        g_critical("vsnprintf() truncation");
e3b251
+        if (size > 0)
e3b251
+            str[size - 1] = '\0';
e3b251
+        rv = size;
e3b251
+    } else {
e3b251
+        rv += 1; /* include \0 */
e3b251
+    }
e3b251
+
e3b251
+    return rv;
e3b251
+}
e3b251
-- 
e3b251
1.8.3.1
e3b251