All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7
@ 2022-05-08  9:31 Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 1/5] slirp: bump submodule past 4.7 release Paolo Bonzini
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Paolo Bonzini @ 2022-05-08  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, malureau

Content-Type: text/plain

Up until now, a CFI-enabled build would require slirp to be compiled as
a static library, using the version that is bundled together with QEMU.
This is because slirp registers functions as callbacks for QEMU Timers
and, when using a system-wide shared libslirp, the type information for
the callback is missing.  Thus, the timer call produces a false positive
with CFI.

slirp 4.7 introduces a new CFI-friendly timer callback that does not pass
function pointers within libslirp as callbacks for timers.  Check the
version number and, if it is new enough, allow using CFI even with a
system libslirp.

Supersedes: <20220412121337.207203-1-pbonzini@redhat.com>

Paolo

v1->v2: check for minimum slirp version (4.1), use config version 1


Paolo Bonzini (5):
  slirp: bump submodule past 4.7 release
  net: slirp: introduce a wrapper struct for QemuTimer
  net: slirp: switch to slirp_new
  net: slirp: add support for CFI-friendly timer API
  net: slirp: allow CFI with libslirp >= 4.7

 meson.build | 33 +++++++++++----------
 net/slirp.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++-------
 slirp       |  2 +-
 3 files changed, 93 insertions(+), 27 deletions(-)

-- 
2.35.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/5] slirp: bump submodule past 4.7 release
  2022-05-08  9:31 [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7 Paolo Bonzini
@ 2022-05-08  9:31 ` Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 2/5] net: slirp: introduce a wrapper struct for QemuTimer Paolo Bonzini
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2022-05-08  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, malureau

Version 4.7 of slirp provides a new timer API that works better with CFI,
together with several other improvements:

* Allow disabling the internal DHCP server !22
* Support Unix sockets in hostfwd !103
* IPv6 DNS proxying support !110
* bootp: add support for UEFI HTTP boot !111

and bugfixes.

The submodule update also includes 2 commits to fix warnings in the
Win32 build.

Reviewed-by: Marc-André Lureau <malureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 slirp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp b/slirp
index a88d9ace23..9d59bb775d 160000
--- a/slirp
+++ b/slirp
@@ -1 +1 @@
-Subproject commit a88d9ace234a24ce1c17189642ef9104799425e0
+Subproject commit 9d59bb775d6294c8b447a88512f7bb43f12a25a8
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/5] net: slirp: introduce a wrapper struct for QemuTimer
  2022-05-08  9:31 [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7 Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 1/5] slirp: bump submodule past 4.7 release Paolo Bonzini
@ 2022-05-08  9:31 ` Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 3/5] net: slirp: switch to slirp_new Paolo Bonzini
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2022-05-08  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, malureau, Samuel Thibault

This struct will be extended in the next few patches to support the
new slirp_handle_timer() call.  For that we need to store an additional
"int" for each SLIRP timer, in addition to the cb_opaque.

Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Marc-André Lureau <malureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 net/slirp.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index bc5e9e4f77..f1e25d741f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -184,23 +184,32 @@ static int64_t net_slirp_clock_get_ns(void *opaque)
     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
+struct SlirpTimer {
+    QEMUTimer timer;
+}
+
 static void *net_slirp_timer_new(SlirpTimerCb cb,
                                  void *cb_opaque, void *opaque)
 {
-    return timer_new_full(NULL, QEMU_CLOCK_VIRTUAL,
-                          SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
-                          cb, cb_opaque);
+    SlirpTimer *t = g_new(SlirpTimer, 1);
+    timer_init_full(&t->timer, NULL, QEMU_CLOCK_VIRTUAL,
+                    SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
+                    cb, cb_opaque);
+    return t;
 }
 
 static void net_slirp_timer_free(void *timer, void *opaque)
 {
-    timer_free(timer);
+    SlirpTimer *t = timer;
+    timer_del(&t->timer);
+    g_free(t);
 }
 
 static void net_slirp_timer_mod(void *timer, int64_t expire_timer,
                                 void *opaque)
 {
-    timer_mod(timer, expire_timer);
+    SlirpTimer *t = timer;
+    timer_mod(&t->timer, expire_timer);
 }
 
 static void net_slirp_register_poll_fd(int fd, void *opaque)
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/5] net: slirp: switch to slirp_new
  2022-05-08  9:31 [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7 Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 1/5] slirp: bump submodule past 4.7 release Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 2/5] net: slirp: introduce a wrapper struct for QemuTimer Paolo Bonzini
@ 2022-05-08  9:31 ` Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 4/5] net: slirp: add support for CFI-friendly timer API Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 5/5] net: slirp: allow CFI with libslirp >= 4.7 Paolo Bonzini
  4 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2022-05-08  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, malureau

Replace slirp_init with slirp_new, so that a more recent cfg.version
can be specified.  Only support version 3 of the configuration for
simplicity, corresponding to a minimum slirp version of 4.3.0.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 meson.build |  2 +-
 net/slirp.c | 27 +++++++++++++++++++++------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/meson.build b/meson.build
index 1712ea9e46..264a5fb5ed 100644
--- a/meson.build
+++ b/meson.build
@@ -2638,7 +2638,7 @@ if have_system
   if slirp_opt in ['enabled', 'auto', 'system']
     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
     slirp = dependency('slirp', kwargs: static_kwargs,
-                       method: 'pkg-config',
+                       method: 'pkg-config', version: '>=4.1.0',
                        required: slirp_opt == 'system' or
                                  slirp_opt == 'enabled' and not have_internal)
     if slirp.found()
diff --git a/net/slirp.c b/net/slirp.c
index f1e25d741f..b7464be86b 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -389,6 +389,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
 #if defined(CONFIG_SMBD_COMMAND)
     struct in_addr smbsrv = { .s_addr = 0 };
 #endif
+    SlirpConfig cfg = { 0 };
     NetClientState *nc;
     SlirpState *s;
     char buf[20];
@@ -577,12 +578,26 @@ static int net_slirp_init(NetClientState *peer, const char *model,
 
     s = DO_UPCAST(SlirpState, nc, nc);
 
-    s->slirp = slirp_init(restricted, ipv4, net, mask, host,
-                          ipv6, ip6_prefix, vprefix6_len, ip6_host,
-                          vhostname, tftp_server_name,
-                          tftp_export, bootfile, dhcp,
-                          dns, ip6_dns, dnssearch, vdomainname,
-                          &slirp_cb, s);
+    cfg.version = 1;
+    cfg.restricted = restricted;
+    cfg.in_enabled = ipv4;
+    cfg.vnetwork = net;
+    cfg.vnetmask = mask;
+    cfg.vhost = host;
+    cfg.in6_enabled = ipv6;
+    cfg.vprefix_addr6 = ip6_prefix;
+    cfg.vprefix_len = vprefix6_len;
+    cfg.vhost6 = ip6_host;
+    cfg.vhostname = vhostname;
+    cfg.tftp_server_name = tftp_server_name;
+    cfg.tftp_path = tftp_export;
+    cfg.bootfile = bootfile;
+    cfg.vdhcp_start = dhcp;
+    cfg.vnameserver = dns;
+    cfg.vnameserver6 = ip6_dns;
+    cfg.vdnssearch = dnssearch;
+    cfg.vdomainname = vdomainname;
+    s->slirp = slirp_new(&cfg, &slirp_cb, s);
     QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
 
     /*
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/5] net: slirp: add support for CFI-friendly timer API
  2022-05-08  9:31 [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2022-05-08  9:31 ` [PATCH v2 3/5] net: slirp: switch to slirp_new Paolo Bonzini
@ 2022-05-08  9:31 ` Paolo Bonzini
  2022-05-08  9:31 ` [PATCH v2 5/5] net: slirp: allow CFI with libslirp >= 4.7 Paolo Bonzini
  4 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2022-05-08  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, malureau, Samuel Thibault

libslirp 4.7 introduces a CFI-friendly version of the .timer_new callback.
The new callback replaces the function pointer with an enum; invoking the
callback is done with a new function slirp_handle_timer.

Support the new API so that CFI can be made compatible with using a system
libslirp.

Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Marc-André Lureau <malureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 net/slirp.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/net/slirp.c b/net/slirp.c
index b7464be86b..8679be6444 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -184,10 +184,43 @@ static int64_t net_slirp_clock_get_ns(void *opaque)
     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
+typedef struct SlirpTimer SlirpTimer;
 struct SlirpTimer {
     QEMUTimer timer;
+#if SLIRP_CHECK_VERSION(4,7,0)
+    Slirp *slirp;
+    SlirpTimerId id;
+    void *cb_opaque;
+#endif
+};
+
+#if SLIRP_CHECK_VERSION(4,7,0)
+static void net_slirp_init_completed(Slirp *slirp, void *opaque)
+{
+    SlirpState *s = opaque;
+    s->slirp = slirp;
 }
 
+static void net_slirp_timer_cb(void *opaque)
+{
+    SlirpTimer *t = opaque;
+    slirp_handle_timer(t->slirp, t->id, t->cb_opaque);
+}
+
+static void *net_slirp_timer_new_opaque(SlirpTimerId id,
+                                        void *cb_opaque, void *opaque)
+{
+    SlirpState *s = opaque;
+    SlirpTimer *t = g_new(SlirpTimer, 1);
+    t->slirp = s->slirp;
+    t->id = id;
+    t->cb_opaque = cb_opaque;
+    timer_init_full(&t->timer, NULL, QEMU_CLOCK_VIRTUAL,
+                    SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
+                    net_slirp_timer_cb, t);
+    return t;
+}
+#else
 static void *net_slirp_timer_new(SlirpTimerCb cb,
                                  void *cb_opaque, void *opaque)
 {
@@ -197,6 +230,7 @@ static void *net_slirp_timer_new(SlirpTimerCb cb,
                     cb, cb_opaque);
     return t;
 }
+#endif
 
 static void net_slirp_timer_free(void *timer, void *opaque)
 {
@@ -231,7 +265,12 @@ static const SlirpCb slirp_cb = {
     .send_packet = net_slirp_send_packet,
     .guest_error = net_slirp_guest_error,
     .clock_get_ns = net_slirp_clock_get_ns,
+#if SLIRP_CHECK_VERSION(4,7,0)
+    .init_completed = net_slirp_init_completed,
+    .timer_new_opaque = net_slirp_timer_new_opaque,
+#else
     .timer_new = net_slirp_timer_new,
+#endif
     .timer_free = net_slirp_timer_free,
     .timer_mod = net_slirp_timer_mod,
     .register_poll_fd = net_slirp_register_poll_fd,
@@ -578,7 +617,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
 
     s = DO_UPCAST(SlirpState, nc, nc);
 
-    cfg.version = 1;
+    cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 1;
     cfg.restricted = restricted;
     cfg.in_enabled = ipv4;
     cfg.vnetwork = net;
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 5/5] net: slirp: allow CFI with libslirp >= 4.7
  2022-05-08  9:31 [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2022-05-08  9:31 ` [PATCH v2 4/5] net: slirp: add support for CFI-friendly timer API Paolo Bonzini
@ 2022-05-08  9:31 ` Paolo Bonzini
  4 siblings, 0 replies; 6+ messages in thread
From: Paolo Bonzini @ 2022-05-08  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: berrange, malureau, Samuel Thibault

slirp 4.7 introduces a new CFI-friendly timer callback that does
not pass function pointers within libslirp as callbacks for timers.
Check the version number and, if it is new enough, allow using CFI
even with a system libslirp.

Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Marc-André Lureau <malureau@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 meson.build | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/meson.build b/meson.build
index 264a5fb5ed..59ca709078 100644
--- a/meson.build
+++ b/meson.build
@@ -2637,10 +2637,25 @@ if have_system
   slirp_opt = get_option('slirp')
   if slirp_opt in ['enabled', 'auto', 'system']
     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
+    slirp_dep_required = (slirp_opt == 'system' or
+                          slirp_opt == 'enabled' and not have_internal)
     slirp = dependency('slirp', kwargs: static_kwargs,
                        method: 'pkg-config', version: '>=4.1.0',
-                       required: slirp_opt == 'system' or
-                                 slirp_opt == 'enabled' and not have_internal)
+                       required: slirp_dep_required)
+    # slirp <4.7 is incompatible with CFI support in QEMU.  This is because
+    # it passes function pointers within libslirp as callbacks for timers.
+    # When using a system-wide shared libslirp, the type information for the
+    # callback is missing and the timer call produces a false positive with CFI.
+    # Do not use the "version" keyword argument to produce a better error.
+    # with control-flow integrity.
+    if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
+      if slirp_dep_required
+        error('Control-Flow Integrity requires libslirp 4.7.')
+      else
+        warning('Control-Flow Integrity requires libslirp 4.7, not using system-wide libslirp.')
+        slirp = not_found
+      endif
+    endif
     if slirp.found()
       slirp_opt = 'system'
     elif have_internal
@@ -2713,18 +2728,6 @@ if have_system
   endif
 endif
 
-# For CFI, we need to compile slirp as a static library together with qemu.
-# This is because we register slirp functions as callbacks for QEMU Timers.
-# When using a system-wide shared libslirp, the type information for the
-# callback is missing and the timer call produces a false positive with CFI.
-#
-# Now that slirp_opt has been defined, check if the selected slirp is compatible
-# with control-flow integrity.
-if get_option('cfi') and slirp_opt == 'system'
-  error('Control-Flow Integrity is not compatible with system-wide slirp.' \
-         + ' Please configure with --enable-slirp=git')
-endif
-
 fdt = not_found
 if have_system
   fdt_opt = get_option('fdt')
-- 
2.35.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-08  9:37 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-08  9:31 [PATCH v2 0/5] net: support for CFI with libslirp >= 4.7 Paolo Bonzini
2022-05-08  9:31 ` [PATCH v2 1/5] slirp: bump submodule past 4.7 release Paolo Bonzini
2022-05-08  9:31 ` [PATCH v2 2/5] net: slirp: introduce a wrapper struct for QemuTimer Paolo Bonzini
2022-05-08  9:31 ` [PATCH v2 3/5] net: slirp: switch to slirp_new Paolo Bonzini
2022-05-08  9:31 ` [PATCH v2 4/5] net: slirp: add support for CFI-friendly timer API Paolo Bonzini
2022-05-08  9:31 ` [PATCH v2 5/5] net: slirp: allow CFI with libslirp >= 4.7 Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.