summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-networking/recipes-connectivity/samba/samba/0001-lib-replace-Implement-memset_explicit.patch91
-rw-r--r--meta-networking/recipes-connectivity/samba/samba/0002-lib-replace-Add-test-for-memset_explicit.patch154
-rw-r--r--meta-networking/recipes-connectivity/samba/samba/0003-Replace-memset_s-with-memset_explicit.patch308
-rw-r--r--meta-networking/recipes-connectivity/samba/samba/0004-lib-replace-Remove-memset_s.patch345
-rw-r--r--meta-networking/recipes-connectivity/samba/samba_4.19.9.bb4
5 files changed, 902 insertions, 0 deletions
diff --git a/meta-networking/recipes-connectivity/samba/samba/0001-lib-replace-Implement-memset_explicit.patch b/meta-networking/recipes-connectivity/samba/samba/0001-lib-replace-Implement-memset_explicit.patch
new file mode 100644
index 0000000000..331d7eae87
--- /dev/null
+++ b/meta-networking/recipes-connectivity/samba/samba/0001-lib-replace-Implement-memset_explicit.patch
@@ -0,0 +1,91 @@
1From fba2c1dfb3b1f474a78e2613f150a9efc6d9b6c2 Mon Sep 17 00:00:00 2001
2From: Andreas Schneider <asn@samba.org>
3Date: Thu, 16 Oct 2025 11:06:56 +0200
4Subject: [PATCH 1/4] lib:replace: Implement memset_explicit()
5
6The memset_s() implementation is a bit obscure, as it requires a
7constraint handler to be set up. You don't really find any
8implmentations out there.
9
10With C23 memset_explicit() was added and this has been implemented
11for glibc 2.43 and also in FreeBSD.
12
13See https://sourceware.org/bugzilla/show_bug.cgi?id=32378
14See https://reviews.freebsd.org/D47286
15
16Upstream-Status: Backport [https://gitlab.com/samba-team/samba/-/commit/ef08be24e9114b4477cc2b3f7a28a816ec66802c]
17Signed-off-by: Andreas Schneider <asn@samba.org>
18Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
19Signed-off-by: Khem Raj <raj.khem@gmail.com>
20---
21 lib/replace/README | 1 +
22 lib/replace/replace.c | 13 +++++++++++++
23 lib/replace/replace.h | 5 +++++
24 lib/replace/wscript | 2 +-
25 4 files changed, 20 insertions(+), 1 deletion(-)
26
27diff --git a/lib/replace/README b/lib/replace/README
28index 6612eab..bb9d008 100644
29--- a/lib/replace/README
30+++ b/lib/replace/README
31@@ -73,6 +73,7 @@ symlink
32 realpath
33 poll
34 setproctitle
35+memset_explicit
36 memset_s
37
38 Types:
39diff --git a/lib/replace/replace.c b/lib/replace/replace.c
40index 68829f2..8615899 100644
41--- a/lib/replace/replace.c
42+++ b/lib/replace/replace.c
43@@ -952,6 +952,19 @@ void rep_setproctitle_init(int argc, char *argv[], char *envp[])
44 }
45 #endif
46
47+#ifndef HAVE_MEMSET_EXPLICIT
48+void *rep_memset_explicit(void *block, int c, size_t size)
49+{
50+ void *ptr = memset(block, c, size);
51+#ifdef HAVE_GCC_VOLATILE_MEMORY_PROTECTION
52+ /* See http://llvm.org/bugs/show_bug.cgi?id=15495 */
53+ __asm__ volatile("" : : "g"(block) : "memory");
54+#endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
55+
56+ return ptr;
57+}
58+#endif
59+
60 #ifndef HAVE_MEMSET_S
61 # ifndef RSIZE_MAX
62 # define RSIZE_MAX (SIZE_MAX >> 1)
63diff --git a/lib/replace/replace.h b/lib/replace/replace.h
64index 25e6e14..1a8336d 100644
65--- a/lib/replace/replace.h
66+++ b/lib/replace/replace.h
67@@ -994,6 +994,11 @@ void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
68 void rep_setproctitle_init(int argc, char *argv[], char *envp[]);
69 #endif
70
71+#ifndef HAVE_MEMSET_EXPLICIT
72+#define memset_explicit rep_memset_explicit
73+void *rep_memset_explicit(void *block, int c, size_t size);
74+#endif
75+
76 #ifndef HAVE_MEMSET_S
77 #define memset_s rep_memset_s
78 int rep_memset_s(void *dest, size_t destsz, int ch, size_t count);
79diff --git a/lib/replace/wscript b/lib/replace/wscript
80index a22ae59..574740a 100644
81--- a/lib/replace/wscript
82+++ b/lib/replace/wscript
83@@ -881,7 +881,7 @@ REPLACEMENT_FUNCTIONS = {
84 'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink',
85 'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf',
86 'dprintf', 'get_current_dir_name', 'copy_file_range',
87- 'strerror_r', 'clock_gettime', 'memset_s'],
88+ 'strerror_r', 'clock_gettime', 'memset_explicit', 'memset_s'],
89 'timegm.c': ['timegm'],
90 # Note: C99_VSNPRINTF is not a function, but a special condition
91 # for replacement
diff --git a/meta-networking/recipes-connectivity/samba/samba/0002-lib-replace-Add-test-for-memset_explicit.patch b/meta-networking/recipes-connectivity/samba/samba/0002-lib-replace-Add-test-for-memset_explicit.patch
new file mode 100644
index 0000000000..33e29533e9
--- /dev/null
+++ b/meta-networking/recipes-connectivity/samba/samba/0002-lib-replace-Add-test-for-memset_explicit.patch
@@ -0,0 +1,154 @@
1From ac2ee18b081483430b42c2cf35e423634aebbeb8 Mon Sep 17 00:00:00 2001
2From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
3Date: Thu, 30 Oct 2025 16:01:36 +0100
4Subject: [PATCH 2/4] lib:replace: Add test for memset_explicit()
5
6Upstream-Status: Backport [https://gitlab.com/samba-team/samba/-/commit/2b17c9816d4373eba365de803eec10435ea038d4]
7Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
8Reviewed-by: Andreas Schneider <asn@samba.org>
9Signed-off-by: Khem Raj <raj.khem@gmail.com>
10---
11 lib/replace/tests/test_memset_explicit.c | 99 ++++++++++++++++++++++++
12 lib/replace/wscript | 5 ++
13 selftest/tests.py | 6 ++
14 3 files changed, 110 insertions(+)
15 create mode 100644 lib/replace/tests/test_memset_explicit.c
16
17diff --git a/lib/replace/tests/test_memset_explicit.c b/lib/replace/tests/test_memset_explicit.c
18new file mode 100644
19index 0000000..4e56d7a
20--- /dev/null
21+++ b/lib/replace/tests/test_memset_explicit.c
22@@ -0,0 +1,99 @@
23+#include <stdarg.h>
24+#include <stddef.h>
25+#include <stdint.h>
26+#include <setjmp.h>
27+#include <cmocka.h>
28+
29+#include "lib/replace/replace.h"
30+
31+
32+/*
33+ * To check that a memset_explicit string is being memset when it
34+ * appears unused, we meed to be sneaky in our check -- otherwise the
35+ * check counts as a use.
36+ *
37+ * We are sneaky by using a function that seens to take an int
38+ * argument which is really a pointer, and we hide that it is a
39+ * pointer by masking it.
40+ *
41+ * For these tests we don't use talloc because the talloc magic gets
42+ * in the way a little bit.
43+ */
44+
45+#define MASK 0x12345678
46+
47+__attribute__((noinline))
48+static void check_memset_explicit(intmax_t p, const char *expected, size_t len)
49+{
50+ size_t i;
51+ char *secret = (char *) (p ^ MASK);
52+ for (i = 0; i < len; i++) {
53+ assert_int_equal(secret[i], expected[i]);
54+ }
55+}
56+
57+
58+__attribute__((noinline))
59+static char *get_secret(off_t offset)
60+{
61+ char * secret = malloc(7 + offset);
62+ memset(secret, 0, 7 + offset);
63+ memcpy(secret + offset, "secret", 7);
64+ /* avoiding *this* being elided */
65+ print_message("secret is '%s'\n", secret);
66+ asm("");
67+ return secret;
68+}
69+
70+
71+static void test_memset_explicit(void ** state)
72+{
73+ uintptr_t p;
74+ char zeros[7] = {0};
75+ char *secret = get_secret(0);
76+ p = ((uintptr_t)secret) ^ MASK;
77+ memset_explicit(secret, 'o', 3);
78+ check_memset_explicit(p, "oooret", 7);
79+ memset_explicit(secret, 0, 7);
80+ check_memset_explicit(p, zeros, 7);
81+ free(secret);
82+}
83+
84+static void test_memset_explicit_double_alloc(void ** state)
85+{
86+ size_t i, found;
87+ uintptr_t p, q;
88+ char *secret = get_secret(20);
89+ p = (uintptr_t)secret ^ MASK;
90+ memset_explicit(secret, 'x', 23);
91+ free(secret);
92+ /*
93+ * Now we malloc the same size again, and hope we got the
94+ * block we just freed.
95+ */
96+ found = 0;
97+ for (i = 0; i < 1000; i++) {
98+ secret = malloc(27);
99+ q = (uintptr_t)secret ^ MASK;
100+ if (q == p) {
101+ q = (uintptr_t)(secret + 20) ^ MASK;
102+ check_memset_explicit(q, "xxxret", 7);
103+ found ++;
104+ }
105+ free(secret);
106+ }
107+ print_message("found freed pointer %zu/1000 times \n",
108+ found);
109+}
110+
111+int main(void)
112+{
113+ const struct CMUnitTest tests[] = {
114+ cmocka_unit_test(test_memset_explicit),
115+ cmocka_unit_test(test_memset_explicit_double_alloc),
116+ };
117+ if (! isatty(1)) {
118+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
119+ }
120+ return cmocka_run_group_tests(tests, NULL, NULL);
121+}
122diff --git a/lib/replace/wscript b/lib/replace/wscript
123index 574740a..9acebd3 100644
124--- a/lib/replace/wscript
125+++ b/lib/replace/wscript
126@@ -964,6 +964,11 @@ def build(bld):
127 deps='replace replace-test',
128 install=False)
129
130+ bld.SAMBA_BINARY('test_memset_explicit',
131+ source='tests/test_memset_explicit.c',
132+ deps='cmocka replace',
133+ for_selftest=True)
134+
135 # build replacements for stdint.h and stdbool.h if needed
136 bld.SAMBA_GENERATOR('replace_stdint_h',
137 rule='cp ${SRC} ${TGT}',
138diff --git a/selftest/tests.py b/selftest/tests.py
139index deb3c0b..3131905 100644
140--- a/selftest/tests.py
141+++ b/selftest/tests.py
142@@ -414,6 +414,12 @@ plantestsuite("samba.unittests.smb1cli_session", "none",
143 plantestsuite("samba.unittests.smb_util_translate", "none",
144 [os.path.join(bindir(), "default/libcli/smb/test_util_translate")])
145
146+plantestsuite(
147+ "samba.unittests.memset_explicit",
148+ "none",
149+ [os.path.join(bindir(), "default/lib/replace/test_memset_explicit")],
150+)
151+
152 plantestsuite("samba.unittests.talloc_keep_secret", "none",
153 [os.path.join(bindir(), "default/lib/util/test_talloc_keep_secret")])
154
diff --git a/meta-networking/recipes-connectivity/samba/samba/0003-Replace-memset_s-with-memset_explicit.patch b/meta-networking/recipes-connectivity/samba/samba/0003-Replace-memset_s-with-memset_explicit.patch
new file mode 100644
index 0000000000..a96cd062cd
--- /dev/null
+++ b/meta-networking/recipes-connectivity/samba/samba/0003-Replace-memset_s-with-memset_explicit.patch
@@ -0,0 +1,308 @@
1From 8174382fe7a278309fc98b6e11ff99b6f41a8719 Mon Sep 17 00:00:00 2001
2From: Andreas Schneider <asn@samba.org>
3Date: Thu, 16 Oct 2025 11:19:51 +0200
4Subject: [PATCH 3/4] Replace memset_s() with memset_explicit()
5
6Upstream-Status: Backport [https://gitlab.com/samba-team/samba/-/commit/3e81b73a050e511c658afc786478431ceef175ee]
7Signed-off-by: Andreas Schneider <asn@samba.org>
8Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
9Signed-off-by: Khem Raj <raj.khem@gmail.com>
10---
11 lib/replace/replace.h | 18 +++++++++---------
12 lib/util/memory.h | 16 +++++++++-------
13 lib/util/tests/test_talloc_keep_secret.c | 19 ++++++++-----------
14 3 files changed, 26 insertions(+), 27 deletions(-)
15
16--- a/lib/replace/replace.h
17+++ b/lib/replace/replace.h
18@@ -815,50 +815,50 @@ typedef unsigned long long ptrdiff_t ;
19 /**
20 * Zero a structure.
21 */
22-#define ZERO_STRUCT(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x))
23+#define ZERO_STRUCT(x) memset_explicit((char *)&(x), 0, sizeof(x))
24
25 /**
26 * Zero a structure given a pointer to the structure.
27 */
28 #define ZERO_STRUCTP(x) do { \
29 if ((x) != NULL) { \
30- memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))); \
31+ memset_explicit((char *)(x), 0, sizeof(*(x))); \
32 } \
33 } while(0)
34
35 /**
36 * Zero a structure given a pointer to the structure - no zero check
37 */
38-#define ZERO_STRUCTPN(x) memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x)))
39+#define ZERO_STRUCTPN(x) memset_explicit((char *)(x), 0, sizeof(*(x)))
40
41 /**
42 * Zero an array - note that sizeof(array) must work - ie. it must not be a
43 * pointer
44 */
45-#define ZERO_ARRAY(x) memset_s((char *)(x), sizeof(x), 0, sizeof(x))
46+#define ZERO_ARRAY(x) memset_explicit((char *)(x), 0, sizeof(x))
47
48 /**
49 * Zero a given len of an array
50 */
51-#define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l))
52+#define ZERO_ARRAY_LEN(x, l) memset_explicit((char *)(x), 0, (l))
53
54 /**
55 * Explicitly zero data from memory. This is guaranteed to be not optimized
56 * away.
57 */
58-#define BURN_DATA(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x))
59+#define BURN_DATA(x) memset_explicit((char *)&(x), 0, sizeof(x))
60
61 /**
62 * Explicitly zero data from memory. This is guaranteed to be not optimized
63 * away.
64 */
65-#define BURN_DATA_SIZE(x, s) memset_s((char *)&(x), (s), 0, (s))
66+#define BURN_DATA_SIZE(x, s) memset_explicit((char *)&(x), 0, (s))
67
68 /**
69 * Explicitly zero data from memory. This is guaranteed to be not optimized
70 * away.
71 */
72-#define BURN_PTR_SIZE(x, s) memset_s((x), (s), 0, (s))
73+#define BURN_PTR_SIZE(x, s) memset_explicit((x), 0, (s))
74
75 /**
76 * Explicitly zero data in string. This is guaranteed to be not optimized
77@@ -867,7 +867,7 @@ typedef unsigned long long ptrdiff_t ;
78 #define BURN_STR(x) do { \
79 if ((x) != NULL) { \
80 size_t s = strlen(x); \
81- memset_s((x), s, 0, s); \
82+ memset_explicit((x), 0, s); \
83 } \
84 } while(0)
85
86--- a/lib/util/memory.h
87+++ b/lib/util/memory.h
88@@ -40,7 +40,7 @@
89 #define BURN_FREE_STR(x) do { \
90 if ((x) != NULL) { \
91 size_t s = strlen(x); \
92- memset_s((x), s, 0, s); \
93+ memset_explicit((x), 0, s); \
94 free(x); (x) = NULL; \
95 } \
96 } while(0)
97@@ -53,7 +53,7 @@
98 **/
99 #define BURN_FREE(x, s) do { \
100 if ((x) != NULL) { \
101- memset_s((x), (s), 0, (s)); \
102+ memset_explicit((x), 0, (s)); \
103 free(x); (x) = NULL; \
104 } \
105 } while(0)
106@@ -78,7 +78,7 @@
107 * Zero a structure.
108 */
109 #ifndef ZERO_STRUCT
110-#define ZERO_STRUCT(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x))
111+#define ZERO_STRUCT(x) memset_explicit((char *)&(x), 0, sizeof(x))
112 #endif
113
114 /**
115@@ -87,7 +87,7 @@
116 #ifndef ZERO_STRUCTP
117 #define ZERO_STRUCTP(x) do { \
118 if ((x) != NULL) { \
119- memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))); \
120+ memset_explicit((char *)(x), 0, sizeof(*(x))); \
121 } \
122 } while(0)
123 #endif
124@@ -96,7 +96,7 @@
125 * Zero a structure given a pointer to the structure - no zero check.
126 */
127 #ifndef ZERO_STRUCTPN
128-#define ZERO_STRUCTPN(x) memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x)))
129+#define ZERO_STRUCTPN(x) memset_explicit((char *)(x), 0, sizeof(*(x)))
130 #endif
131
132 /**
133@@ -104,13 +104,15 @@
134 * pointer.
135 */
136 #ifndef ZERO_ARRAY
137-#define ZERO_ARRAY(x) memset_s((char *)(x), sizeof(x), 0, sizeof(x))
138+#define ZERO_ARRAY(x) memset_explicit((char *)(x), 0, sizeof(x))
139 #endif
140
141 /**
142 * Zero a given len of an array
143 */
144-#define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l))
145+#ifndef ZERO_ARRAY_LEN
146+#define ZERO_ARRAY_LEN(x, l) memset_explicit((char *)(x), 0, (l))
147+#endif
148
149 /**
150 * Work out how many elements there are in a static array
151--- a/lib/util/tests/test_talloc_keep_secret.c
152+++ b/lib/util/tests/test_talloc_keep_secret.c
153@@ -8,12 +8,11 @@
154 #include <talloc.h>
155 #include "lib/util/talloc_keep_secret.h"
156
157-int rep_memset_s(void *dest, size_t destsz, int ch, size_t count);
158+int rep_memset_explicit(void *dest, int ch, size_t count);
159
160-int rep_memset_s(void *dest, size_t destsz, int ch, size_t count)
161+int rep_memset_explicit(void *dest, int ch, size_t count)
162 {
163 check_expected_ptr(dest);
164- check_expected(destsz);
165 check_expected(ch);
166 check_expected(count);
167
168@@ -44,10 +43,9 @@ static void test_talloc_keep_secret(void
169 ptr1_size = talloc_get_size(ptr1);
170 assert_int_equal(ptr1_size, strlen(ptr1) + 1);
171
172- expect_string(rep_memset_s, dest, "secret");
173- expect_value(rep_memset_s, destsz, strlen(ptr1) + 1);
174- expect_value(rep_memset_s, ch, (int)'\0');
175- expect_value(rep_memset_s, count, strlen(ptr1) + 1);
176+ expect_string(rep_memset_explicit, dest, "secret");
177+ expect_value(rep_memset_explicit, ch, (int)'\0');
178+ expect_value(rep_memset_explicit, count, strlen(ptr1) + 1);
179
180 talloc_free(ptr1);
181
182@@ -73,10 +71,9 @@ static void test_talloc_keep_secret_vali
183 assert_non_null(password);
184 talloc_keep_secret(password);
185
186- expect_string(rep_memset_s, dest, "secret");
187- expect_value(rep_memset_s, destsz, strlen(password) + 1);
188- expect_value(rep_memset_s, ch, (int)'\0');
189- expect_value(rep_memset_s, count, strlen(password) + 1);
190+ expect_string(rep_memset_explicit, dest, "secret");
191+ expect_value(rep_memset_explicit, ch, (int)'\0');
192+ expect_value(rep_memset_explicit, count, strlen(password) + 1);
193
194 talloc_free(mem_ctx);
195 }
196--- a/lib/cmdline/cmdline.c
197+++ b/lib/cmdline/cmdline.c
198@@ -358,7 +358,7 @@ bool samba_cmdline_burn(int argc, char *
199 p += ulen;
200 }
201
202- memset_s(p, strlen(p), '\0', strlen(p));
203+ memset_explicit(p, '\0', strlen(p));
204 burnt = true;
205 }
206 }
207--- a/lib/util/data_blob.c
208+++ b/lib/util/data_blob.c
209@@ -1,19 +1,19 @@
210-/*
211+/*
212 Unix SMB/CIFS implementation.
213 Easy management of byte-length data
214 Copyright (C) Andrew Tridgell 2001
215 Copyright (C) Andrew Bartlett 2001
216-
217+
218 This program is free software; you can redistribute it and/or modify
219 it under the terms of the GNU General Public License as published by
220 the Free Software Foundation; either version 3 of the License, or
221 (at your option) any later version.
222-
223+
224 This program is distributed in the hope that it will be useful,
225 but WITHOUT ANY WARRANTY; without even the implied warranty of
226 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
227 GNU General Public License for more details.
228-
229+
230 You should have received a copy of the GNU General Public License
231 along with this program. If not, see <http://www.gnu.org/licenses/>.
232 */
233@@ -67,7 +67,7 @@ _PUBLIC_ DATA_BLOB data_blob_talloc_name
234 }
235
236 /**
237- construct a zero data blob, using supplied TALLOC_CTX.
238+ construct a zero data blob, using supplied TALLOC_CTX.
239 use this sparingly as it initialises data - better to initialise
240 yourself if you want specific data in the blob
241 **/
242@@ -95,7 +95,7 @@ clear a DATA_BLOB's contents
243 _PUBLIC_ void data_blob_clear(DATA_BLOB *d)
244 {
245 if (d->data) {
246- memset_s(d->data, d->length, 0, d->length);
247+ memset_explicit(d->data, 0, d->length);
248 }
249 }
250
251@@ -219,7 +219,7 @@ _PUBLIC_ DATA_BLOB data_blob_string_cons
252 }
253
254 /**
255- * Create a new data blob from const data
256+ * Create a new data blob from const data
257 */
258
259 _PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length)
260@@ -266,7 +266,7 @@ _PUBLIC_ bool data_blob_append(TALLOC_CT
261 if ((const uint8_t *)p + length < (const uint8_t *)p) {
262 return false;
263 }
264-
265+
266 if (!data_blob_realloc(mem_ctx, blob, new_len)) {
267 return false;
268 }
269--- a/lib/util/talloc_keep_secret.c
270+++ b/lib/util/talloc_keep_secret.c
271@@ -22,27 +22,13 @@
272
273 static int talloc_keep_secret_destructor(void *ptr)
274 {
275- int ret;
276 size_t size = talloc_get_size(ptr);
277
278 if (unlikely(size == 0)) {
279 return 0;
280 }
281
282- ret = memset_s(ptr, size, 0, size);
283- if (unlikely(ret != 0)) {
284- char *msg = NULL;
285- int ret2;
286- ret2 = asprintf(&msg,
287- "talloc_keep_secret_destructor: memset_s() failed: %s",
288- strerror(ret));
289- if (ret2 != -1) {
290- smb_panic(msg);
291- } else {
292- smb_panic("talloc_keep_secret_destructor: memset_s() failed");
293- }
294- }
295-
296+ memset_explicit(ptr, 0, size);
297 return 0;
298 }
299
300--- a/librpc/ndr/util.c
301+++ b/librpc/ndr/util.c
302@@ -32,5 +32,5 @@ _PUBLIC_ void ndr_print_sockaddr_storage
303
304 _PUBLIC_ void ndr_zero_memory(void *ptr, size_t len)
305 {
306- memset_s(ptr, len, 0, len);
307+ memset_explicit(ptr, 0, len);
308 }
diff --git a/meta-networking/recipes-connectivity/samba/samba/0004-lib-replace-Remove-memset_s.patch b/meta-networking/recipes-connectivity/samba/samba/0004-lib-replace-Remove-memset_s.patch
new file mode 100644
index 0000000000..409c36da7c
--- /dev/null
+++ b/meta-networking/recipes-connectivity/samba/samba/0004-lib-replace-Remove-memset_s.patch
@@ -0,0 +1,345 @@
1From 06b9291b4a351c5d3a40f6c80ee11713840b1039 Mon Sep 17 00:00:00 2001
2From: Andreas Schneider <asn@samba.org>
3Date: Thu, 16 Oct 2025 11:22:46 +0200
4Subject: [PATCH 4/4] lib:replace: Remove memset_s()
5
6Upstream-Status: Backport [https://gitlab.com/samba-team/samba/-/commit/f3b380b8a3866286244725903287211cf54a4e74]
7Signed-off-by: Andreas Schneider <asn@samba.org>
8Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
9
10Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
11Autobuild-Date(master): Tue Nov 11 14:51:45 UTC 2025 on atb-devel-224
12
13Signed-off-by: Khem Raj <raj.khem@gmail.com>
14---
15 lib/replace/README | 1 -
16 lib/replace/replace.c | 87 ++++++++-----------------
17 lib/replace/replace.h | 5 --
18 lib/replace/wscript | 2 +-
19 third_party/heimdal_build/roken.h | 4 --
20 third_party/heimdal_build/wscript_build | 5 ++
21 6 files changed, 34 insertions(+), 70 deletions(-)
22
23diff --git a/lib/replace/README b/lib/replace/README
24index bb9d008..d8431e7 100644
25--- a/lib/replace/README
26+++ b/lib/replace/README
27@@ -74,7 +74,6 @@ realpath
28 poll
29 setproctitle
30 memset_explicit
31-memset_s
32
33 Types:
34 bool
35diff --git a/lib/replace/replace.c b/lib/replace/replace.c
36index 8615899..a419837 100644
37--- a/lib/replace/replace.c
38+++ b/lib/replace/replace.c
39@@ -1,4 +1,4 @@
40-/*
41+/*
42 Unix SMB/CIFS implementation.
43 replacement routines for broken systems
44 Copyright (C) Andrew Tridgell 1992-1998
45@@ -8,7 +8,7 @@
46 ** NOTE! The following LGPL license applies to the replace
47 ** library. This does NOT imply that all of Samba is released
48 ** under the LGPL
49-
50+
51 This library is free software; you can redistribute it and/or
52 modify it under the terms of the GNU Lesser General Public
53 License as published by the Free Software Foundation; either
54@@ -91,7 +91,7 @@ size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
55 #endif
56
57 #ifndef HAVE_STRLCAT
58-/* like strncat but does not 0 fill the buffer and always null
59+/* like strncat but does not 0 fill the buffer and always null
60 terminates. bufsize is the length of the buffer, which should
61 be one more than the maximum resulting string length */
62 size_t rep_strlcat(char *d, const char *s, size_t bufsize)
63@@ -116,7 +116,7 @@ size_t rep_strlcat(char *d, const char *s, size_t bufsize)
64
65 #ifndef HAVE_MKTIME
66 /*******************************************************************
67-a mktime() replacement for those who don't have it - contributed by
68+a mktime() replacement for those who don't have it - contributed by
69 C.A. Lademann <cal@zls.com>
70 Corrections by richard.kettlewell@kewill.com
71 ********************************************************************/
72@@ -137,7 +137,7 @@ time_t rep_mktime(struct tm *t)
73 return((time_t)-1);
74
75 n = t->tm_year + 1900 - 1;
76- epoch = (t->tm_year - 70) * YEAR +
77+ epoch = (t->tm_year - 70) * YEAR +
78 ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
79
80 y = t->tm_year + 1900;
81@@ -147,7 +147,7 @@ time_t rep_mktime(struct tm *t)
82 epoch += mon [m] * DAY;
83 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
84 epoch += DAY;
85-
86+
87 if(++m > 11) {
88 m = 0;
89 y++;
90@@ -156,7 +156,7 @@ time_t rep_mktime(struct tm *t)
91
92 epoch += (t->tm_mday - 1) * DAY;
93 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
94-
95+
96 if((u = localtime(&epoch)) != NULL) {
97 t->tm_sec = u->tm_sec;
98 t->tm_min = u->tm_min;
99@@ -176,7 +176,7 @@ time_t rep_mktime(struct tm *t)
100
101 #ifndef HAVE_INITGROUPS
102 /****************************************************************************
103- some systems don't have an initgroups call
104+ some systems don't have an initgroups call
105 ****************************************************************************/
106 int rep_initgroups(char *name, gid_t id)
107 {
108@@ -194,7 +194,7 @@ int rep_initgroups(char *name, gid_t id)
109 int i,j;
110 struct group *g;
111 char *gr;
112-
113+
114 if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
115 errno = ENOMEM;
116 return -1;
117@@ -250,9 +250,9 @@ void *rep_memmove(void *dest,const void *src,int size)
118
119 if (d < s) {
120 /* we can forward copy */
121- if (s-d >= sizeof(int) &&
122- !(s%sizeof(int)) &&
123- !(d%sizeof(int)) &&
124+ if (s-d >= sizeof(int) &&
125+ !(s%sizeof(int)) &&
126+ !(d%sizeof(int)) &&
127 !(size%sizeof(int))) {
128 /* do it all as words */
129 int *idest = (int *)dest;
130@@ -267,9 +267,9 @@ void *rep_memmove(void *dest,const void *src,int size)
131 }
132 } else {
133 /* must backward copy */
134- if (d-s >= sizeof(int) &&
135- !(s%sizeof(int)) &&
136- !(d%sizeof(int)) &&
137+ if (d-s >= sizeof(int) &&
138+ !(s%sizeof(int)) &&
139+ !(d%sizeof(int)) &&
140 !(size%sizeof(int))) {
141 /* do it all as words */
142 int *idest = (int *)dest;
143@@ -281,7 +281,7 @@ void *rep_memmove(void *dest,const void *src,int size)
144 char *cdest = (char *)dest;
145 char *csrc = (char *)src;
146 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
147- }
148+ }
149 }
150 return(dest);
151 }
152@@ -334,16 +334,16 @@ void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
153 size_t rep_strnlen(const char *s, size_t max)
154 {
155 size_t len;
156-
157+
158 for (len = 0; len < max; len++) {
159 if (s[len] == '\0') {
160 break;
161 }
162 }
163- return len;
164+ return len;
165 }
166 #endif
167-
168+
169 #ifndef HAVE_STRNDUP
170 /**
171 Some platforms don't have strndup.
172@@ -351,7 +351,7 @@ void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
173 char *rep_strndup(const char *s, size_t n)
174 {
175 char *ret;
176-
177+
178 n = strnlen(s, n);
179 ret = malloc(n+1);
180 if (!ret)
181@@ -407,7 +407,7 @@ int rep_chroot(const char *dname)
182
183 /*****************************************************************
184 Possibly replace mkstemp if it is broken.
185-*****************************************************************/
186+*****************************************************************/
187
188 #ifndef HAVE_SECURE_MKSTEMP
189 int rep_mkstemp(char *template)
190@@ -425,7 +425,7 @@ int rep_mkstemp(char *template)
191 char *rep_mkdtemp(char *template)
192 {
193 char *dname;
194-
195+
196 if ((dname = mktemp(template))) {
197 if (mkdir(dname, 0700) >= 0) {
198 return dname;
199@@ -532,7 +532,7 @@ long long int rep_strtoll(const char *str, char **endptr, int base)
200 {
201 #ifdef HAVE_STRTOQ
202 return strtoq(str, endptr, base);
203-#elif defined(HAVE___STRTOLL)
204+#elif defined(HAVE___STRTOLL)
205 return __strtoll(str, endptr, base);
206 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
207 return (long long int) strtol(str, endptr, base);
208@@ -568,7 +568,7 @@ unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
209 {
210 #ifdef HAVE_STRTOUQ
211 return strtouq(str, endptr, base);
212-#elif defined(HAVE___STRTOULL)
213+#elif defined(HAVE___STRTOULL)
214 return __strtoull(str, endptr, base);
215 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
216 return (unsigned long long int) strtoul(str, endptr, base);
217@@ -599,7 +599,7 @@ unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
218 #endif /* HAVE_STRTOULL */
219
220 #ifndef HAVE_SETENV
221-int rep_setenv(const char *name, const char *value, int overwrite)
222+int rep_setenv(const char *name, const char *value, int overwrite)
223 {
224 char *p;
225 size_t l1, l2;
226@@ -644,10 +644,10 @@ int rep_unsetenv(const char *name)
227 for (i=0;environ[i];i++) /* noop */ ;
228
229 count=i;
230-
231+
232 for (i=0;i<count;) {
233 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
234- /* note: we do _not_ free the old variable here. It is unsafe to
235+ /* note: we do _not_ free the old variable here. It is unsafe to
236 do so, as the pointer may not have come from malloc */
237 memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
238 count--;
239@@ -688,7 +688,7 @@ int rep_utimes(const char *filename, const struct timeval tv[2])
240 #endif
241
242 #ifndef HAVE_DUP2
243-int rep_dup2(int oldfd, int newfd)
244+int rep_dup2(int oldfd, int newfd)
245 {
246 errno = ENOSYS;
247 return -1;
248@@ -965,37 +965,6 @@ void *rep_memset_explicit(void *block, int c, size_t size)
249 }
250 #endif
251
252-#ifndef HAVE_MEMSET_S
253-# ifndef RSIZE_MAX
254-# define RSIZE_MAX (SIZE_MAX >> 1)
255-# endif
256-
257-int rep_memset_s(void *dest, size_t destsz, int ch, size_t count)
258-{
259- if (dest == NULL) {
260- return EINVAL;
261- }
262-
263- if (destsz > RSIZE_MAX ||
264- count > RSIZE_MAX ||
265- count > destsz) {
266- return ERANGE;
267- }
268-
269-#if defined(HAVE_MEMSET_EXPLICIT)
270- memset_explicit(dest, destsz, ch, count);
271-#else /* HAVE_MEMSET_EXPLICIT */
272- memset(dest, ch, count);
273-# if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION)
274- /* See http://llvm.org/bugs/show_bug.cgi?id=15495 */
275- __asm__ volatile("" : : "g"(dest) : "memory");
276-# endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
277-#endif /* HAVE_MEMSET_EXPLICIT */
278-
279- return 0;
280-}
281-#endif /* HAVE_MEMSET_S */
282-
283 #ifndef HAVE_GETPROGNAME
284 # ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
285 # define PROGNAME_SIZE 32
286diff --git a/lib/replace/replace.h b/lib/replace/replace.h
287index 6b72c1f..24b2d8c 100644
288--- a/lib/replace/replace.h
289+++ b/lib/replace/replace.h
290@@ -999,11 +999,6 @@ void rep_setproctitle_init(int argc, char *argv[], char *envp[]);
291 void *rep_memset_explicit(void *block, int c, size_t size);
292 #endif
293
294-#ifndef HAVE_MEMSET_S
295-#define memset_s rep_memset_s
296-int rep_memset_s(void *dest, size_t destsz, int ch, size_t count);
297-#endif
298-
299 #ifndef HAVE_GETPROGNAME
300 #define getprogname rep_getprogname
301 const char *rep_getprogname(void);
302diff --git a/lib/replace/wscript b/lib/replace/wscript
303index 9acebd3..faef185 100644
304--- a/lib/replace/wscript
305+++ b/lib/replace/wscript
306@@ -881,7 +881,7 @@ REPLACEMENT_FUNCTIONS = {
307 'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink',
308 'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf',
309 'dprintf', 'get_current_dir_name', 'copy_file_range',
310- 'strerror_r', 'clock_gettime', 'memset_explicit', 'memset_s'],
311+ 'strerror_r', 'clock_gettime', 'memset_explicit'],
312 'timegm.c': ['timegm'],
313 # Note: C99_VSNPRINTF is not a function, but a special condition
314 # for replacement
315diff --git a/third_party/heimdal_build/roken.h b/third_party/heimdal_build/roken.h
316index 3870609..4740a3d 100644
317--- a/third_party/heimdal_build/roken.h
318+++ b/third_party/heimdal_build/roken.h
319@@ -123,10 +123,6 @@
320 #define HAVE_SETEUID
321 #endif
322
323-#ifndef HAVE_MEMSET_S
324-#define HAVE_MEMSET_S
325-#endif
326-
327 #ifndef HAVE_DIRFD
328 #ifdef HAVE_DIR_DD_FD
329 #define dirfd(x) ((x)->dd_fd)
330diff --git a/third_party/heimdal_build/wscript_build b/third_party/heimdal_build/wscript_build
331index 8aea52b..1988535 100644
332--- a/third_party/heimdal_build/wscript_build
333+++ b/third_party/heimdal_build/wscript_build
334@@ -366,6 +366,11 @@ if not bld.CONFIG_SET('USING_SYSTEM_ROKEN'):
335 lib/roken/getuserinfo.c
336 '''
337
338+ if not bld.CONFIG_SET('HAVE_MEMSET_S'):
339+ ROKEN_SOURCE += '''
340+ lib/roken/memset_s.c
341+ '''
342+
343 HEIMDAL_LIBRARY('roken',
344 ROKEN_SOURCE,
345 includes='../heimdal/lib/roken ../heimdal/include ../heimdal_build/include',
diff --git a/meta-networking/recipes-connectivity/samba/samba_4.19.9.bb b/meta-networking/recipes-connectivity/samba/samba_4.19.9.bb
index ae88705668..3ed1d46754 100644
--- a/meta-networking/recipes-connectivity/samba/samba_4.19.9.bb
+++ b/meta-networking/recipes-connectivity/samba/samba_4.19.9.bb
@@ -25,6 +25,10 @@ SRC_URI = "${SAMBA_MIRROR}/stable/samba-${PV}.tar.gz \
25 file://0006-smbtorture-skip-test-case-tfork_cmd_send.patch \ 25 file://0006-smbtorture-skip-test-case-tfork_cmd_send.patch \
26 file://0007-Deleted-settiong-of-python-to-fix-the-install-confli.patch \ 26 file://0007-Deleted-settiong-of-python-to-fix-the-install-confli.patch \
27 file://9aa5c43315d83c19514251a11c4fba5a137f2821.patch \ 27 file://9aa5c43315d83c19514251a11c4fba5a137f2821.patch \
28 file://0001-lib-replace-Implement-memset_explicit.patch \
29 file://0002-lib-replace-Add-test-for-memset_explicit.patch \
30 file://0003-Replace-memset_s-with-memset_explicit.patch \
31 file://0004-lib-replace-Remove-memset_s.patch \
28 " 32 "
29 33
30SRC_URI:append:libc-musl = " \ 34SRC_URI:append:libc-musl = " \