diff --git a/backport-0001-CVE-2021-44142.patch b/backport-0001-CVE-2021-44142.patch new file mode 100644 index 0000000000000000000000000000000000000000..1e9e5cd1b95e1d2597497937f56ecadaa7fc7565 --- /dev/null +++ b/backport-0001-CVE-2021-44142.patch @@ -0,0 +1,31 @@ +From eee61be9b5867b63b73b0b1fea03f44a4e1235b7 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Thu, 13 Jan 2022 16:48:01 +0100 +Subject: [PATCH 03/99] CVE-2021-44142: libadouble: add defines for icon + lengths + +From https://www.ietf.org/rfc/rfc1740.txt + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + source3/lib/adouble.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source3/lib/adouble.h b/source3/lib/adouble.h +index 8b14d0ab871..de44f3f5fdc 100644 +--- a/source3/lib/adouble.h ++++ b/source3/lib/adouble.h +@@ -101,6 +101,8 @@ typedef enum {ADOUBLE_META, ADOUBLE_RSRC} adouble_type_t; + #define ADEDLEN_MACFILEI 4 + #define ADEDLEN_PRODOSFILEI 8 + #define ADEDLEN_MSDOSFILEI 2 ++#define ADEDLEN_ICONBW 128 ++#define ADEDLEN_ICONCOL 1024 + #define ADEDLEN_DID 4 + #define ADEDLEN_PRIVDEV 8 + #define ADEDLEN_PRIVINO 8 +-- +2.25.1 diff --git a/backport-0001-CVE-2022-0336.patch b/backport-0001-CVE-2022-0336.patch new file mode 100644 index 0000000000000000000000000000000000000000..39c54958ffc33ed4a89d637ef972b656bc20d0ad --- /dev/null +++ b/backport-0001-CVE-2022-0336.patch @@ -0,0 +1,52 @@ +From d392b10c55bbcedda01fdd87fe6035fa3a6986b3 Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Tue, 18 Jan 2022 11:56:38 +1300 +Subject: [PATCH 01/99] CVE-2022-0336: pytest: Add a test for an SPN conflict + with a re-added SPN + +This test currently fails, as re-adding an SPN means that later checks +do not run. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14950 + +Signed-off-by: Joseph Sutton +Reviewed-by: Douglas Bagnall +--- + python/samba/tests/ldap_spn.py | 7 +++++++ + selftest/knownfail.d/ldap_spn | 1 + + 2 files changed, 8 insertions(+) + +diff --git a/python/samba/tests/ldap_spn.py b/python/samba/tests/ldap_spn.py +index 8a398ffaa49..6ebdf8f9a32 100644 +--- a/python/samba/tests/ldap_spn.py ++++ b/python/samba/tests/ldap_spn.py +@@ -268,6 +268,8 @@ class LdapSpnTestBase(TestCase): + for k in ('dNSHostName', 'servicePrincipalName'): + if isinstance(m.get(k), str): + m[k] = m[k].format(dnsname=f"x.{REALM}") ++ elif isinstance(m.get(k), list): ++ m[k] = [x.format(dnsname=f"x.{REALM}") for x in m[k]] + + msg = ldb.Message.from_dict(samdb, m, op) + +@@ -727,6 +729,11 @@ class LdapSpnSambaOnlyTest(LdapSpnTestBase): + ('user:C', 'host/{dnsname}', '*', ok), + ('user:D', 'www/{dnsname}', 'D', denied), + ), ++ ("add a conflict, along with a re-added SPN", ++ ('A', 'cifs/{dnsname}', '*', ok), ++ ('B', 'cifs/heeble.example.net', 'B', ok), ++ ('B', ['cifs/heeble.example.net', 'host/{dnsname}'], 'B', constraint), ++ ), + + ("changing dNSHostName after host", + ('A', {'dNSHostName': '{dnsname}'}, '*', ok), +diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn +index 63f9fe02ef7..16dafa91b66 100644 +--- a/selftest/knownfail.d/ldap_spn ++++ b/selftest/knownfail.d/ldap_spn +@@ -1 +1,2 @@ + samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns ++samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_along_with_a_re_added_SPN +-- +2.25.1 diff --git a/backport-0002-CVE-2021-44142.patch b/backport-0002-CVE-2021-44142.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ce8fec077a35fdd55f2db7f81d0974213ea62d9 --- /dev/null +++ b/backport-0002-CVE-2021-44142.patch @@ -0,0 +1,38 @@ +From 22b4091924977f6437b59627f33a8e6f02b41011 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Sat, 20 Nov 2021 16:36:42 +0100 +Subject: [PATCH 04/99] CVE-2021-44142: smbd: add Netatalk xattr used by + vfs_fruit to the list of private Samba xattrs + +This is an internal xattr that should not be user visible. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + source3/smbd/trans2.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index a86ac3228e3..4f6d92955cf 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -46,6 +46,7 @@ + #include "libcli/smb/smb2_posix.h" + #include "lib/util/string_wrappers.h" + #include "source3/lib/substitute.h" ++#include "source3/lib/adouble.h" + + #define DIR_ENTRY_SAFETY_MARGIN 4096 + +@@ -203,6 +204,7 @@ bool samba_private_attr_name(const char *unix_ea_name) + SAMBA_XATTR_DOS_ATTRIB, + SAMBA_XATTR_MARKER, + XATTR_NTACL_NAME, ++ AFPINFO_EA_NETATALK, + NULL + }; + +-- +2.25.1 diff --git a/backport-0002-CVE-2022-0336.patch b/backport-0002-CVE-2022-0336.patch new file mode 100644 index 0000000000000000000000000000000000000000..57943e86a5991c8c9233910f4b3e618bd59199a1 --- /dev/null +++ b/backport-0002-CVE-2022-0336.patch @@ -0,0 +1,41 @@ +From 7a516257ea310fa045bdf14e677eaa97f2a83c33 Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Tue, 18 Jan 2022 12:02:45 +1300 +Subject: [PATCH 02/99] CVE-2022-0336: s4/dsdb/samldb: Don't return early when + an SPN is re-added to an object + +If an added SPN already exists on an object, we still want to check the +rest of the element values for conflicts. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14950 + +Signed-off-by: Joseph Sutton +Reviewed-by: Douglas Bagnall +--- + selftest/knownfail.d/ldap_spn | 1 - + source4/dsdb/samdb/ldb_modules/samldb.c | 3 +-- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn +index 16dafa91b66..63f9fe02ef7 100644 +--- a/selftest/knownfail.d/ldap_spn ++++ b/selftest/knownfail.d/ldap_spn +@@ -1,2 +1 @@ + samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns +-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_along_with_a_re_added_SPN +diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c +index db3883eb527..24971d521aa 100644 +--- a/source4/dsdb/samdb/ldb_modules/samldb.c ++++ b/source4/dsdb/samdb/ldb_modules/samldb.c +@@ -4006,8 +4006,7 @@ static int samldb_spn_uniqueness_check(struct samldb_ctx *ac, + ac->msg->dn); + if (ret == LDB_ERR_COMPARE_TRUE) { + DBG_INFO("SPN %s re-added to the same object\n", spn); +- talloc_free(tmp_ctx); +- return LDB_SUCCESS; ++ continue; + } + if (ret != LDB_SUCCESS) { + DBG_ERR("SPN %s failed direct uniqueness check\n", spn); +-- +2.25.1 diff --git a/backport-0003-CVE-2021-44142.patch b/backport-0003-CVE-2021-44142.patch new file mode 100644 index 0000000000000000000000000000000000000000..316275ff6da93cc24fb85d4d12c4b0f2695ac2ec --- /dev/null +++ b/backport-0003-CVE-2021-44142.patch @@ -0,0 +1,67 @@ +From b4c0b4620f12055207adb0519c8d91c3021f354a Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Fri, 26 Nov 2021 07:19:32 +0100 +Subject: [PATCH 05/99] CVE-2021-44142: libadouble: harden ad_unpack_xattrs() + +This ensures ad_unpack_xattrs() is only called for an ad_type of ADOUBLE_RSRC, +which is used for parsing ._ AppleDouble sidecar files, and the buffer +ad->ad_data is AD_XATTR_MAX_HDR_SIZE bytes large which is a prerequisite for all +buffer out-of-bounds access checks in ad_unpack_xattrs(). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + source3/lib/adouble.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c +index f809a445081..6cbe8a5aeda 100644 +--- a/source3/lib/adouble.c ++++ b/source3/lib/adouble.c +@@ -707,14 +707,27 @@ static bool ad_pack(struct vfs_handle_struct *handle, + static bool ad_unpack_xattrs(struct adouble *ad) + { + struct ad_xattr_header *h = &ad->adx_header; ++ size_t bufsize = talloc_get_size(ad->ad_data); + const char *p = ad->ad_data; + uint32_t hoff; + uint32_t i; + ++ if (ad->ad_type != ADOUBLE_RSRC) { ++ return false; ++ } ++ + if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) { + return true; + } + ++ /* ++ * Ensure the buffer ad->ad_data was allocated by ad_alloc() for an ++ * ADOUBLE_RSRC type (._ AppleDouble file on-disk). ++ */ ++ if (bufsize != AD_XATTR_MAX_HDR_SIZE) { ++ return false; ++ } ++ + /* 2 bytes padding */ + hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2; + +@@ -964,9 +977,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries, + ad->ad_eid[eid].ade_len = len; + } + +- ok = ad_unpack_xattrs(ad); +- if (!ok) { +- return false; ++ if (ad->ad_type == ADOUBLE_RSRC) { ++ ok = ad_unpack_xattrs(ad); ++ if (!ok) { ++ return false; ++ } + } + + return true; +-- +2.25.1 diff --git a/backport-0004-CVE-2021-44142.patch b/backport-0004-CVE-2021-44142.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c5c36b32159656037285a7293eee2d39443040f --- /dev/null +++ b/backport-0004-CVE-2021-44142.patch @@ -0,0 +1,451 @@ +From 4533a7b4319cd95815d2dcd5fe5075539fb850e5 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Thu, 25 Nov 2021 15:04:03 +0100 +Subject: [PATCH 06/99] CVE-2021-44142: libadouble: add basic cmocka tests + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +[slow@samba.org: conflict due to missing test in selftest/tests.py] +--- + selftest/knownfail.d/samba.unittests.adouble | 3 + + selftest/tests.py | 2 + + source3/lib/test_adouble.c | 389 +++++++++++++++++++ + source3/wscript_build | 5 + + 4 files changed, 399 insertions(+) + create mode 100644 selftest/knownfail.d/samba.unittests.adouble + create mode 100644 source3/lib/test_adouble.c + +diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble +new file mode 100644 +index 00000000000..8b0314f2fae +--- /dev/null ++++ b/selftest/knownfail.d/samba.unittests.adouble +@@ -0,0 +1,3 @@ ++^samba.unittests.adouble.parse_abouble_finderinfo2\(none\) ++^samba.unittests.adouble.parse_abouble_finderinfo3\(none\) ++^samba.unittests.adouble.parse_abouble_date2\(none\) +diff --git a/selftest/tests.py b/selftest/tests.py +index e7338985caf..c87b41c1a66 100644 +--- a/selftest/tests.py ++++ b/selftest/tests.py +@@ -434,3 +434,5 @@ if with_elasticsearch_backend: + [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) + plantestsuite("samba.unittests.credentials", "none", + [os.path.join(bindir(), "default/auth/credentials/test_creds")]) ++plantestsuite("samba.unittests.adouble", "none", ++ [os.path.join(bindir(), "test_adouble")]) +diff --git a/source3/lib/test_adouble.c b/source3/lib/test_adouble.c +new file mode 100644 +index 00000000000..615c22469c9 +--- /dev/null ++++ b/source3/lib/test_adouble.c +@@ -0,0 +1,389 @@ ++/* ++ * Unix SMB/CIFS implementation. ++ * ++ * Copyright (C) 2021 Ralph Boehme ++ * ++ * 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 . ++ */ ++ ++#include "adouble.c" ++#include ++ ++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; ++} ++ ++/* ++ * Basic and sane buffer. ++ */ ++static uint8_t ad_basic[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * An empty FinderInfo entry. ++ */ ++static uint8_t ad_finderinfo1[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */ ++ 0x00, 0x00, 0x00, 0x00, /* len: 0, so off+len don't exceed bufferlen */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A dangerous FinderInfo with correct length exceeding buffer by one byte. ++ */ ++static uint8_t ad_finderinfo2[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */ ++ 0x00, 0x00, 0x00, 0x20, /* len: 32, so off+len exceeds bufferlen by 1 */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++static uint8_t ad_finderinfo3[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */ ++ 0x00, 0x00, 0x00, 0x1f, /* len: 31, so off+len don't exceed buf */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A dangerous name entry. ++ */ ++static uint8_t ad_name[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Name */ ++ 0x00, 0x00, 0x00, 0x03, /* eid: Name */ ++ 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */ ++ 0x00, 0x00, 0x00, 0x01, /* len: 1, so off+len exceeds bufferlen */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A empty ADEID_FILEDATESI entry. ++ */ ++static uint8_t ad_date1[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Dates */ ++ 0x00, 0x00, 0x00, 0x08, /* eid: dates */ ++ 0x00, 0x00, 0x00, 0x52, /* off: end of buffer */ ++ 0x00, 0x00, 0x00, 0x00, /* len: 0, empty entry, valid */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A dangerous ADEID_FILEDATESI entry, invalid length. ++ */ ++static uint8_t ad_date2[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Dates */ ++ 0x00, 0x00, 0x00, 0x08, /* eid: dates */ ++ 0x00, 0x00, 0x00, 0x43, /* off: FinderInfo buf but one byte short */ ++ 0x00, 0x00, 0x00, 0x0f, /* len: 15, so off+len don't exceed bufferlen */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++static struct adouble *parse_adouble(TALLOC_CTX *mem_ctx, ++ uint8_t *adbuf, ++ size_t adsize, ++ off_t filesize) ++{ ++ struct adouble *ad = NULL; ++ bool ok; ++ ++ ad = talloc_zero(mem_ctx, struct adouble); ++ ad->ad_data = talloc_zero_size(ad, adsize); ++ assert_non_null(ad); ++ ++ memcpy(ad->ad_data, adbuf, adsize); ++ ++ ok = ad_unpack(ad, 2, filesize); ++ if (!ok) { ++ return NULL; ++ } ++ ++ return ad; ++} ++ ++static void parse_abouble_basic(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ char *p = NULL; ++ ++ ad = parse_adouble(frame, ad_basic, sizeof(ad_basic), 0xffffff52); ++ assert_non_null(ad); ++ ++ p = ad_get_entry(ad, ADEID_FINDERI); ++ assert_non_null(p); ++ ++ return; ++} ++ ++static void parse_abouble_finderinfo1(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ char *p = NULL; ++ ++ ad = parse_adouble(frame, ++ ad_finderinfo1, ++ sizeof(ad_finderinfo1), ++ 0xffffff52); ++ assert_non_null(ad); ++ ++ p = ad_get_entry(ad, ADEID_FINDERI); ++ assert_null(p); ++ ++ return; ++} ++ ++static void parse_abouble_finderinfo2(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ++ ad_finderinfo2, ++ sizeof(ad_finderinfo2), ++ 0xffffff52); ++ assert_null(ad); ++ ++ return; ++} ++ ++static void parse_abouble_finderinfo3(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ++ ad_finderinfo3, ++ sizeof(ad_finderinfo3), ++ 0xffffff52); ++ assert_null(ad); ++ ++ return; ++} ++ ++static void parse_abouble_name(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ad_name, sizeof(ad_name), 0x52); ++ assert_null(ad); ++ ++ return; ++} ++ ++static void parse_abouble_date1(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ char *p = NULL; ++ ++ ad = parse_adouble(frame, ad_date1, sizeof(ad_date1), 0x52); ++ assert_non_null(ad); ++ ++ p = ad_get_entry(ad, ADEID_FILEDATESI); ++ assert_null(p); ++ ++ return; ++} ++ ++static void parse_abouble_date2(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ad_date2, sizeof(ad_date2), 0x52); ++ assert_null(ad); ++ ++ return; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int rc; ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(parse_abouble_basic), ++ cmocka_unit_test(parse_abouble_finderinfo1), ++ cmocka_unit_test(parse_abouble_finderinfo2), ++ cmocka_unit_test(parse_abouble_finderinfo3), ++ cmocka_unit_test(parse_abouble_name), ++ cmocka_unit_test(parse_abouble_date1), ++ cmocka_unit_test(parse_abouble_date2), ++ }; ++ ++ 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/source3/wscript_build b/source3/wscript_build +index 69febb53750..9df9bdd35b7 100644 +--- a/source3/wscript_build ++++ b/source3/wscript_build +@@ -1085,6 +1085,11 @@ bld.SAMBA3_SUBSYSTEM('ADOUBLE', + source='lib/adouble.c', + deps='STRING_REPLACE') + ++bld.SAMBA3_BINARY('test_adouble', ++ source='lib/test_adouble.c', ++ deps='smbd_base STRING_REPLACE cmocka', ++ for_selftest=True) ++ + bld.SAMBA3_SUBSYSTEM('STRING_REPLACE', + source='lib/string_replace.c') + +-- +2.25.1 diff --git a/backport-0005-CVE-2021-44142.patch b/backport-0005-CVE-2021-44142.patch new file mode 100644 index 0000000000000000000000000000000000000000..bb490fcd5b844a75bc436654870c3ad3489035fe --- /dev/null +++ b/backport-0005-CVE-2021-44142.patch @@ -0,0 +1,169 @@ + +From 0e2b3fb982d1f53d111e10d9197ed2ec2e13712c Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Thu, 13 Jan 2022 17:03:02 +0100 +Subject: [PATCH 07/99] CVE-2021-44142: libadouble: harden parsing code + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + selftest/knownfail.d/samba.unittests.adouble | 3 - + source3/lib/adouble.c | 115 ++++++++++++++++--- + 2 files changed, 101 insertions(+), 17 deletions(-) + delete mode 100644 selftest/knownfail.d/samba.unittests.adouble + +diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble +deleted file mode 100644 +index 8b0314f2fae..00000000000 +--- a/selftest/knownfail.d/samba.unittests.adouble ++++ /dev/null +@@ -1,3 +0,0 @@ +-^samba.unittests.adouble.parse_abouble_finderinfo2\(none\) +-^samba.unittests.adouble.parse_abouble_finderinfo3\(none\) +-^samba.unittests.adouble.parse_abouble_date2\(none\) +diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c +index 6cbe8a5aeda..37fb686f17b 100644 +--- a/source3/lib/adouble.c ++++ b/source3/lib/adouble.c +@@ -269,6 +269,95 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off) + return ad->ad_eid[eid].ade_off = off; + } + ++/* ++ * All entries besides FinderInfo and resource fork must fit into the ++ * buffer. FinderInfo is special as it may be larger then the default 32 bytes ++ * if it contains marshalled xattrs, which we will fixup that in ++ * ad_convert(). The first 32 bytes however must also be part of the buffer. ++ * ++ * The resource fork is never accessed directly by the ad_data buf. ++ */ ++static bool ad_entry_check_size(uint32_t eid, ++ size_t bufsize, ++ uint32_t off, ++ uint32_t got_len) ++{ ++ struct { ++ off_t expected_len; ++ bool fixed_size; ++ bool minimum_size; ++ } ad_checks[] = { ++ [ADEID_DFORK] = {-1, false, false}, /* not applicable */ ++ [ADEID_RFORK] = {-1, false, false}, /* no limit */ ++ [ADEID_NAME] = {ADEDLEN_NAME, false, false}, ++ [ADEID_COMMENT] = {ADEDLEN_COMMENT, false, false}, ++ [ADEID_ICONBW] = {ADEDLEN_ICONBW, true, false}, ++ [ADEID_ICONCOL] = {ADEDLEN_ICONCOL, false, false}, ++ [ADEID_FILEI] = {ADEDLEN_FILEI, true, false}, ++ [ADEID_FILEDATESI] = {ADEDLEN_FILEDATESI, true, false}, ++ [ADEID_FINDERI] = {ADEDLEN_FINDERI, false, true}, ++ [ADEID_MACFILEI] = {ADEDLEN_MACFILEI, true, false}, ++ [ADEID_PRODOSFILEI] = {ADEDLEN_PRODOSFILEI, true, false}, ++ [ADEID_MSDOSFILEI] = {ADEDLEN_MSDOSFILEI, true, false}, ++ [ADEID_SHORTNAME] = {ADEDLEN_SHORTNAME, false, false}, ++ [ADEID_AFPFILEI] = {ADEDLEN_AFPFILEI, true, false}, ++ [ADEID_DID] = {ADEDLEN_DID, true, false}, ++ [ADEID_PRIVDEV] = {ADEDLEN_PRIVDEV, true, false}, ++ [ADEID_PRIVINO] = {ADEDLEN_PRIVINO, true, false}, ++ [ADEID_PRIVSYN] = {ADEDLEN_PRIVSYN, true, false}, ++ [ADEID_PRIVID] = {ADEDLEN_PRIVID, true, false}, ++ }; ++ ++ if (eid >= ADEID_MAX) { ++ return false; ++ } ++ if (got_len == 0) { ++ /* Entry present, but empty, allow */ ++ return true; ++ } ++ if (ad_checks[eid].expected_len == 0) { ++ /* ++ * Shouldn't happen: implicitly initialized to zero because ++ * explicit initializer missing. ++ */ ++ return false; ++ } ++ if (ad_checks[eid].expected_len == -1) { ++ /* Unused or no limit */ ++ return true; ++ } ++ if (ad_checks[eid].fixed_size) { ++ if (ad_checks[eid].expected_len != got_len) { ++ /* Wrong size fo fixed size entry. */ ++ return false; ++ } ++ } else { ++ if (ad_checks[eid].minimum_size) { ++ if (got_len < ad_checks[eid].expected_len) { ++ /* ++ * Too small for variable sized entry with ++ * minimum size. ++ */ ++ return false; ++ } ++ } else { ++ if (got_len > ad_checks[eid].expected_len) { ++ /* Too big for variable sized entry. */ ++ return false; ++ } ++ } ++ } ++ if (off + got_len < off) { ++ /* wrap around */ ++ return false; ++ } ++ if (off + got_len > bufsize) { ++ /* overflow */ ++ return false; ++ } ++ return true; ++} ++ + /** + * Return a pointer to an AppleDouble entry + * +@@ -276,8 +365,15 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off) + **/ + char *ad_get_entry(const struct adouble *ad, int eid) + { ++ size_t bufsize = talloc_get_size(ad->ad_data); + off_t off = ad_getentryoff(ad, eid); + size_t len = ad_getentrylen(ad, eid); ++ bool valid; ++ ++ valid = ad_entry_check_size(eid, bufsize, off, len); ++ if (!valid) { ++ return NULL; ++ } + + if (off == 0 || len == 0) { + return NULL; +@@ -914,20 +1010,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries, + return false; + } + +- /* +- * All entries besides FinderInfo and resource fork +- * must fit into the buffer. FinderInfo is special as +- * it may be larger then the default 32 bytes (if it +- * contains marshalled xattrs), but we will fixup that +- * in ad_convert(). And the resource fork is never +- * accessed directly by the ad_data buf (also see +- * comment above) anyway. +- */ +- if ((eid != ADEID_RFORK) && +- (eid != ADEID_FINDERI) && +- ((off + len) > bufsize)) { +- DEBUG(1, ("bogus eid %d: off: %" PRIu32 ", len: %" PRIu32 "\n", +- eid, off, len)); ++ ok = ad_entry_check_size(eid, bufsize, off, len); ++ if (!ok) { ++ DBG_ERR("bogus eid [%"PRIu32"] bufsize [%zu] " ++ "off [%"PRIu32"] len [%"PRIu32"]\n", ++ eid, bufsize, off, len); + return false; + } + +-- +2.25.1 diff --git a/samba.spec b/samba.spec index 9480844c1026d23945befd9d9478342b84c7c9d3..01018105856f8a74e2207e59ebafe916c447dbbe 100644 --- a/samba.spec +++ b/samba.spec @@ -49,7 +49,7 @@ Name: samba Version: 4.15.3 -Release: 2 +Release: 3 Summary: A suite for Linux to interoperate with Windows License: GPLv3+ and LGPLv3+ @@ -66,6 +66,14 @@ Source7: samba.pamd Source201: README.downgrade +Patch0: backport-0001-CVE-2021-44142.patch +Patch1: backport-0002-CVE-2021-44142.patch +Patch2: backport-0003-CVE-2021-44142.patch +Patch3: backport-0004-CVE-2021-44142.patch +Patch4: backport-0005-CVE-2021-44142.patch +Patch5: backport-0001-CVE-2022-0336.patch +Patch6: backport-0002-CVE-2022-0336.patch + BuildRequires: avahi-devel bison dbus-devel docbook-style-xsl e2fsprogs-devel flex gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel BuildRequires: jansson-devel krb5-devel >= %{required_mit_krb5} libacl-devel libaio-devel libarchive-devel libattr-devel BuildRequires: libcap-devel libicu-devel libcmocka-devel libtirpc-devel libuuid-devel libxslt lmdb ncurses-devel openldap-devel @@ -3378,6 +3386,12 @@ fi %endif %changelog +* Tue Feb 15 2022 gaihuiying - 4.15.3-3 +- Type:cves +- ID:CVE-2022-0336 CVE-2021-44142 +- SUG:NA +- DESC:backport to fix CVE-2022-0336 CVE-2021-44142 + * Mon Jan 17 2022 gaihuiying - 4.15.3-2 - Type:bugfix - ID:NA