new file mode 100644
@@ -0,0 +1,122 @@
+From 927bca7344e31fd58e2f7afaca784aad4400eb84 Mon Sep 17 00:00:00 2001
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Date: Sat, 23 May 2026 22:06:59 +0200
+Subject: [PATCH] oob: cap urgent data count to what is actually available
+
+so_urgc is provided by the guest sender, so can arbitrary and beyond
+what we actually have. Worse, this can lead to an sb_cc integer
+underflow leading to leaking gigabytes of data.
+
+Fixes #93
+
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+CVE: CVE-2026-9539
+Upstream-Status: Backport [https://gitlab.freedesktop.org/slirp/libslirp/-/commit/927bca7344e31fd58e2f7afaca784aad4400eb84]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ src/socket.c | 40 +++++++++++++++++++++++-----------------
+ 1 file changed, 23 insertions(+), 17 deletions(-)
+
+diff --git a/src/socket.c b/src/socket.c
+index 77c5cf6..c491d0f 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -337,7 +337,8 @@ int sorecvoob(struct socket *so)
+ int sosendoob(struct socket *so)
+ {
+ struct sbuf *sb = &so->so_rcv;
+- char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
++ uint32_t urgc = so->so_urgc;
++ char buff[2048];
+
+ int n;
+
+@@ -345,12 +346,15 @@ int sosendoob(struct socket *so)
+ DEBUG_ARG("so = %p", so);
+ DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
+
+- if (so->so_urgc > sizeof(buff))
+- so->so_urgc = sizeof(buff); /* XXXX */
++ if (urgc > sizeof(buff))
++ urgc = sizeof(buff);
++
++ if (urgc > sb->sb_cc)
++ urgc = sb->sb_cc;
+
+ if (sb->sb_rptr < sb->sb_wptr) {
+ /* We can send it directly */
+- n = slirp_send(so, sb->sb_rptr, so->so_urgc,
++ n = slirp_send(so, sb->sb_rptr, urgc,
+ (MSG_OOB)); /* |MSG_DONTWAIT)); */
+ } else {
+ /*
+@@ -358,7 +362,6 @@ int sosendoob(struct socket *so)
+ * we must copy all data to a linear buffer then
+ * send it all
+ */
+- uint32_t urgc = so->so_urgc; /* Amount of room left in buff */
+ int len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
+ if (len > urgc) {
+ len = urgc;
+@@ -403,7 +406,7 @@ int sosendoob(struct socket *so)
+ */
+ int sowrite(struct socket *so)
+ {
+- int n, nn;
++ int n, nn, noob = 0;
+ struct sbuf *sb = &so->so_rcv;
+ int len = sb->sb_cc;
+ struct iovec iov[2];
+@@ -413,16 +416,20 @@ int sowrite(struct socket *so)
+
+ if (so->so_urgc) {
+ uint32_t expected = so->so_urgc;
+- if (sosendoob(so) < expected) {
+- /* Treat a short write as a fatal error too,
+- * rather than continuing on and sending the urgent
+- * data as if it were non-urgent and leaving the
+- * so_urgc count wrong.
+- */
++ int noob = sosendoob(so);
++
++ if (noob <= 0)
+ goto err_disconnected;
+- }
++
++ if (noob < expected)
++ /* Short write: either we have not yet received all
++ * urgent data, or the socket buffers are full. Leave
++ * it for later when we have data or have room. */
++ return noob;
++
+ if (sb->sb_cc == 0)
+- return 0;
++ /* Nothing left to write actually */
++ return noob;
+ }
+
+ /*
+@@ -453,12 +460,11 @@ int sowrite(struct socket *so)
+ } else
+ n = 1;
+ }
+- /* Check if there's urgent data to send, and if so, send it */
+
+ nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len, 0);
+ /* This should never happen, but people tell me it does *shrug* */
+ if (nn < 0 && (errno == EAGAIN || errno == EINTR))
+- return 0;
++ return noob;
+
+ if (nn <= 0) {
+ goto err_disconnected;
+@@ -485,7 +491,7 @@ int sowrite(struct socket *so)
+ if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
+ sofcantsendmore(so);
+
+- return nn;
++ return noob + nn;
+
+ err_disconnected:
+ DEBUG_MISC(" --- sowrite disconnected, so->so_state = %x, errno = %d",
@@ -4,7 +4,10 @@ HOMEPAGE = "https://gitlab.freedesktop.org/slirp/libslirp"
LICENSE = "BSD-3-Clause & MIT"
LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=bca0186b14e6b05e338e729f106db727"
-SRC_URI = "git://gitlab.freedesktop.org/slirp/libslirp.git;protocol=https;branch=master"
+SRC_URI = "\
+ git://gitlab.freedesktop.org/slirp/libslirp.git;protocol=https;branch=master \
+ file://CVE-2026-9539.patch \
+"
SRCREV = "3ad1710a96678fe79066b1469cead4058713a1d9"
PV = "4.7.0"
S = "${WORKDIR}/git"