The branch, v4-14-stable has been updated via 0490e756e11 VERSION: Bump version up to 4.14.0rc3. via 486f38219b1 WHATSNEW: Add release notes for Samba 4.14.0rc3. via dedae240651 classicupgrade: treat old never expires value right via ecb41890f10 s3:pysmbd: fix fd leak in py_smbd_create_file() via a6f228f6754 HEIMDAL: krb5_storage_free(NULL) should work via 938b89616a1 lib:util: Avoid free'ing our own pointer via 27d93c8d46a lib:util: Add cache oversize test for memcache via 805b8be9497 lib:util: Add basic memcache unit test via ea2f9ebf787 VERSION: Bump version up to Samba 4.14.0rc3... from 3b1235240f3 VERSION: Disable GIT_SNAPSHOT for the 4.14.0rc2 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-14-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 18 ++++- lib/util/memcache.c | 19 ++++- lib/util/tests/test_memcache.c | 161 +++++++++++++++++++++++++++++++++++++++ lib/util/wscript_build | 6 ++ python/samba/upgrade.py | 2 +- selftest/tests.py | 2 + source3/smbd/pysmbd.c | 3 + source4/heimdal/lib/krb5/store.c | 2 + 9 files changed, 208 insertions(+), 7 deletions(-) create mode 100644 lib/util/tests/test_memcache.c Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index b14af4687ac..485e6eb0aa1 100644 --- a/VERSION +++ b/VERSION @@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=2 +SAMBA_VERSION_RC_RELEASE=3 ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 890e6313fe9..ca597378c9e 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,7 +1,7 @@ Release Announcements ===================== -This is the second release candidate of Samba 4.14. This is *not* +This is the third release candidate of Samba 4.14. This is *not* intended for production environments and is designed for testing purposes only. Please report any defects via the Samba bug reporting system at https://bugzilla.samba.org/. @@ -203,6 +203,22 @@ smb.conf changes server smb encrypt New default +CHANGES SINCE 4.14.0rc2 +======================= + +o Björn Jacke <b...@sernet.de> + * BUG 14624: classicupgrade: Treat old never expires value right. + +o Stefan Metzmacher <me...@samba.org> + * BUG 13898: s3:pysmbd: fix fd leak in py_smbd_create_file(). + +o Andreas Schneider <a...@samba.org> + * BUG 14625: Fix smbd share mode double free crash. + +o Paul Wise <pa...@bonedaddy.net> + * BUG 12505: HEIMDAL: krb5_storage_free(NULL) should work. + + CHANGES SINCE 4.14.0rc1 ======================= diff --git a/lib/util/memcache.c b/lib/util/memcache.c index 1e616bd0e9a..7b0b27eaddb 100644 --- a/lib/util/memcache.c +++ b/lib/util/memcache.c @@ -223,14 +223,25 @@ static void memcache_delete_element(struct memcache *cache, TALLOC_FREE(e); } -static void memcache_trim(struct memcache *cache) +static void memcache_trim(struct memcache *cache, struct memcache_element *e) { + struct memcache_element *tail = NULL; + if (cache->max_size == 0) { return; } - while ((cache->size > cache->max_size) && DLIST_TAIL(cache->mru)) { - memcache_delete_element(cache, DLIST_TAIL(cache->mru)); + for (tail = DLIST_TAIL(cache->mru); + (cache->size > cache->max_size) && (tail != NULL); + tail = DLIST_TAIL(cache->mru)) + { + if (tail == e) { + tail = DLIST_PREV(tail); + if (tail == NULL) { + break; + } + } + memcache_delete_element(cache, tail); } } @@ -351,7 +362,7 @@ void memcache_add(struct memcache *cache, enum memcache_number n, memcpy(&mtv, cache_value.data, sizeof(mtv)); cache->size += mtv.len; } - memcache_trim(cache); + memcache_trim(cache, e); } void memcache_add_talloc(struct memcache *cache, enum memcache_number n, diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c new file mode 100644 index 00000000000..8a3997817c1 --- /dev/null +++ b/lib/util/tests/test_memcache.c @@ -0,0 +1,161 @@ +/* + * Unix SMB/CIFS implementation. + * + * Copyright (C) 2021 Andreas Schneider <a...@samba.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <setjmp.h> +#include <cmocka.h> + +#include "lib/replace/replace.h" +#include "lib/util/talloc_stack.h" +#include "lib/util/memcache.h" + +static int setup_talloc_context(void **state) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + *state = frame; + return 0; +} + +static int teardown_talloc_context(void **state) +{ + TALLOC_CTX *frame = *state; + TALLOC_FREE(frame); + return 0; +} + +static void torture_memcache_init(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct memcache *cache = NULL; + + cache = memcache_init(mem_ctx, 0); + assert_non_null(cache); + + TALLOC_FREE(cache); + + cache = memcache_init(mem_ctx, 10); + assert_non_null(cache); + + TALLOC_FREE(cache); +} + +static void torture_memcache_add_lookup_delete(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct memcache *cache = NULL; + DATA_BLOB key1, key2; + char *path1 = NULL, *path2 = NULL; + + cache = memcache_init(mem_ctx, 0); + assert_non_null(cache); + + key1 = data_blob_const("key1", 4); + path1 = talloc_strdup(mem_ctx, "/tmp/one"); + assert_non_null(path1); + + key2 = data_blob_const("key2", 4); + path2 = talloc_strdup(mem_ctx, "/tmp/two"); + assert_non_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key1, &path1); + assert_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key2, &path2); + assert_null(path2); + + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1); + assert_non_null(path1); + assert_string_equal(path1, "/tmp/one"); + + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); + assert_non_null(path2); + assert_string_equal(path2, "/tmp/two"); + + memcache_delete(cache, GETWD_CACHE, key1); + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1); + assert_null(path1); + + memcache_flush(cache, GETWD_CACHE); + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); + assert_null(path2); + + TALLOC_FREE(path1); + TALLOC_FREE(path2); + TALLOC_FREE(cache); +} + +static void torture_memcache_add_oversize(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct memcache *cache = NULL; + DATA_BLOB key1, key2; + char *path1 = NULL, *path2 = NULL; + + cache = memcache_init(mem_ctx, 10); + assert_non_null(cache); + + key1 = data_blob_const("key1", 4); + path1 = talloc_strdup(mem_ctx, "/tmp/one"); + assert_non_null(path1); + + key2 = data_blob_const("key2", 4); + path2 = talloc_strdup(mem_ctx, "/tmp/two"); + assert_non_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key1, &path1); + assert_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key2, &path2); + assert_null(path2); + + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1); + assert_null(path1); + + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); + assert_non_null(path2); + assert_string_equal(path2, "/tmp/two"); + + TALLOC_FREE(path1); + TALLOC_FREE(path2); + TALLOC_FREE(cache); +} + +int main(int argc, char *argv[]) +{ + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_memcache_init), + cmocka_unit_test(torture_memcache_add_lookup_delete), + cmocka_unit_test(torture_memcache_add_oversize), + }; + + if (argc == 2) { + cmocka_set_test_filter(argv[1]); + } + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); + + rc = cmocka_run_group_tests(tests, + setup_talloc_context, + teardown_talloc_context); + + return rc; +} diff --git a/lib/util/wscript_build b/lib/util/wscript_build index 000c9be6f4f..460661e9a63 100644 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -350,3 +350,9 @@ else: deps='cmocka replace talloc samba-util', local_include=False, for_selftest=True) + + bld.SAMBA_BINARY('test_memcache', + source='tests/test_memcache.c', + deps='cmocka replace talloc samba-util', + local_include=False, + for_selftest=True) diff --git a/python/samba/upgrade.py b/python/samba/upgrade.py index 8511bed2868..dff856a8d7c 100644 --- a/python/samba/upgrade.py +++ b/python/samba/upgrade.py @@ -74,7 +74,7 @@ def import_sam_policy(samdb, policy, logger): if 'maximum password age' in policy: max_pw_age_unix = policy['maximum password age'] - if max_pw_age_unix == -1 or max_pw_age_unix == 0: + if max_pw_age_unix == -1 or max_pw_age_unix == 0 or max_pw_age_unix == 0xFFFFFFFF: max_pw_age_nt = -0x8000000000000000 else: max_pw_age_nt = int(-max_pw_age_unix * (1e7)) diff --git a/selftest/tests.py b/selftest/tests.py index 381586eb868..6bf46ae5621 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -405,6 +405,8 @@ plantestsuite("samba.unittests.util_paths", "none", [os.path.join(bindir(), "default/lib/util/test_util_paths")]) plantestsuite("samba.unittests.util", "none", [os.path.join(bindir(), "default/lib/util/test_util")]) +plantestsuite("samba.unittests.memcache", "none", + [os.path.join(bindir(), "default/lib/util/test_memcache")]) plantestsuite("samba.unittests.ntlm_check", "none", [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")]) plantestsuite("samba.unittests.gnutls", "none", diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 042e31b79d6..3ef4fd7c248 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -1183,9 +1183,12 @@ static PyObject *py_smbd_create_file(PyObject *self, PyObject *args, PyObject *k if (!NT_STATUS_IS_OK(status)) { DBG_ERR("init_files_struct failed: %s\n", nt_errstr(status)); + } else if (fsp != NULL) { + SMB_VFS_CLOSE(fsp); } TALLOC_FREE(frame); + PyErr_NTSTATUS_NOT_OK_RAISE(status); Py_RETURN_NONE; } diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c index 17de78e9e74..31afb23c983 100644 --- a/source4/heimdal/lib/krb5/store.c +++ b/source4/heimdal/lib/krb5/store.c @@ -270,6 +270,8 @@ krb5_storage_get_eof_code(krb5_storage *sp) KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_storage_free(krb5_storage *sp) { + if (sp == NULL) + return 0; if(sp->free) (*sp->free)(sp); free(sp->data); -- Samba Shared Repository