Bug 16035 - use after free in streams_xattr_connect()
Summary: use after free in streams_xattr_connect()
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: File services (show other bugs)
Version: 4.24.0rc*
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba release manager
QA Contact: Samba QA Contact
URL: https://gitlab.com/samba-team/samba/-...
Keywords:
Depends on:
Blocks:
 
Reported: 2026-03-17 15:03 UTC by Stefan Metzmacher
Modified: 2026-03-20 08:40 UTC (History)
1 user (show)

See Also:


Attachments
backport for 4.24 (4.55 KB, patch)
2026-03-20 01:08 UTC, Björn Jacke
metze: review+
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Metzmacher 2026-03-17 15:03:53 UTC
Trend Micro's Zero Day Initiative has identified the problem as ZDI-CAN-29200.

There's a use after free and it will be fixed like this:

diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 5d267a1c1fbf..4d8b81bdc9d8 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -1470,8 +1470,8 @@ static int streams_xattr_connect(vfs_handle_struct *handle,
                                          "streams_xattr",
                                          "ext_prefix",
                                          default_ext_prefix);
-       TALLOC_FREE(default_ext_prefix);
        config->ext_prefix = talloc_strdup(config, ext_prefix);
+       TALLOC_FREE(default_ext_prefix);
        if (config->ext_prefix == NULL) {
                DEBUG(1, ("talloc_strdup() failed\n"));
                errno = ENOMEM;

While tools like address sanitizer and most likely valgrind
report this it's not actually a real problem.

Most likely the content of default_ext_prefix is still the same
as TALLOC_FREE doesn't explicitly change and talloc_tos() most likely
allocated on the talloc_stackframe_pool(8192) allocated in in
smbd_tevent_trace_callback_before_loop_once().

talloc_strdup(config, ext_prefix) may reuse the same memory and the
memcpy in __talloc_strlendup() may get a problem.

Also all values are only controlled by the administrator via
the smb.conf not by the client.

To prove this theory I used the following change:

diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 5d267a1c1fbf..dc20ec1eb2e3 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -1466,18 +1466,25 @@ static int streams_xattr_connect(vfs_handle_struct *handle,
                return -1;
        }

+       DBG_ERR("default_ext_prefix[%p][%zu][%s]\n", default_ext_prefix, talloc_get_size(default_ext_prefix), default_ext_prefix);
+
        ext_prefix = lp_parm_const_string(SNUM(handle->conn),
                                          "streams_xattr",
                                          "ext_prefix",
                                          default_ext_prefix);
+       DBG_ERR("ext_prefix[%p][%s]\n", ext_prefix, ext_prefix);
+       SMB_ASSERT(default_ext_prefix == ext_prefix);
        TALLOC_FREE(default_ext_prefix);
+       DBG_ERR("ext_prefix[%p][%s]\n", ext_prefix, ext_prefix);
        config->ext_prefix = talloc_strdup(config, ext_prefix);
+       DBG_ERR("config->ext_prefix[%p][%zu][%s]\n", config->ext_prefix, talloc_get_size(config->ext_prefix), config->ext_prefix);
+       SMB_ASSERT(config->ext_prefix == ext_prefix);
        if (config->ext_prefix == NULL) {
                DEBUG(1, ("talloc_strdup() failed\n"));
                errno = ENOMEM;
                return -1;
        }
-       DBG_DEBUG("using stream ext prefix: %s\n", config->ext_prefix);
+       DBG_ERR("using stream ext prefix: %s\n", config->ext_prefix);

        config->store_stream_type = lp_parm_bool(SNUM(handle->conn),
                                                 "streams_xattr", 

Running it twice in a debugger didn't hit any SMB_ASSERT
and printed the expected values:

smbd version 4.25.0pre1-DEVELOPERBUILD started.
Copyright Andrew Tridgell and the Samba Team 1992-2026
[Detaching after fork from child process 7933]
daemon 'smbd' : Starting process ...
streams_xattr_connect: default_ext_prefix[0x5555555ed930][19][user.DosStreamExt.]
streams_xattr_connect: ext_prefix[0x5555555ed930][user.DosStreamExt.]
streams_xattr_connect: ext_prefix[0x5555555ed930][user.DosStreamExt.]
streams_xattr_connect: config->ext_prefix[0x5555555ed930][19][user.DosStreamExt.]
streams_xattr_connect: using stream ext prefix: user.DosStreamExt.

Program received signal SIGTERM, Terminated.
Download failed: Invalid argument.  Continuing without source file ./signal/../sysdeps/unix/syscall-template.S.
0x00007ffff764613b in __GI_kill () at ../sysdeps/unix/syscall-template.S:120
⚠️+ warning: 120 ../sysdeps/unix/syscall-template.S: No such file or directory
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/samba.git/bin/smbd -i
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
smbd version 4.25.0pre1-DEVELOPERBUILD started.
Copyright Andrew Tridgell and the Samba Team 1992-2026
[Detaching after fork from child process 7971]
daemon 'smbd' : Starting process ...
streams_xattr_connect: default_ext_prefix[0x5555555ed6d0][19][user.DosStreamExt.]
streams_xattr_connect: ext_prefix[0x5555555ed6d0][user.DosStreamExt.]
streams_xattr_connect: ext_prefix[0x5555555ed6d0][user.DosStreamExt.]
streams_xattr_connect: config->ext_prefix[0x5555555ed6d0][19][user.DosStreamExt.]
streams_xattr_connect: using stream ext prefix: user.DosStreamExt.

Program received signal SIGTERM, Terminated.
Comment 1 Samba QA Contact 2026-03-19 15:01:04 UTC
This bug was referenced in samba master:

1c9a5d40298169e391749c834e8c381d736abdb4
Comment 2 Björn Jacke 2026-03-20 01:08:33 UTC
Created attachment 18913 [details]
backport for 4.24