The branch, master has been updated via d385058ce7c CVE-2022-3592 smbd: Slightly simplify filename_convert_dirfsp() via d905dbddf8d CVE-2022-3592 lib: Move subdir_of() to source3/lib/util_path.c via fbc0feeca40 CVE-2022-3592 lib: lib/util/fault.h requires _SAMBA_DEBUG_H for SMB_ASSERT() via c770b7872da CVE-2022-3592 torture3: Show that our symlink traversal checks are insecure via dc650bde6f9 CVE-2022-3592 smbd: No empty path components in openat_pathref_dirfsp_nosymlink() via 2671f995fed CVE-2022-3437 third_party/heimdal: Pass correct length to _gssapi_verify_pad() via d12bd2cd50b CVE-2022-3437 third_party/heimdal: Check for overflow in _gsskrb5_get_mech() via 2d0ad4ede7b CVE-2022-3437 third_party/heimdal: Check buffer length against overflow for DES{,3} unwrap via 841b6ddcf2a CVE-2022-3437 third_party/heimdal: Check the result of _gsskrb5_get_mech() via ba60f647524 CVE-2022-3437 third_party/heimdal: Avoid undefined behaviour in _gssapi_verify_pad() via ad9d1690ed5 CVE-2022-3437 third_party/heimdal: Don't pass NULL pointers to memcpy() in DES unwrap via dffc997adac CVE-2022-3437 third_party/heimdal: Use constant-time memcmp() in unwrap_des3() via 16120b736f2 CVE-2022-3437 third_party/heimdal: Use constant-time memcmp() for arcfour unwrap via c8e85295c98 CVE-2022-3437 s4/auth/tests: Add unit tests for unwrap_des3() via ec456766d53 CVE-2022-3437 third_party/heimdal_build: Add gssapi-subsystem subsystem via cd48f2da59f CVE-2022-3437 third_party/heimdal: Remove __func__ compatibility workaround from ce7c418ca4f python/samba/tests: fix samba.tests.auth_log_pass_change for later gnutls
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit d385058ce7c9914ea58613f65414e45f2f777481 Author: Volker Lendecke <v...@samba.org> Date: Sat Oct 15 13:37:17 2022 +0200 CVE-2022-3592 smbd: Slightly simplify filename_convert_dirfsp() subdir_of() calculates the share-relative rest for us, don't do the strlen(connectpath) calculation twice. subdir_of() also checks that the target properly ends on a directory. With just strncmp a symlink to x->/aa/etc would qualify as in share /a, so a "get x/passwd" leads to a pretty unfortunate result. This is the proper fix for bug 15207, so we need to change the expected error code to OBJECT_PATH_NOT_FOUND Bug: https://bugzilla.samba.org/show_bug.cgi?id=15207 Signed-off-by: Volker Lendecke <v...@samba.org> Autobuild-User(master): Jule Anger <jan...@samba.org> Autobuild-Date(master): Tue Oct 25 11:27:02 UTC 2022 on sn-devel-184 commit d905dbddf8d2655e6c91752b750cbe9c15837ee5 Author: Volker Lendecke <v...@samba.org> Date: Sat Oct 15 13:29:14 2022 +0200 CVE-2022-3592 lib: Move subdir_of() to source3/lib/util_path.c Make it available for other components Bug: https://bugzilla.samba.org/show_bug.cgi?id=15207 Signed-off-by: Volker Lendecke <v...@samba.org> commit fbc0feeca4061c4e1a2543b0a24c4333c1532587 Author: Volker Lendecke <v...@samba.org> Date: Sat Oct 15 13:26:48 2022 +0200 CVE-2022-3592 lib: lib/util/fault.h requires _SAMBA_DEBUG_H for SMB_ASSERT() fault.h has: which leads to SMB_ASSERT not being defined when you include samba_util.h (and thus fault.h) before debug.h. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15207 Signed-off-by: Volker Lendecke <v...@samba.org> commit c770b7872daae21e5ead57374707d7ac334c8f69 Author: Volker Lendecke <v...@samba.org> Date: Sat Oct 15 14:09:55 2022 +0200 CVE-2022-3592 torture3: Show that our symlink traversal checks are insecure This test shows that we don't properly check whether symlink targets are inside the exported share. Linking to <share-root>a/etc makes us loop back into filename_convert_dirfsp_nosymlink() with /etc as a directory name. On Linux systems with openat2(RESOLVE_NO_SYMLINKS) we pass "/etc" directly into that call after some checks for "."/".." as invalid file name components. "/etc" is okay for openat2(), but this test must also succeed on systems without RESOLVE_NO_SYMLINKS (sn-devel-184 for example). On systems without RESOLVE_NO_SYMLINKS split up the path "/etc" into path components, in this case "" and "etc". So we pass "" down to openat(), which correctly fails with ENOENT. Summary: Only with RESOLVE_NO_SYMLINKS we're hit by bug 15207, and this test shows by expecting CONNECTION_DISCONNECTED that we violate the internal assumption of empty path components with an unexpected symlink target, making it testable on systems with and without RESOLVE_NO_SYMLINKS. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15207 Signed-off-by: Volker Lendecke <v...@samba.org> commit dc650bde6f97ea63d6105ead874b0249307db13b Author: Volker Lendecke <v...@samba.org> Date: Mon Oct 17 18:06:02 2022 +0200 CVE-2022-3592 smbd: No empty path components in openat_pathref_dirfsp_nosymlink() Upper layers must have filtered this, everything else is a bug Bug: https://bugzilla.samba.org/show_bug.cgi?id=15207 Signed-off-by: Volker Lendecke <v...@samba.org> commit 2671f995fed735bb03d9efd55d6603b35141ff38 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:57:33 2022 +1300 CVE-2022-3437 third_party/heimdal: Pass correct length to _gssapi_verify_pad() We later subtract 8 when calculating the length of the output message buffer. If padlength is excessively high, this calculation can underflow and result in a very large positive value. Now we properly constrain the value of padlength so underflow shouldn't be possible. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d12bd2cd50b45e064e5bea5a99c826ef156b4e64 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Mon Oct 10 20:33:09 2022 +1300 CVE-2022-3437 third_party/heimdal: Check for overflow in _gsskrb5_get_mech() If len_len is equal to total_len - 1 (i.e. the input consists only of a 0x60 byte and a length), the expression 'total_len - 1 - len_len - 1', used as the 'len' parameter to der_get_length(), will overflow to SIZE_MAX. Then der_get_length() will proceed to read, unconstrained, whatever data follows in memory. Add a check to ensure that doesn't happen. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 2d0ad4ede7b391af3f38cd3664dc04c7ceea76e8 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Mon Aug 15 16:54:23 2022 +1200 CVE-2022-3437 third_party/heimdal: Check buffer length against overflow for DES{,3} unwrap BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 841b6ddcf2a80c085ed6159ec9d420f37ceb691e Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Mon Aug 15 16:53:55 2022 +1200 CVE-2022-3437 third_party/heimdal: Check the result of _gsskrb5_get_mech() We should make sure that the result of 'total_len - mech_len' won't overflow, and that we don't memcmp() past the end of the buffer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ba60f647524ec12b3b5901680c5922d6b2490420 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Mon Aug 15 16:53:45 2022 +1200 CVE-2022-3437 third_party/heimdal: Avoid undefined behaviour in _gssapi_verify_pad() By decrementing 'pad' only when we know it's safe, we ensure we can't stray backwards past the start of a buffer, which would be undefined behaviour. In the previous version of the loop, 'i' is the number of bytes left to check, and 'pad' is the current byte we're checking. 'pad' was decremented at the end of each loop iteration. If 'i' was 1 (so we checked the final byte), 'pad' could potentially be pointing to the first byte of the input buffer, and the decrement would put it one byte behind the buffer. That would be undefined behaviour. The patch changes it so that 'pad' is the byte we previously checked, which allows us to ensure that we only decrement it when we know we have a byte to check. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ad9d1690ed51d73fbfb7dcb07c6ecb7750cab290 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:57:42 2022 +1300 CVE-2022-3437 third_party/heimdal: Don't pass NULL pointers to memcpy() in DES unwrap BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit dffc997adaccaa0980911b62473470cb80969700 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:57:55 2022 +1300 CVE-2022-3437 third_party/heimdal: Use constant-time memcmp() in unwrap_des3() The surrounding checks all use ct_memcmp(), so this one was presumably meant to as well. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 16120b736f28e85e7b46f8c69b7aa02073b2e26c Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:57:13 2022 +1300 CVE-2022-3437 third_party/heimdal: Use constant-time memcmp() for arcfour unwrap BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit c8e85295c988d653c3c425e0c4b8900f30fa1bba Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:55:39 2022 +1300 CVE-2022-3437 s4/auth/tests: Add unit tests for unwrap_des3() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ec456766d53da45c9d3edcb382569768cbef60dd Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:55:51 2022 +1300 CVE-2022-3437 third_party/heimdal_build: Add gssapi-subsystem subsystem This allows us to access (and so test) functions internal to GSSAPI by depending on this subsystem. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit cd48f2da59f48caa20e7ac652c958182671e804b Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Oct 12 13:56:08 2022 +1300 CVE-2022-3437 third_party/heimdal: Remove __func__ compatibility workaround As described by the C standard, __func__ is a variable, not a macro. Hence this #ifndef check does not work as intended, and only serves to unconditionally disable __func__. A nonoperating __func__ prevents cmocka operating correctly, so remove this definition. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15134 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/tests.py | 5 + source3/lib/util_path.c | 52 +- source3/lib/util_path.h | 4 + .../script/tests/test_symlink_traversal_smb2.sh | 4 + source3/smbd/filename.c | 11 +- source3/smbd/files.c | 6 + source3/smbd/open.c | 52 - source4/auth/tests/heimdal_unwrap_des.c | 1244 ++++++++++++++++++++ source4/auth/wscript_build | 21 + third_party/heimdal/lib/gssapi/krb5/arcfour.c | 14 +- third_party/heimdal/lib/gssapi/krb5/decapsulate.c | 12 +- third_party/heimdal/lib/gssapi/krb5/unwrap.c | 34 +- third_party/heimdal/lib/krb5/krb5_locl.h | 4 - third_party/heimdal_build/wscript_build | 18 +- 14 files changed, 1394 insertions(+), 87 deletions(-) create mode 100644 source4/auth/tests/heimdal_unwrap_des.c Changeset truncated at 500 lines: diff --git a/selftest/tests.py b/selftest/tests.py index 46d301956ed..db43d8a9e7d 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -47,6 +47,8 @@ with_pam = ("WITH_PAM" in config_hash) with_elasticsearch_backend = ("HAVE_SPOTLIGHT_BACKEND_ES" in config_hash) pam_wrapper_so_path = config_hash.get("LIBPAM_WRAPPER_SO_PATH") pam_set_items_so_path = config_hash.get("PAM_SET_ITEMS_SO_PATH") +have_heimdal_support = "SAMBA4_USES_HEIMDAL" in config_hash +using_system_gssapi = "USING_SYSTEM_GSSAPI" in config_hash planpythontestsuite("none", "samba.tests.source") planpythontestsuite("none", "samba.tests.source_chars") @@ -449,6 +451,9 @@ plantestsuite("samba.unittests.test_oLschema2ldif", "none", [os.path.join(bindir(), "default/source4/utils/oLschema2ldif/test_oLschema2ldif")]) plantestsuite("samba.unittests.auth.sam", "none", [os.path.join(bindir(), "test_auth_sam")]) +if have_heimdal_support and not using_system_gssapi: + plantestsuite("samba.unittests.auth.heimdal_gensec_unwrap_des", "none", + [valgrindify(os.path.join(bindir(), "test_heimdal_gensec_unwrap_des"))]) if with_elasticsearch_backend: plantestsuite("samba.unittests.mdsparser_es", "none", [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c index 5b7c01b05e3..5a94b391dd6 100644 --- a/source3/lib/util_path.c +++ b/source3/lib/util_path.c @@ -23,8 +23,8 @@ #include "replace.h" #include <talloc.h> -#include "lib/util/samba_util.h" #include "lib/util/debug.h" +#include "lib/util/samba_util.h" #include "lib/util_path.h" struct loadparm_substitution; @@ -304,3 +304,53 @@ bool extract_snapshot_token(char *fname, NTTIME *twrp) return true; } + +/* + * Take two absolute paths, figure out if "subdir" is a proper + * subdirectory of "parent". Return the component relative to the + * "parent" without the potential "/". Take care of "parent" + * possibly ending in "/". + */ +bool subdir_of(const char *parent, + size_t parent_len, + const char *subdir, + const char **_relative) +{ + const char *relative = NULL; + bool matched; + + SMB_ASSERT(parent[0] == '/'); + SMB_ASSERT(subdir[0] == '/'); + + if (parent_len == 1) { + /* + * Everything is below "/" + */ + *_relative = subdir+1; + return true; + } + + if (parent[parent_len-1] == '/') { + parent_len -= 1; + } + + matched = (strncmp(subdir, parent, parent_len) == 0); + if (!matched) { + return false; + } + + relative = &subdir[parent_len]; + + if (relative[0] == '\0') { + *_relative = relative; /* nothing left */ + return true; + } + + if (relative[0] == '/') { + /* End of parent must match a '/' in subdir. */ + *_relative = relative+1; + return true; + } + + return false; +} diff --git a/source3/lib/util_path.h b/source3/lib/util_path.h index 33699da28c2..5b0a1f13e38 100644 --- a/source3/lib/util_path.h +++ b/source3/lib/util_path.h @@ -49,5 +49,9 @@ bool clistr_is_previous_version_path(const char *path, const char **startp, const char **endp, NTTIME *ptwrp); +bool subdir_of(const char *parent, + size_t parent_len, + const char *subdir, + const char **_relative); #endif diff --git a/source3/script/tests/test_symlink_traversal_smb2.sh b/source3/script/tests/test_symlink_traversal_smb2.sh index efd4353c533..38719cc8eae 100755 --- a/source3/script/tests/test_symlink_traversal_smb2.sh +++ b/source3/script/tests/test_symlink_traversal_smb2.sh @@ -144,6 +144,9 @@ chmod 0 "$dir_outside_share_noperms" mkdir "dir_inside_share_noperms/noperm_subdir_exists" touch "dir_inside_share_noperms/noperm_subdir_exists/noperm_subdir_file_exists" chmod 0 "dir_inside_share_noperms" + + # Symlink pointing out of the share + ln -s "$share_test_dir"a"/etc" x ) # @@ -345,6 +348,7 @@ test_symlink_traversal_SMB2() smbclient_expect_error "get" "symlink_to_dir_exists/subdir_exists" "" "NT_STATUS_FILE_IS_A_DIRECTORY" || return 1 smbclient_expect_error "get" "symlink_to_dir_exists/subdir_exists/noexist1" "" "NT_STATUS_OBJECT_NAME_NOT_FOUND" || return 1 smbclient_expect_error "get" "symlink_to_dir_exists/subdir_exists/noexist1/noexist2" "" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 + smbclient_expect_error "get" "x/passwd" "passwd" "NT_STATUS_OBJECT_PATH_NOT_FOUND" || return 1 # # Test paths within share with no permissions. diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 79bb7dffe99..5bfa4b2f1df 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1369,6 +1369,7 @@ NTSTATUS filename_convert_dirfsp( struct smb_filename **_smb_fname) { char *substitute = NULL; + const char *relative = NULL; size_t unparsed = 0; NTSTATUS status; char *target = NULL; @@ -1441,17 +1442,17 @@ next: DBG_DEBUG("abs_target_canon=%s\n", abs_target_canon); - in_share = strncmp( - abs_target_canon, + in_share = subdir_of( conn->connectpath, - strlen(conn->connectpath)) == 0; + strlen(conn->connectpath), + abs_target_canon, + &relative); if (!in_share) { DBG_DEBUG("wide link to %s\n", abs_target_canon); return NT_STATUS_OBJECT_PATH_NOT_FOUND; } - name_in = talloc_strdup( - mem_ctx, abs_target_canon + strlen(conn->connectpath) + 1); + name_in = talloc_strdup(mem_ctx, relative); symlink_redirects += 1; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 87c1f0f6301..64297f18773 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -817,6 +817,12 @@ NTSTATUS openat_pathref_dirfsp_nosymlink( next = strv_next(path, rel_fname.base_name); + /* + * Path sanitizing further up has cleaned or rejected + * empty path components. Assert this here. + */ + SMB_ASSERT(rel_fname.base_name[0] != '\0'); + if (ISDOT(rel_fname.base_name) || ISDOTDOT(rel_fname.base_name)) { DBG_DEBUG("%s contains a dot\n", path_in); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 9d85b0d8ef8..d4a679a4cb0 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -475,58 +475,6 @@ static NTSTATUS check_base_file_access(struct files_struct *fsp, access_mask); } -/* - * Take two absolute paths, figure out if "subdir" is a proper - * subdirectory of "parent". Return the component relative to the - * "parent" without the potential "/". Take care of "parent" - * possibly ending in "/". - */ -static bool subdir_of( - const char *parent, - size_t parent_len, - const char *subdir, - const char **_relative) - -{ - const char *relative = NULL; - bool matched; - - SMB_ASSERT(parent[0] == '/'); - SMB_ASSERT(subdir[0] == '/'); - - if (parent_len == 1) { - /* - * Everything is below "/" - */ - *_relative = subdir+1; - return true; - } - - if (parent[parent_len-1] == '/') { - parent_len -= 1; - } - - matched = (strncmp(subdir, parent, parent_len) == 0); - if (!matched) { - return false; - } - - relative = &subdir[parent_len]; - - if (relative[0] == '\0') { - *_relative = relative; /* nothing left */ - return true; - } - - if (relative[0] == '/') { - /* End of parent must match a '/' in subdir. */ - *_relative = relative+1; - return true; - } - - return false; -} - static NTSTATUS chdir_below_conn( TALLOC_CTX *mem_ctx, connection_struct *conn, diff --git a/source4/auth/tests/heimdal_unwrap_des.c b/source4/auth/tests/heimdal_unwrap_des.c new file mode 100644 index 00000000000..fbfe7782e7e --- /dev/null +++ b/source4/auth/tests/heimdal_unwrap_des.c @@ -0,0 +1,1244 @@ +/* + * Unit tests for third_party/heimdal/lib/gssapi/krb5/unwrap.c + * + * Copyright (C) Catalyst.NET Ltd 2022 + * + * 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/>. + * + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include <stdarg.h> + * #include <stddef.h> + * #include <setjmp.h> + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ + +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> + +#include <cmocka.h> + +#include "includes.h" +#include "replace.h" + +#include "../../../third_party/heimdal/lib/gssapi/gssapi/gssapi.h" +#include "gsskrb5_locl.h" + +/****************************************************************************** + * Helper functions + ******************************************************************************/ + +const uint8_t *valid_range_begin; +const uint8_t *valid_range_end; +const uint8_t *invalid_range_end; + +/* + * 'array_len' is the size of the passed in array. 'buffer_len' is the size to + * report in the resulting buffer. + */ +static const gss_buffer_desc get_input_buffer(TALLOC_CTX *mem_ctx, + const uint8_t array[], + const size_t array_len, + const size_t buffer_len) +{ + gss_buffer_desc buf; + + /* Add some padding to catch invalid memory accesses. */ + const size_t padding = 0x100; + const size_t padded_len = array_len + padding; + + uint8_t *data = talloc_size(mem_ctx, padded_len); + assert_non_null(data); + + memcpy(data, array, array_len); + memset(data + array_len, 0, padding); + + assert_in_range(buffer_len, 0, array_len); + + buf.value = data; + buf.length = buffer_len; + + valid_range_begin = buf.value; + valid_range_end = valid_range_begin + buf.length; + invalid_range_end = valid_range_begin + padded_len; + + return buf; +} + +static void assert_mem_in_valid_range(const uint8_t *ptr, const size_t len) +{ + /* Ensure we've set up the range pointers properly. */ + assert_non_null(valid_range_begin); + assert_non_null(valid_range_end); + assert_non_null(invalid_range_end); + + /* + * Ensure the length isn't excessively large (a symptom of integer + * underflow). + */ + assert_in_range(len, 0, 0x1000); + + /* Ensure the memory is in our valid range. */ + assert_in_range(ptr, valid_range_begin, valid_range_end); + assert_in_range(ptr + len, valid_range_begin, valid_range_end); +} + +/* + * This function takes a pointer to volatile to allow it to be called from the + * ct_memcmp() wrapper. + */ +static void assert_mem_outside_invalid_range(const volatile uint8_t *ptr, + const size_t len) +{ + const LargestIntegralType _valid_range_end + = cast_ptr_to_largest_integral_type(valid_range_end); + const LargestIntegralType _invalid_range_end + = cast_ptr_to_largest_integral_type(invalid_range_end); + const LargestIntegralType _ptr = cast_ptr_to_largest_integral_type(ptr); + const LargestIntegralType _len = cast_to_largest_integral_type(len); + + /* Ensure we've set up the range pointers properly. */ + assert_non_null(valid_range_begin); + assert_non_null(valid_range_end); + assert_non_null(invalid_range_end); + + /* + * Ensure the length isn't excessively large (a symptom of integer + * underflow). + */ + assert_in_range(len, 0, 0x1000); + + /* Ensure the memory is outside the invalid range. */ + if (_ptr < _invalid_range_end && _ptr + _len > _valid_range_end) { + fail(); + } +} + +/***************************************************************************** + * wrapped functions + *****************************************************************************/ + +krb5_keyblock dummy_key; + +krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock **keyblock); +krb5_error_code __wrap_krb5_auth_con_getlocalsubkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock **keyblock) +{ + *keyblock = &dummy_key; + return 0; +} + +void __wrap_krb5_free_keyblock(krb5_context context, + krb5_keyblock *keyblock); +void __wrap_krb5_free_keyblock(krb5_context context, + krb5_keyblock *keyblock) +{ + assert_ptr_equal(&dummy_key, keyblock); +} + +struct krb5_crypto_data dummy_crypto; + +krb5_error_code __wrap_krb5_crypto_init(krb5_context context, + const krb5_keyblock *key, + krb5_enctype etype, + krb5_crypto *crypto); +krb5_error_code __wrap_krb5_crypto_init(krb5_context context, + const krb5_keyblock *key, + krb5_enctype etype, + krb5_crypto *crypto) +{ + static const LargestIntegralType etypes[] = {ETYPE_DES3_CBC_NONE, 0}; + + assert_ptr_equal(&dummy_key, key); + assert_in_set(etype, etypes, ARRAY_SIZE(etypes)); + + *crypto = &dummy_crypto; + + return 0; +} + +krb5_error_code __wrap_krb5_decrypt(krb5_context context, + krb5_crypto crypto, + unsigned usage, + void *data, + size_t len, + krb5_data *result); +krb5_error_code __wrap_krb5_decrypt(krb5_context context, + krb5_crypto crypto, + unsigned usage, + void *data, + size_t len, + krb5_data *result) +{ + assert_ptr_equal(&dummy_crypto, crypto); + assert_int_equal(KRB5_KU_USAGE_SEAL, usage); + + assert_mem_in_valid_range(data, len); + + check_expected(len); + check_expected_ptr(data); + + result->data = malloc(len); + assert_non_null(result->data); + result->length = len; + + memcpy(result->data, data, len); + + return 0; +} + +krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context, + krb5_crypto crypto, + unsigned usage, + void *data, + size_t len, + krb5_data *result, + void *ivec); +krb5_error_code __wrap_krb5_decrypt_ivec(krb5_context context, + krb5_crypto crypto, + unsigned usage, + void *data, + size_t len, + krb5_data *result, + void *ivec) +{ + assert_ptr_equal(&dummy_crypto, crypto); + assert_int_equal(KRB5_KU_USAGE_SEQ, usage); + + assert_mem_in_valid_range(data, len); + + assert_int_equal(8, len); + check_expected_ptr(data); + check_expected_ptr(ivec); + + result->data = malloc(len); + assert_non_null(result->data); + result->length = len; + + memcpy(result->data, data, len); + + return 0; +} + +krb5_error_code __wrap_krb5_verify_checksum(krb5_context context, + krb5_crypto crypto, + krb5_key_usage usage, + void *data, + size_t len, + Checksum *cksum); -- Samba Shared Repository