Version in base suite: 6.2+dfsg-2 Base version: libsmb2_6.2+dfsg-2 Target version: libsmb2_6.2+dfsg-2+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libs/libsmb2/libsmb2_6.2+dfsg-2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libs/libsmb2/libsmb2_6.2+dfsg-2+deb13u1.dsc changelog | 15 patches/CVE-2025-57632-pt1.patch | 36 + patches/CVE-2025-57632-pt2.patch | 65 ++ patches/CVE-2025-57632-pt3.patch | 38 + patches/CVE-2025-57632-pt4.patch | 1146 +++++++++++++++++++++++++++++++++++++++ patches/series | 4 6 files changed, 1304 insertions(+) diff -Nru libsmb2-6.2+dfsg/debian/changelog libsmb2-6.2+dfsg/debian/changelog --- libsmb2-6.2+dfsg/debian/changelog 2025-04-03 18:20:58.000000000 +0000 +++ libsmb2-6.2+dfsg/debian/changelog 2025-10-17 23:26:34.000000000 +0000 @@ -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 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 1970-01-01 00:00:00.000000000 +0000 +++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt1.patch 2025-10-17 23:26:34.000000000 +0000 @@ -0,0 +1,36 @@ +From 5e75eebf922b338cdb548d60cffb3b997d2a12e8 Mon Sep 17 00:00:00 2001 +From: ZjW1nd +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 1970-01-01 00:00:00.000000000 +0000 +++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt2.patch 2025-10-17 23:26:34.000000000 +0000 @@ -0,0 +1,65 @@ +From 70754b01fb272604e90f8b886ec4ff73ca6ab38f Mon Sep 17 00:00:00 2001 +From: ZjW1nd +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 + +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 1970-01-01 00:00:00.000000000 +0000 +++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt3.patch 2025-10-17 23:26:34.000000000 +0000 @@ -0,0 +1,38 @@ +From d0801c5cdb847339b881447087216628a7a4ebe4 Mon Sep 17 00:00:00 2001 +From: ZjW1nd +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 + +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 1970-01-01 00:00:00.000000000 +0000 +++ libsmb2-6.2+dfsg/debian/patches/CVE-2025-57632-pt4.patch 2025-10-17 23:26:34.000000000 +0000 @@ -0,0 +1,1146 @@ +From 883e787426df52dd19206234d7278d46ac997668 Mon Sep 17 00:00:00 2001 +From: ZjW1nd +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 + +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 18:20:58.000000000 +0000 +++ libsmb2-6.2+dfsg/debian/patches/series 2025-10-17 23:26:34.000000000 +0000 @@ -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