[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1118374: marked as done (trixie-pu: package libsmb2/6.2+dfsg-2+deb13u1)



Your message dated Sat, 15 Nov 2025 11:21:45 +0000
with message-id <736c7150dc08501cc89945035c406eaf9688e144.camel@adam-barratt.org.uk>
and subject line Closing requests for updates included in 13.2
has caused the Debian Bug report #1118374,
regarding trixie-pu: package libsmb2/6.2+dfsg-2+deb13u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1118374: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1118374
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Subject: trixie-pu: package libsmb2/6.2+dfsg-2+deb13u1
Package: release.debian.org
Control: affects -1 + src:libsmb2
X-Debbugs-Cc: libsmb2@packages.debian.org
User: release.debian.org@packages.debian.org
Usertags: pu
Tags: trixie
Severity: normal

[ Reason ]
The reason is to fix CVE-2025-57632 [1], When processing SMB2 chained
PDUs (NextCommand), libsmb2 repeatedly calls smb2_add_iovector() to
append to a fixed-size iovec array without checking the upper bound
of v->niov (SMB2_MAX_VECTORS=256).
Bug: #1116446

[ Impact ]
The vulnerabilities in libsmb2 in trixie can be exploited by attackers,
potentially compromising secure connections or causing access failures.

[ Tests ]
In a controlled environment, use the library to connect to a malicious
SMB server that sends chained PDUs. The library should handle the
malicious message without crashing, unlike the vulnerable version

[ Risks ]
The risk of not applying this fix is high. The vulnerability allows
an attacker to cause a denial-of-service (DoS) or execute arbitrary
code, which could fully compromise the system.

[ Checklist ]
  [X] *all* changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in (old)stable
  [X] the issue is verified as fixed in unstable

[ Changes ]
Buffer Overflow Fix: A bounds check (v->niov >= SMB2_MAX_VECTORS)
was added to the smb2_add_iovector() function to prevent an
attacker from overwriting memory.

[ Other info  ]
@samueloph has reviewed this backport and will sponsor it.

[1] https://security-tracker.debian.org/tracker/CVE-2025-57632
-- 
Thanks,
Polkorny
diff -Nru libsmb2-6.2+dfsg/debian/changelog libsmb2-6.2+dfsg/debian/changelog
--- libsmb2-6.2+dfsg/debian/changelog	2025-04-03 15:20:58.000000000 -0300
+++ libsmb2-6.2+dfsg/debian/changelog	2025-10-17 20:26:34.000000000 -0300
@@ -1,3 +1,18 @@
+libsmb2 (6.2+dfsg-2+deb13u1) trixie; urgency=medium
+
+  * Import upstream patches to fix CVE-2025-57632
+    - When processing SMB2 chained PDUs (NextCommand), libsmb2
+      repeatedly calls smb2_add_iovector() to append to a
+      fixed-size iovec array without checking the upper bound
+      of v->niov (SMB2_MAX_VECTORS=256)
+  * d/p/CVE-2025-57632-pt*.patch: Import upstream patches to fix CVE
+  * d/p/CVE-2025-57632-pt2.patch: Backport patch and Update hunks' offsets
+  * d/p/CVE-2025-57632-pt3.patch: Backport patch and Update hunks' offsets
+  * d/p/CVE-2025-57632-pt4.patch: Backport patch and Change hunk to
+    reflect new code indentation
+
+ -- Matheus Polkorny <mpolkorny@gmail.com>  Fri, 17 Oct 2025 20:26:34 -0300
+
 libsmb2 (6.2+dfsg-2) unstable; urgency=medium
 
   * d/control: Bump Standards-Version to 4.7.2 (no changes)
diff -Nru libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt1.patch libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt1.patch
--- libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt1.patch	1969-12-31 21:00:00.000000000 -0300
+++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt1.patch	2025-10-17 20:26:34.000000000 -0300
@@ -0,0 +1,36 @@
+From 5e75eebf922b338cdb548d60cffb3b997d2a12e8 Mon Sep 17 00:00:00 2001
+From: ZjW1nd <zj_w1nd@qq.com>
+Date: Mon, 18 Aug 2025 10:26:17 +0800
+Subject: [PATCH 1/4] [Security]: fix OOB write in smb2_add_iovector via
+ chained PDUs
+Origin: upstream, https://github.com/sahlberg/libsmb2/commit/5e75eebf922b338cdb548d60cffb3b997d2a12e8
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1116446
+
+Root cause: missing bounds check for v->niov against SMB2_MAX_VECTORS (256).
+Trigger: a malicious server can chain PDUs (OPLOCK_BREAK bypasses message_id checks) to repeatedly append iovecs until niov overflows.
+Impact: heap corruption, crash, potential RCE on client.
+Fix: add upper-bound check in smb2_add_iovector() and return the last iovec on overflow.
+---
+ lib/init.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/lib/init.c b/lib/init.c
+index 6ba86dc..07f2d16 100644
+--- a/lib/init.c
++++ b/lib/init.c
+@@ -431,7 +431,11 @@ struct smb2_iovec *smb2_add_iovector(struct smb2_context *smb2,
+                                      void (*free)(void *))
+ {
+         struct smb2_iovec *iov = &v->iov[v->niov];
+-
++        // Add bounds checking
++        if (v->niov >= SMB2_MAX_VECTORS) {
++            smb2_set_error(smb2, "Too many I/O vectors");
++            return (struct smb2_iovec*) &v->iov[SMB2_MAX_VECTORS - 1]; // We dont return NULL to prevent null point deref.
++        }                                                              // I chose the simplest solution here, it can be treated more elegantly.
+         v->iov[v->niov].buf = buf;
+         v->iov[v->niov].len = len;
+         v->iov[v->niov].free = free;
+-- 
+2.51.0
+
diff -Nru libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt2.patch libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt2.patch
--- libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt2.patch	1969-12-31 21:00:00.000000000 -0300
+++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt2.patch	2025-10-17 20:26:34.000000000 -0300
@@ -0,0 +1,65 @@
+From 70754b01fb272604e90f8b886ec4ff73ca6ab38f Mon Sep 17 00:00:00 2001
+From: ZjW1nd <zj_w1nd@qq.com>
+Date: Mon, 18 Aug 2025 10:47:55 +0800
+Subject: [PATCH 2/4] [Security]: fix NULL deref on alloc failure in
+ dcerpc_bind_async
+Origin: upstream, https://github.com/sahlberg/libsmb2/commit/70754b01fb272604e90f8b886ec4ff73ca6ab38f
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1116446
+
+Root cause: unchecked smb2_alloc_data results for p_cont_elem and transfer_syntaxes could be NULL.
+Trigger: low-memory or crafted conditions causing allocator to return NULL; code then writes to transfer_syntaxes[0].
+Impact: client crash (DoS) due to NULL pointer dereference.
+Fix: guard all allocations in dcerpc_bind_async; on failure set error, free PDU, and return -ENOMEM; avoid invoking callbacks before initialization.
+
+Backported by: Matheus Polkorny <mpolkorny@gmail.com>
+
+Changes:
+
+- Update hunks' offsets.
+---
+ lib/dcerpc.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/lib/dcerpc.c b/lib/dcerpc.c
+index d0be632..a0c6174 100644
+--- a/lib/dcerpc.c
++++ b/lib/dcerpc.c
+@@ -1756,6 +1756,11 @@ dcerpc_bind_async(struct dcerpc_context *dce, dcerpc_cb cb,
+         pdu->bind.n_context_elem = dce->smb2->ndr ? 1 : 2;
+         pdu->bind.p_cont_elem = smb2_alloc_data(dce->smb2, pdu->payload,
+                      pdu->bind.n_context_elem * sizeof(struct p_cont_elem_t));
++        if (pdu->bind.p_cont_elem == NULL) {
++                smb2_set_error(dce->smb2, "Failed to allocate p_cont_elem");
++                dcerpc_free_pdu(dce, pdu);
++                return -ENOMEM;
++        }
+         pce = pdu->bind.p_cont_elem;
+         if (dce->smb2->ndr == 0 || dce->smb2->ndr == 1) {
+                 pce->p_cont_id = 0;
+@@ -1764,6 +1769,11 @@ dcerpc_bind_async(struct dcerpc_context *dce, dcerpc_cb cb,
+                 pce->transfer_syntaxes = smb2_alloc_data(
+                      dce->smb2, pdu->payload,
+                      pce->n_transfer_syn * sizeof(struct p_cont_elem_t *));
++                if (pce->transfer_syntaxes == NULL) {
++                        smb2_set_error(dce->smb2, "Failed to allocate transfer_syntaxes");
++                        dcerpc_free_pdu(dce, pdu);
++                        return -ENOMEM;
++                }
+                 pce->transfer_syntaxes[0] = &ndr32_syntax;
+                 pce++;
+         }
+@@ -1774,6 +1784,11 @@ dcerpc_bind_async(struct dcerpc_context *dce, dcerpc_cb cb,
+                 pce->transfer_syntaxes = smb2_alloc_data(
+                      dce->smb2, pdu->payload,
+                      pce->n_transfer_syn * sizeof(struct p_cont_elem_t *));
++                if (pce->transfer_syntaxes == NULL) {
++                        smb2_set_error(dce->smb2, "Failed to allocate transfer_syntaxes");
++                        dcerpc_free_pdu(dce, pdu);
++                        return -ENOMEM;
++                }
+                 pce->transfer_syntaxes[0] = &ndr64_syntax;
+         }
+ 
+-- 
+2.51.0
+
diff -Nru libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt3.patch libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt3.patch
--- libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt3.patch	1969-12-31 21:00:00.000000000 -0300
+++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt3.patch	2025-10-17 20:26:34.000000000 -0300
@@ -0,0 +1,38 @@
+From d0801c5cdb847339b881447087216628a7a4ebe4 Mon Sep 17 00:00:00 2001
+From: ZjW1nd <zj_w1nd@qq.com>
+Date: Mon, 18 Aug 2025 10:53:55 +0800
+Subject: [PATCH 3/4] [Security]: fix off-by-one OOB write in compat strdup
+Origin: upstream, https://github.com/sahlberg/libsmb2/commit/d0801c5cdb847339b881447087216628a7a4ebe4
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1116446
+
+Root cause: memcpy used len+1 while len already included the NUL terminator.
+Trigger: calling compat strdup with any input string; over-copies by 1 byte.
+Impact: 1-byte heap overflow -> potential heap corruption/crash (client-side).
+Fix: copy exactly len bytes (which includes the NUL) after allocating len bytes
+
+Backported by: Matheus Polkorny <mpolkorny@gmail.com>
+
+Changes:
+
+- Update hunks' offsets.
+---
+ lib/compat.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/compat.c b/lib/compat.c
+index b99606b..651d031 100644
+--- a/lib/compat.c
++++ b/lib/compat.c
+@@ -580,7 +580,8 @@ char *strdup(const char *s)
+ #endif /* !_IOP */
+                 return NULL;
+         }
+-        memcpy(str, s, len + 1);
++        /* len already includes the NULL terminator */
++        memcpy(str, s, len);
+         return str;
+ }
+ #endif /* NEED_STRDUP */
+-- 
+2.51.0
+
diff -Nru libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt4.patch libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt4.patch
--- libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt4.patch	1969-12-31 21:00:00.000000000 -0300
+++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt4.patch	2025-10-17 20:26:34.000000000 -0300
@@ -0,0 +1,1146 @@
+From 883e787426df52dd19206234d7278d46ac997668 Mon Sep 17 00:00:00 2001
+From: ZjW1nd <zj_w1nd@qq.com>
+Date: Mon, 18 Aug 2025 14:29:10 +0800
+Subject: [PATCH 4/4] [Security]: Enforce NULL-checks for smb2_add_iovector.
+Origin: upstream, https://github.com/sahlberg/libsmb2/commit/883e787426df52dd19206234d7278d46ac997668
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1116446
+
+This is a better fix for the previous 2 commit. And I also add malloc return value check in smb2_read_data to prevent Null deref.
+
+Backported by: Matheus Polkorny <mpolkorny@gmail.com>
+
+Changes:
+
+- Change hunk to reflect new code indentation.
+---
+ lib/init.c                     |  32 +++++++-----
+ lib/pdu.c                      |  12 +++--
+ lib/smb2-cmd-close.c           |   8 +++
+ lib/smb2-cmd-create.c          |  24 +++++++++
+ lib/smb2-cmd-echo.c            |   8 +++
+ lib/smb2-cmd-error.c           |   4 ++
+ lib/smb2-cmd-flush.c           |   7 +++
+ lib/smb2-cmd-ioctl.c           |  12 +++++
+ lib/smb2-cmd-lock.c            |  12 +++++
+ lib/smb2-cmd-logoff.c          |   8 +++
+ lib/smb2-cmd-negotiate.c       |  22 ++++++--
+ lib/smb2-cmd-notify-change.c   |  12 +++++
+ lib/smb2-cmd-oplock-break.c    |  24 +++++++++
+ lib/smb2-cmd-query-directory.c |  13 +++++
+ lib/smb2-cmd-query-info.c      |  12 +++++
+ lib/smb2-cmd-read.c            |  23 +++++++--
+ lib/smb2-cmd-session-setup.c   |  16 ++++++
+ lib/smb2-cmd-set-info.c        |  31 ++++++++++-
+ lib/smb2-cmd-tree-connect.c    |  12 +++++
+ lib/smb2-cmd-tree-disconnect.c |   8 +++
+ lib/smb2-cmd-write.c           |  16 +++++-
+ lib/smb3-seal.c                |   9 +++-
+ lib/socket.c                   | 114 +++++++++++++++++++++++++++++++----------
+ 23 files changed, 385 insertions(+), 54 deletions(-)
+
+diff --git a/lib/init.c b/lib/init.c
+index 7269e43..fc0f2a1 100644
+--- a/lib/init.c
++++ b/lib/init.c
+@@ -426,19 +426,25 @@ void smb2_free_iovector(struct smb2_context *smb2, struct smb2_io_vectors *v)
+ }
+ 
+ struct smb2_iovec *smb2_add_iovector(struct smb2_context *smb2,
+-                                     struct smb2_io_vectors *v,
+-                                     uint8_t *buf, size_t len,
+-                                     void (*free)(void *))
+-{
+-        struct smb2_iovec *iov = &v->iov[v->niov];
+-        // Add bounds checking
+-        if (v->niov >= SMB2_MAX_VECTORS) {
+-            smb2_set_error(smb2, "Too many I/O vectors");
+-            return (struct smb2_iovec*) &v->iov[SMB2_MAX_VECTORS - 1]; // We dont return NULL to prevent null point deref.
+-        }                                                              // I chose the simplest solution here, it can be treated more elegantly.
+-        v->iov[v->niov].buf = buf;
+-        v->iov[v->niov].len = len;
+-        v->iov[v->niov].free = free;
++                                    struct smb2_io_vectors *v,
++                                    uint8_t *buf, size_t len,
++                                    void (*free_cb)(void *))
++{
++                struct smb2_iovec *iov;
++                /* Bounds checking */
++                if (v->niov >= SMB2_MAX_VECTORS) {
++                        smb2_set_error(smb2, "Too many I/O vectors");
++                        /* Avoid leaks for caller-provided buffers */
++                        if (free_cb && buf) {
++                                free_cb(buf);
++                        }
++                        return NULL;
++                }
++
++                iov = &v->iov[v->niov];
++                v->iov[v->niov].buf = buf;
++                v->iov[v->niov].len = len;
++                v->iov[v->niov].free = free_cb;
+         v->total_size += len;
+         v->niov++;
+ 
+diff --git a/lib/pdu.c b/lib/pdu.c
+index 573dc86..ddeae2f 100644
+--- a/lib/pdu.c
++++ b/lib/pdu.c
+@@ -70,8 +70,10 @@ smb2_pad_to_64bit(struct smb2_context *smb2, struct smb2_io_vectors *v)
+         if ((len & 0x07) == 0) {
+                 return 0;
+         }
+-        if (smb2_add_iovector(smb2, v, &zero_bytes[0], 8 - (len & 0x07), NULL)
+-            == NULL) {
++        if (smb2_add_iovector(smb2, v, 
++                        &zero_bytes[0], 
++                        8 - (len & 0x07), NULL)
++                        == NULL) {
+                 return -1;
+         }
+ 
+@@ -153,7 +155,11 @@ smb2_allocate_pdu(struct smb2_context *smb2, enum smb2_command command,
+         pdu->cb_data = cb_data;
+         pdu->out.niov = 0;
+ 
+-        smb2_add_iovector(smb2, &pdu->out, pdu->hdr, SMB2_HEADER_SIZE, NULL);
++        if (smb2_add_iovector(smb2, &pdu->out, pdu->hdr, SMB2_HEADER_SIZE, NULL) == NULL) {
++                free(pdu);
++                smb2_set_error(smb2, "Too many I/O vectors when adding SMB2 header");
++                return NULL;
++        }
+ 
+         switch (command) {
+         case SMB2_NEGOTIATE:
+diff --git a/lib/smb2-cmd-close.c b/lib/smb2-cmd-close.c
+index fb2996e..41ddf0e 100644
+--- a/lib/smb2-cmd-close.c
++++ b/lib/smb2-cmd-close.c
+@@ -72,6 +72,10 @@ smb2_encode_close_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for close request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_CLOSE_REQUEST_SIZE);
+         smb2_set_uint16(iov, 2, req->flags);
+@@ -122,6 +126,10 @@ smb2_encode_close_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for close reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_CLOSE_REPLY_SIZE);
+         smb2_set_uint16(iov, 2, rep->flags);
+diff --git a/lib/smb2-cmd-create.c b/lib/smb2-cmd-create.c
+index 4991ed8..58a3e6f 100644
+--- a/lib/smb2-cmd-create.c
++++ b/lib/smb2-cmd-create.c
+@@ -77,6 +77,10 @@ smb2_encode_create_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for create request");
++                return -1;
++        }
+ 
+         /* Name */
+         if (req->name && req->name[0]) {
+@@ -134,6 +138,10 @@ smb2_encode_create_request(struct smb2_context *smb2,
+                                         buf,
+                                         len,
+                                         free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for create name");
++                        return -1;
++                }
+                 /* Convert '/' to '\' */
+                 for (i = 0; i < name->len; i++) {
+                         smb2_get_uint16(iov, i * 2, &ch);
+@@ -150,6 +158,10 @@ smb2_encode_create_request(struct smb2_context *smb2,
+                 static uint8_t zero[8];
+                 iov = smb2_add_iovector(smb2, &pdu->out,
+                                                 zero, 8, NULL);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for create empty name padding");
++                        return -1;
++                }
+         }
+         /* Create Context: note there is no encoding, we just pass along */
+         if (req->create_context_length) {
+@@ -165,6 +177,10 @@ smb2_encode_create_request(struct smb2_context *smb2,
+                                         buf,
+                                         len,
+                                         free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for create context");
++                        return -1;
++                }
+         }
+ 
+         return 0;
+@@ -212,6 +228,10 @@ smb2_encode_create_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for create reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_CREATE_REPLY_SIZE);
+         smb2_set_uint8(iov, 2, rep->oplock_level);
+@@ -243,6 +263,10 @@ smb2_encode_create_reply(struct smb2_context *smb2,
+                                         buf,
+                                         len,
+                                         free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for create reply context");
++                        return -1;
++                }
+         }
+ 
+         return 0;
+diff --git a/lib/smb2-cmd-echo.c b/lib/smb2-cmd-echo.c
+index 68669a5..32571fc 100644
+--- a/lib/smb2-cmd-echo.c
++++ b/lib/smb2-cmd-echo.c
+@@ -70,6 +70,10 @@ smb2_encode_echo_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for echo request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_ECHO_REQUEST_SIZE);
+ 
+@@ -117,6 +121,10 @@ smb2_encode_echo_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for echo reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_ECHO_REPLY_SIZE);
+         return 0;
+diff --git a/lib/smb2-cmd-error.c b/lib/smb2-cmd-error.c
+index ed798e3..de8d6b2 100644
+--- a/lib/smb2-cmd-error.c
++++ b/lib/smb2-cmd-error.c
+@@ -72,6 +72,10 @@ smb2_encode_error_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for error reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_ERROR_REPLY_SIZE);
+         smb2_set_uint8(iov, 2, rep->error_context_count);
+diff --git a/lib/smb2-cmd-flush.c b/lib/smb2-cmd-flush.c
+index 9f1597d..c5da6ad 100644
+--- a/lib/smb2-cmd-flush.c
++++ b/lib/smb2-cmd-flush.c
+@@ -72,6 +72,10 @@ smb2_encode_flush_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                /* buf freed by add_iovector on failure */
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_FLUSH_REQUEST_SIZE);
+         memcpy(iov->buf + 8, req->file_id, SMB2_FD_SIZE);
+@@ -120,6 +124,9 @@ smb2_encode_flush_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_FLUSH_REPLY_SIZE);
+ 
+diff --git a/lib/smb2-cmd-ioctl.c b/lib/smb2-cmd-ioctl.c
+index b6a2f3f..fa19d59 100644
+--- a/lib/smb2-cmd-ioctl.c
++++ b/lib/smb2-cmd-ioctl.c
+@@ -72,6 +72,9 @@ smb2_encode_ioctl_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_IOCTL_REQUEST_SIZE);
+         smb2_set_uint32(iov, 4, req->ctl_code);
+@@ -86,6 +89,9 @@ smb2_encode_ioctl_request(struct smb2_context *smb2,
+         if (req->input_count) {
+                 iov = smb2_add_iovector(smb2, &pdu->out, req->input,
+                                         req->input_count, NULL);
++                if (iov == NULL) {
++                        return -1;
++                }
+         }
+ 
+         return 0;
+@@ -133,6 +139,9 @@ smb2_encode_ioctl_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         ioctlv = NULL;
+         if (rep->output_count) {
+@@ -161,6 +170,9 @@ smb2_encode_ioctl_reply(struct smb2_context *smb2,
+                 }
+                 memset(buf, 0, rep->output_count);
+                 ioctlv = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++                if (ioctlv == NULL) {
++                        return -1;
++                }
+ 
+                 switch (rep->ctl_code) {
+                 case SMB2_FSCTL_VALIDATE_NEGOTIATE_INFO:
+diff --git a/lib/smb2-cmd-lock.c b/lib/smb2-cmd-lock.c
+index 61a9ea2..4f3c133 100644
+--- a/lib/smb2-cmd-lock.c
++++ b/lib/smb2-cmd-lock.c
+@@ -77,6 +77,10 @@ smb2_encode_lock_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for lock request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LOCK_REQUEST_SIZE);
+         smb2_set_uint16(iov, 2, req->lock_count);
+@@ -101,6 +105,10 @@ smb2_encode_lock_request(struct smb2_context *smb2,
+                         return -1;
+                 }
+                 iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for lock elements");
++                        return -1;
++                }
+ 
+                 for (i = 0, offset = 0; i < req->lock_count; i++) {
+                         smb2_set_uint64(iov, offset, elements->offset);
+@@ -155,6 +163,10 @@ smb2_encode_lock_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for lock reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LOCK_REPLY_SIZE);
+         return 0;
+diff --git a/lib/smb2-cmd-logoff.c b/lib/smb2-cmd-logoff.c
+index 2ddc269..eb78db0 100644
+--- a/lib/smb2-cmd-logoff.c
++++ b/lib/smb2-cmd-logoff.c
+@@ -70,6 +70,10 @@ smb2_encode_logoff_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for logoff request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LOGOFF_REQUEST_SIZE);
+ 
+@@ -117,6 +121,10 @@ smb2_encode_logoff_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for logoff reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LOGOFF_REPLY_SIZE);
+ 
+diff --git a/lib/smb2-cmd-negotiate.c b/lib/smb2-cmd-negotiate.c
+index 190a227..e89d298 100644
+--- a/lib/smb2-cmd-negotiate.c
++++ b/lib/smb2-cmd-negotiate.c
+@@ -73,6 +73,9 @@ smb2_encode_preauth_context(struct smb2_context *smb2, struct smb2_pdu *pdu)
+         memset(buf, 0, len);
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+         smb2_set_uint16(iov, 0, SMB2_PREAUTH_INTEGRITY_CAP);
+         smb2_set_uint16(iov, 2, data_len);
+         smb2_set_uint16(iov, 8, 1);
+@@ -103,6 +106,9 @@ smb2_encode_encryption_context(struct smb2_context *smb2, struct smb2_pdu *pdu)
+         memset(buf, 0, len);
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+         smb2_set_uint16(iov, 0, SMB2_ENCRYPTION_CAP);
+         smb2_set_uint16(iov, 2, data_len);
+         smb2_set_uint16(iov, 8, 1);
+@@ -138,6 +144,10 @@ smb2_encode_negotiate_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for negotiate request");
++                return -1;
++        }
+ 
+         if (smb2->version == SMB2_VERSION_ANY ||
+             smb2->version == SMB2_VERSION_ANY3 ||
+@@ -221,6 +231,10 @@ smb2_encode_negotiate_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for negotiate reply");
++                return -1;
++        }
+ 
+         if (rep->security_buffer_length) {
+                 seclen = rep->security_buffer_length;
+@@ -233,10 +247,12 @@ smb2_encode_negotiate_reply(struct smb2_context *smb2,
+                 }
+                 memcpy(buf, rep->security_buffer, rep->security_buffer_length);
+                 memset(buf + rep->security_buffer_length, 0, seclen - rep->security_buffer_length);
+-                smb2_add_iovector(smb2, &pdu->out,
++                if (smb2_add_iovector(smb2, &pdu->out,
+                                         buf,
+-                                        len,
+-                                        free);
++                                        seclen,
++                                        free) == NULL) {
++                        return -1;
++                }
+         }
+ 
+         if (smb2->dialect == SMB2_VERSION_ANY ||
+diff --git a/lib/smb2-cmd-notify-change.c b/lib/smb2-cmd-notify-change.c
+index 875d933..852d034 100644
+--- a/lib/smb2-cmd-notify-change.c
++++ b/lib/smb2-cmd-notify-change.c
+@@ -73,6 +73,10 @@ smb2_encode_change_notify_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for change-notify request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_CHANGE_NOTIFY_REQUEST_SIZE);
+         smb2_set_uint16(iov, 2, req->flags);
+@@ -125,6 +129,10 @@ smb2_encode_change_notify_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for change-notify reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_CHANGE_NOTIFY_REPLY_SIZE);
+         rep->output_buffer_offset = SMB2_HEADER_SIZE + SMB2_CHANGE_NOTIFY_REQUEST_SIZE;
+@@ -147,6 +155,10 @@ smb2_encode_change_notify_reply(struct smb2_context *smb2,
+                                         buf,
+                                         len,
+                                         free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for change-notify output buffer");
++                return -1;
++        }
+ 
+         if (smb2->passthrough) {
+                 memcpy(buf, rep->output, rep->output_buffer_length);
+diff --git a/lib/smb2-cmd-oplock-break.c b/lib/smb2-cmd-oplock-break.c
+index 1c22e39..ab9aae5 100644
+--- a/lib/smb2-cmd-oplock-break.c
++++ b/lib/smb2-cmd-oplock-break.c
+@@ -70,6 +70,10 @@ smb2_encode_oplock_break_acknowledgement(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for oplock break ack");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_OPLOCK_BREAK_ACKNOWLEDGE_SIZE);
+         smb2_set_uint8(iov, 2, req->oplock_level);
+@@ -121,6 +125,10 @@ smb2_encode_oplock_break_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for oplock break reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_OPLOCK_BREAK_REPLY_SIZE);
+         smb2_set_uint8(iov, 2, rep->oplock_level);
+@@ -172,6 +180,10 @@ smb2_encode_oplock_break_notification(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for oplock break notification");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_OPLOCK_BREAK_REPLY_SIZE);
+         smb2_set_uint8(iov, 2, rep->oplock_level);
+@@ -222,6 +234,10 @@ smb2_encode_lease_break_acknowledgement(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for lease break ack");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LEASE_BREAK_ACKNOWLEDGE_SIZE);
+         smb2_set_uint32(iov, 4, req->flags);
+@@ -275,6 +291,10 @@ smb2_encode_lease_break_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for lease break reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LEASE_BREAK_REPLY_SIZE);
+         smb2_set_uint32(iov, 4, rep->flags);
+@@ -327,6 +347,10 @@ smb2_encode_lease_break_notification(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for lease break notification");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_LEASE_BREAK_NOTIFICATION_SIZE);
+         smb2_set_uint16(iov, 2, req->new_epoch);
+diff --git a/lib/smb2-cmd-query-directory.c b/lib/smb2-cmd-query-directory.c
+index 31b5002..4733c43 100644
+--- a/lib/smb2-cmd-query-directory.c
++++ b/lib/smb2-cmd-query-directory.c
+@@ -117,6 +117,11 @@ smb2_encode_query_directory_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for query-directory request");
++                free(name);
++                return -1;
++        }
+ 
+         /* Name */
+         if (req->name && req->name[0]) {
+@@ -149,6 +154,10 @@ smb2_encode_query_directory_request(struct smb2_context *smb2,
+                                         buf,
+                                         2 * name->len,
+                                         free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for query-directory name");
++                        return -1;
++                }
+         }
+         free(name);
+ 
+@@ -277,6 +286,10 @@ smb2_encode_query_directory_reply(struct smb2_context *smb2,
+                                         buf,
+                                         len,
+                                         free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for query-directory output buffer");
++                return -1;
++        }
+ 
+         in_offset = 0;
+         in_remain = fslen;
+diff --git a/lib/smb2-cmd-query-info.c b/lib/smb2-cmd-query-info.c
+index 0cef94d..195f816 100644
+--- a/lib/smb2-cmd-query-info.c
++++ b/lib/smb2-cmd-query-info.c
+@@ -77,6 +77,10 @@ smb2_encode_query_info_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for query-info request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_QUERY_INFO_REQUEST_SIZE);
+         smb2_set_uint8(iov, 2, req->info_type);
+@@ -145,6 +149,10 @@ smb2_encode_query_info_reply(struct smb2_context *smb2,
+         }
+ 
+         cmdiov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (cmdiov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for query-info reply header");
++                return -1;
++        }
+ 
+         smb2_set_uint16(cmdiov, 0, SMB2_QUERY_INFO_REPLY_SIZE);
+         smb2_set_uint16(cmdiov, 2, rep->output_buffer_offset);
+@@ -164,6 +172,10 @@ smb2_encode_query_info_reply(struct smb2_context *smb2,
+                                         buf,
+                                         len + 1024,
+                                         free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for query-info output buffer");
++                        return -1;
++                }
+ 
+                 created_output_buffer_length = 0;
+ 
+diff --git a/lib/smb2-cmd-read.c b/lib/smb2-cmd-read.c
+index 598060b..a0d4026 100644
+--- a/lib/smb2-cmd-read.c
++++ b/lib/smb2-cmd-read.c
+@@ -72,6 +72,9 @@ smb2_encode_read_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         if (!smb2->supports_multi_credit && req->length > 64 * 1024) {
+                 req->length = 64 * 1024;
+@@ -107,6 +110,9 @@ smb2_encode_read_request(struct smb2_context *smb2,
+                                                         buf,
+                                                         len,
+                                                         free);
++                        if (iov == NULL) {
++                                return -1;
++                        }
+                 }
+                 else {
+                         smb2_set_error(smb2, "ChannelInfo not yet implemented");
+@@ -120,7 +126,9 @@ smb2_encode_read_request(struct smb2_context *smb2,
+         if (req->read_channel_info_length == 0) {
+                 static uint8_t zero;
+ 
+-                smb2_add_iovector(smb2, &pdu->out, &zero, 1, NULL);
++                if (smb2_add_iovector(smb2, &pdu->out, &zero, 1, NULL) == NULL) {
++                        return -1;
++                }
+         }
+ 
+         return 0;
+@@ -144,8 +152,10 @@ smb2_cmd_read_async(struct smb2_context *smb2,
+         }
+ 
+         /* Add a vector for the buffer that the application gave us */
+-        smb2_add_iovector(smb2, &pdu->in, req->buf,
+-                          req->length, NULL);
++        if (smb2_add_iovector(smb2, &pdu->in, req->buf, req->length, NULL) == NULL) {
++                smb2_free_pdu(smb2, pdu);
++                return NULL;
++        }
+ 
+         if (smb2_pad_to_64bit(smb2, &pdu->out) != 0) {
+                 smb2_free_pdu(smb2, pdu);
+@@ -177,6 +187,9 @@ smb2_encode_read_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         rep->data_offset = 0;
+         if (rep->data_length && rep->data) {
+@@ -188,7 +201,9 @@ smb2_encode_read_reply(struct smb2_context *smb2,
+         smb2_set_uint32(iov, 8, rep->data_remaining);
+ 
+         if (rep->data_length > 0 && rep->data) {
+-                smb2_add_iovector(smb2, &pdu->out, rep->data, rep->data_length, free);
++                if (smb2_add_iovector(smb2, &pdu->out, rep->data, rep->data_length, free) == NULL) {
++                        return -1;
++                }
+         }
+ 
+         return 0;
+diff --git a/lib/smb2-cmd-session-setup.c b/lib/smb2-cmd-session-setup.c
+index f58edf5..9244283 100644
+--- a/lib/smb2-cmd-session-setup.c
++++ b/lib/smb2-cmd-session-setup.c
+@@ -73,6 +73,10 @@ smb2_encode_session_setup_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for session setup request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_SESSION_SETUP_REQUEST_SIZE);
+         smb2_set_uint8(iov, 2, req->flags);
+@@ -95,6 +99,10 @@ smb2_encode_session_setup_request(struct smb2_context *smb2,
+                                 buf,
+                                 req->security_buffer_length,
+                                 free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for session setup security buffer");
++                return -1;
++        }
+         return 0;
+ }
+ 
+@@ -142,6 +150,10 @@ smb2_encode_session_setup_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for session setup reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_SESSION_SETUP_REPLY_SIZE);
+         smb2_set_uint16(iov, 2, rep->session_flags);
+@@ -164,6 +176,10 @@ smb2_encode_session_setup_reply(struct smb2_context *smb2,
+                                         buf,
+                                         len,
+                                         free);
++                if (iov == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for session setup reply buffer");
++                        return -1;
++                }
+         }
+         /* TODO append neg contexts? */
+         return 0;
+diff --git a/lib/smb2-cmd-set-info.c b/lib/smb2-cmd-set-info.c
+index 3ff81b5..3002fa8 100644
+--- a/lib/smb2-cmd-set-info.c
++++ b/lib/smb2-cmd-set-info.c
+@@ -77,6 +77,10 @@ smb2_encode_set_info_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for set-info request header");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_SET_INFO_REQUEST_SIZE);
+         smb2_set_uint8(iov, 2, req->info_type);
+@@ -94,7 +98,11 @@ smb2_encode_set_info_request(struct smb2_context *smb2,
+                                 return -1;
+                         }
+                         memcpy(buf, req->input_data, req->buffer_length);
+-                        smb2_add_iovector(smb2, &pdu->out, buf, req->buffer_length, free);
++                        iov = smb2_add_iovector(smb2, &pdu->out, buf, req->buffer_length, free);
++                        if (iov == NULL) {
++                                smb2_set_error(smb2, "Failed to add iovector for set-info passthrough buffer");
++                                return -1;
++                        }
+                 }
+                 smb2_set_uint32(iov, 4, req->buffer_length);
+                 smb2_set_uint16(iov, 8, req->buffer_offset);
+@@ -116,6 +124,10 @@ smb2_encode_set_info_request(struct smb2_context *smb2,
+                         }
+                         iov = smb2_add_iovector(smb2, &pdu->out, buf, len,
+                                                 free);
++                        if (iov == NULL) {
++                                smb2_set_error(smb2, "Failed to add iovector for set-info basic data");
++                                return -1;
++                        }
+                         smb2_encode_file_basic_info(smb2, req->input_data, iov);
+                         break;
+                 case SMB2_FILE_END_OF_FILE_INFORMATION:
+@@ -130,6 +142,10 @@ smb2_encode_set_info_request(struct smb2_context *smb2,
+                         }
+                         iov = smb2_add_iovector(smb2, &pdu->out, buf, len,
+                                                 free);
++                        if (iov == NULL) {
++                                smb2_set_error(smb2, "Failed to add iovector for set-info EOF data");
++                                return -1;
++                        }
+ 
+                         eofi = req->input_data;
+                         smb2_set_uint64(iov, 0, eofi->end_of_file);
+@@ -162,6 +178,11 @@ smb2_encode_set_info_request(struct smb2_context *smb2,
+                         }
+                         iov = smb2_add_iovector(smb2, &pdu->out, buf, len,
+                                                 free);
++                        if (iov == NULL) {
++                                smb2_set_error(smb2, "Failed to add iovector for set-info rename data");
++                                free(name);
++                                return -1;
++                        }
+ 
+                         smb2_set_uint8(iov, 0, rni->replace_if_exist);
+                         smb2_set_uint64(iov, 8, 0u);
+@@ -182,6 +203,10 @@ smb2_encode_set_info_request(struct smb2_context *smb2,
+                         }
+                         iov = smb2_add_iovector(smb2, &pdu->out, buf, len,
+                                                 free);
++                        if (iov == NULL) {
++                                smb2_set_error(smb2, "Failed to add iovector for set-info disposition data");
++                                return -1;
++                        }
+ 
+                         fdi = req->input_data;
+                         smb2_set_uint8(iov, 0, fdi->delete_pending);
+@@ -246,6 +271,10 @@ smb2_encode_set_info_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for set-info reply header");
++                return -1;
++        }
+         smb2_set_uint16(iov, 0, SMB2_SET_INFO_REPLY_SIZE);
+         return 0;
+ }
+diff --git a/lib/smb2-cmd-tree-connect.c b/lib/smb2-cmd-tree-connect.c
+index a4846a7..9eb3099 100644
+--- a/lib/smb2-cmd-tree-connect.c
++++ b/lib/smb2-cmd-tree-connect.c
+@@ -73,6 +73,10 @@ smb2_encode_tree_connect_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for tree connect request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_TREE_CONNECT_REQUEST_SIZE);
+         smb2_set_uint16(iov, 2, req->flags);
+@@ -92,6 +96,10 @@ smb2_encode_tree_connect_request(struct smb2_context *smb2,
+                                 buf,
+                                 req->path_length,
+                                 free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for tree connect path");
++                return -1;
++        }
+ 
+         return 0;
+ }
+@@ -139,6 +147,10 @@ smb2_encode_tree_connect_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for tree connect reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_TREE_CONNECT_REPLY_SIZE);
+         smb2_set_uint8(iov, 2, rep->share_type);
+diff --git a/lib/smb2-cmd-tree-disconnect.c b/lib/smb2-cmd-tree-disconnect.c
+index 8541742..4e74abe 100644
+--- a/lib/smb2-cmd-tree-disconnect.c
++++ b/lib/smb2-cmd-tree-disconnect.c
+@@ -71,6 +71,10 @@ smb2_encode_tree_disconnect_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for tree disconnect request");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_TREE_DISCONNECT_REQUEST_SIZE);
+ 
+@@ -118,6 +122,10 @@ smb2_encode_tree_disconnect_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                smb2_set_error(smb2, "Failed to add iovector for tree disconnect reply");
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_TREE_DISCONNECT_REPLY_SIZE);
+ 
+diff --git a/lib/smb2-cmd-write.c b/lib/smb2-cmd-write.c
+index 25988c6..1aa3fd1 100644
+--- a/lib/smb2-cmd-write.c
++++ b/lib/smb2-cmd-write.c
+@@ -72,6 +72,9 @@ smb2_encode_write_request(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         if (!smb2->supports_multi_credit && req->length > 64 * 1024) {
+                 req->length = 64 * 1024;
+@@ -106,6 +109,9 @@ smb2_encode_write_request(struct smb2_context *smb2,
+                                                         buf,
+                                                         len,
+                                                         free);
++                        if (iov == NULL) {
++                                return -1;
++                        }
+                 }
+                 else {
+                         smb2_set_error(smb2, "ChannelInfo not yet implemented");
+@@ -139,8 +145,11 @@ smb2_cmd_write_async(struct smb2_context *smb2,
+                 return NULL;
+         }
+ 
+-        smb2_add_iovector(smb2, &pdu->out, (uint8_t*)req->buf,
+-                        req->length, pass_buf_ownership ? free : NULL);
++        if (smb2_add_iovector(smb2, &pdu->out, (uint8_t*)req->buf,
++                        req->length, pass_buf_ownership ? free : NULL) == NULL) {
++                smb2_free_pdu(smb2, pdu);
++                return NULL;
++        }
+ 
+         /* Adjust credit charge for large payloads */
+         if (smb2->supports_multi_credit) {
+@@ -167,6 +176,9 @@ smb2_encode_write_reply(struct smb2_context *smb2,
+         }
+ 
+         iov = smb2_add_iovector(smb2, &pdu->out, buf, len, free);
++        if (iov == NULL) {
++                return -1;
++        }
+ 
+         smb2_set_uint16(iov, 0, SMB2_WRITE_REPLY_SIZE);
+         smb2_set_uint32(iov, 4, rep->count);
+diff --git a/lib/smb3-seal.c b/lib/smb3-seal.c
+index 056df0b..b894f5f 100644
+--- a/lib/smb3-seal.c
++++ b/lib/smb3-seal.c
+@@ -148,8 +148,13 @@ smb3_decrypt_pdu(struct smb2_context *smb2)
+ 
+                 smb2->spl = (uint32_t)smb2->enc_len;
+                 smb2->recv_state = SMB2_RECV_HEADER;
+-                smb2_add_iovector(smb2, &smb2->in, &smb2->header[0],
+-                                  SMB2_HEADER_SIZE, NULL);
++                if (smb2_add_iovector(smb2, &smb2->in, &smb2->header[0],
++                                       SMB2_HEADER_SIZE, NULL) == NULL) {
++                        smb2_set_error(smb2, "Failed to add iovector for decrypted header");
++                        free(smb2->enc);
++                        smb2->enc = NULL;
++                        return -1;
++                }
+         }
+ 
+         rc = smb2_read_from_buf(smb2);
+diff --git a/lib/socket.c b/lib/socket.c
+index 8d2f381..474eddb 100644
+--- a/lib/socket.c
++++ b/lib/socket.c
+@@ -398,17 +398,28 @@ read_more_data:
+         case SMB2_RECV_SPL:
+                 smb2->spl = be32toh(smb2->spl);
+                 smb2->recv_state = SMB2_RECV_HEADER;
+-                smb2_add_iovector(smb2, &smb2->in, &smb2->header[0],
+-                                  SMB2_HEADER_SIZE, NULL);
++                if (smb2_add_iovector(smb2, &smb2->in, &smb2->header[0],
++                                  SMB2_HEADER_SIZE, NULL) == NULL) {
++                        smb2_set_error(smb2, "Too many I/O vectors when adding header");
++                        return -1;
++                }
+                 goto read_more_data;
+         case SMB2_RECV_HEADER:
+                 if (!memcmp(smb2->in.iov[smb2->in.niov - 1].buf, smb3tfrm, 4)) {
+                         smb2->in.iov[smb2->in.niov - 1].len = 52;
+                         len = smb2->spl - 52;
+                         smb2->in.total_size -= 12;
+-                        smb2_add_iovector(smb2, &smb2->in,
+-                                          malloc(len),
+-                                          len, free);
++                        {
++                                uint8_t *tmp = malloc(len);
++                                if (tmp == NULL) {
++                                        smb2_set_error(smb2, "malloc failed while adding TRFM payload");
++                                        return -1;
++                                }
++                                if (smb2_add_iovector(smb2, &smb2->in,tmp,len, free) == NULL) {
++                                        smb2_set_error(smb2, "Failed to add iovector for TRFM payload");
++                                        return -1;
++                                }
++                        }
+                         memcpy(smb2->in.iov[smb2->in.niov - 1].buf,
+                                &smb2->in.iov[smb2->in.niov - 2].buf[52], 12);
+                         smb2->recv_state = SMB2_RECV_TRFM;
+@@ -485,9 +496,16 @@ read_more_data:
+                         }
+                         /* Add padding before the next PDU */
+                         smb2->recv_state = SMB2_RECV_PAD;
+-                        smb2_add_iovector(smb2, &smb2->in,
+-                                          malloc(len),
+-                                          len, free);
++                        {
++                                uint8_t *tmp = malloc(len);
++                                if (tmp == NULL) {
++                                        smb2_set_error(smb2, "malloc failed while adding PENDING padding");
++                                        return -1;
++                                }
++                                if (smb2_add_iovector(smb2, &smb2->in,tmp, len, free) == NULL) {
++                                        return -1;
++                                }
++                        }
+                         goto read_more_data;
+                 }
+ 
+@@ -545,9 +563,19 @@ read_more_data:
+                 }
+ 
+                 smb2->recv_state = SMB2_RECV_FIXED;
+-                smb2_add_iovector(smb2, &smb2->in,
+-                                  malloc(len & 0xfffe),
+-                                  len & 0xfffe, free);
++                {
++                        size_t alen = len & 0xfffe;
++                        uint8_t *tmp = malloc(alen);
++                        if (tmp == NULL) {
++                                smb2_set_error(smb2, "malloc failed while adding FIXED payload");
++                                return -1;
++                        }
++                        if (smb2_add_iovector(smb2, &smb2->in,
++                                  tmp,
++                                  alen, free) == NULL) {
++                                return -1;
++                        }
++                }
+                 goto read_more_data;
+         case SMB2_RECV_FIXED:
+                 len = smb2_process_payload_fixed(smb2, pdu);
+@@ -566,9 +594,11 @@ read_more_data:
+                                 if (num > (size_t)len) {
+                                         num = (size_t)len;
+                                 }
+-                                smb2_add_iovector(smb2, &smb2->in,
++                                if (smb2_add_iovector(smb2, &smb2->in,
+                                                   pdu->in.iov[i].buf,
+-                                                  num, NULL);
++                                                  num, NULL) == NULL) {
++                                        return -1;
++                                }
+                                 len -= num;
+ 
+                                 if (len == 0) {
+@@ -578,9 +608,18 @@ read_more_data:
+                         }
+                         if (len > 0) {
+                                 smb2->recv_state = SMB2_RECV_VARIABLE;
+-                                smb2_add_iovector(smb2, &smb2->in,
+-                                                  malloc(len),
+-                                                  len, free);
++                                {
++                                        uint8_t *tmp = malloc(len);
++                                        if (tmp == NULL) {
++                                                smb2_set_error(smb2, "malloc failed while adding VARIABLE tail");
++                                                return -1;
++                                        }
++                                        if (smb2_add_iovector(smb2, &smb2->in,
++                                                  tmp,
++                                                  len, free) == NULL) {
++                                                return -1;
++                                        }
++                                }
+                                 goto read_more_data;
+                         }
+                 }
+@@ -608,9 +647,18 @@ read_more_data:
+                 if (len > 0) {
+                         /* Add padding before the next PDU */
+                         smb2->recv_state = SMB2_RECV_PAD;
+-                        smb2_add_iovector(smb2, &smb2->in,
+-                                          malloc(len),
+-                                          len, free);
++                        {
++                                uint8_t *tmp = malloc(len);
++                                if (tmp == NULL) {
++                                        smb2_set_error(smb2, "malloc failed while adding PAD");
++                                        return -1;
++                                }
++                                if (smb2_add_iovector(smb2, &smb2->in,
++                                          tmp,
++                                          len, free) == NULL) {
++                                        return -1;
++                                }
++                        }
+                         goto read_more_data;
+                 }
+ 
+@@ -648,9 +696,17 @@ read_more_data:
+                 if (len > 0) {
+                         /* Add padding before the next PDU */
+                         smb2->recv_state = SMB2_RECV_PAD;
+-                        smb2_add_iovector(smb2, &smb2->in,
+-                                          malloc(len),
+-                                          len, free);
++                        uint8_t * tmp = malloc(len);
++                        if (tmp == NULL) {
++                            smb2_set_error(smb2, "malloc failed while adding PAD");
++                            return -1;
++                        }
++                        if (smb2_add_iovector(smb2, &smb2->in,
++                                              tmp,
++                                              len, free) == NULL) {
++                                smb2_set_error(smb2, "Failed to add iovector for PAD");
++                                return -1;
++                        }
+                         goto read_more_data;
+                 }
+ 
+@@ -744,8 +800,11 @@ read_more_data:
+                 /* Record at which iov we ended in this loop so we know where to start in the next */
+                 iov_offset = smb2->in.niov - 1;
+                 smb2->recv_state = SMB2_RECV_HEADER;
+-                smb2_add_iovector(smb2, &smb2->in, &smb2->header[0],
+-                                  SMB2_HEADER_SIZE, NULL);
++                if (smb2_add_iovector(smb2, &smb2->in, &smb2->header[0],
++                                  SMB2_HEADER_SIZE, NULL) == NULL) {
++                        smb2_set_error(smb2, "Too many I/O vectors when adding chained header");
++                        return -1;
++                }
+                 goto read_more_data;
+         }
+ 
+@@ -777,8 +836,11 @@ smb2_read_from_socket(struct smb2_context *smb2)
+                 smb2->spl = 0;
+ 
+                 smb2_free_iovector(smb2, &smb2->in);
+-                smb2_add_iovector(smb2, &smb2->in, (uint8_t *)&smb2->spl,
+-                                  SMB2_SPL_SIZE, NULL);
++                if (smb2_add_iovector(smb2, &smb2->in, (uint8_t *)&smb2->spl,
++                                  SMB2_SPL_SIZE, NULL) == NULL) {
++                        smb2_set_error(smb2, "Too many I/O vectors when adding SPL");
++                        return -1;
++                }
+         }
+ 
+         return smb2_read_data(smb2, smb2_readv_from_socket, 0);
diff -Nru libsmb2-6.2+dfsg/debian/patches/series libsmb2-6.2+dfsg/debian/patches/series
--- libsmb2-6.2+dfsg/debian/patches/series	2025-04-03 15:20:58.000000000 -0300
+++ libsmb2-6.2+dfsg/debian/patches/series	2025-10-17 20:26:34.000000000 -0300
@@ -1,2 +1,6 @@
 10-Fix-compiler-warning.patch
 20-Handle-a-bunch-of-other-compiler-warnings.patch
+CVE-2025-57632-pt1.patch
+CVE-2025-57632-pt2.patch
+CVE-2025-57632-pt3.patch
+CVE-2025-57632-pt4.patch

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 13.2

Hi,

The updates referenced in each of these bugs were included in today's
13.2 trixie point release.

Regards,

Adam

--- End Message ---

Reply to: