Bug 14334 (CVE-2020-10704) - CVE-2020-10704 [FUZZING][SECURITY] Stack overflow in AD DC (C)LDAP server
Summary: CVE-2020-10704 [FUZZING][SECURITY] Stack overflow in AD DC (C)LDAP server
Status: RESOLVED FIXED
Alias: CVE-2020-10704
Product: Samba 4.1 and newer
Classification: Unclassified
Component: AD: LDB/DSDB/SAMDB (show other bugs)
Version: 4.12.0
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Karolin Seeger
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks: 14349
  Show dependency treegraph
 
Reported: 2020-04-02 02:14 UTC by Andrew Bartlett
Modified: 2020-05-05 06:25 UTC (History)
4 users (show)

See Also:


Attachments
Proposed patch for master (17.50 KB, patch)
2020-04-02 19:57 UTC, Gary Lockyer
no flags Details
a packet for ldap_decode that should fail with the new restriction (970 bytes, application/octet-stream)
2020-04-03 03:18 UTC, Andrew Bartlett
no flags Details
packet with 10,000 OR expressions (crashes Samba with restricted stack) (38.94 KB, application/octet-stream)
2020-04-05 20:44 UTC, Andrew Bartlett
no flags Details
'exploit' script (294 bytes, text/x-python)
2020-04-05 20:45 UTC, Andrew Bartlett
no flags Details
A script to use as SAMBA_VALGRIND=/tmp/ulimit-samba to run samba under a ulimit trivially (28 bytes, application/x-shellscript)
2020-04-05 20:48 UTC, Andrew Bartlett
no flags Details
Proposes patch for master v2 (78.94 KB, patch)
2020-04-14 04:04 UTC, Gary Lockyer
no flags Details
Proposed patch for master V3 (79.79 KB, patch)
2020-04-14 04:54 UTC, Gary Lockyer
no flags Details
Proposed patch for master V4 (79.93 KB, patch)
2020-04-14 21:15 UTC, Gary Lockyer
abartlet: review+
Details
Patch for Master (v5) (80.33 KB, patch)
2020-04-15 20:54 UTC, Gary Lockyer
abartlet: review+
gary: ci-passed+
Details
Patch for V4.12 (v5) (80.35 KB, patch)
2020-04-15 20:55 UTC, Gary Lockyer
abartlet: review+
gary: ci-passed+
Details
Patch for V4.11 (v5) (78.96 KB, patch)
2020-04-15 21:10 UTC, Gary Lockyer
abartlet: review+
gary: ci-passed+
Details
Patch for V4.10 (v5) (79.98 KB, patch)
2020-04-16 05:14 UTC, Gary Lockyer
gary: ci-passed+
Details
Advisory v1 with release versions (3.81 KB, text/plain)
2020-04-16 08:24 UTC, Andrew Bartlett
no flags Details
Advisory v2 with release versions (3.91 KB, text/plain)
2020-04-16 20:32 UTC, Andrew Bartlett
dbagnall: review+
gary: review+
dbagnall: review+
abartlet: review+
Details
Patch for V4.10 (v6) (80.13 KB, patch)
2020-04-16 20:54 UTC, Gary Lockyer
abartlet: review+
gary: ci-passed+
Details
Patch for V4.5 (v5) (39.34 KB, patch)
2020-04-16 21:29 UTC, Gary Lockyer
abartlet: review+
gary: ci-passed+
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Bartlett 2020-04-02 02:14:30 UTC
Fuzzing by oss-fuzz has disclosed that a recursive LDAP filter can cause a stack overflow in ldap_decode()

We need to prevent the recursive ASN.1 definitions from allowing a stack overflow in Samba.

The tests so far only fail when ASAN is in use, but this is just a matter of degree, not a matter of substance, as a larger more recursive packet can be presented.

See also CVE-2018-0739 in OpenSSL for PKCS#7 for where this has happened before.
Comment 2 Andrew Bartlett 2020-04-02 04:35:24 UTC
Note that this is very similar to the already public
 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19736#c3
as that issue was mistakenly marked as fixed when a much more minor issue was addressed.
Comment 3 Gary Lockyer 2020-04-02 19:57:18 UTC
Created attachment 15889 [details]
Proposed patch for master

Currently running CI
Comment 4 Andrew Bartlett 2020-04-02 23:48:03 UTC
Comment on attachment 15889 [details]
Proposed patch for master

+ * Note that this test needs to be run with ASAN enabled, as it checks a stack
+ * overflow condition.

I think this is not correct, the test now fails on all hosts, right?
Comment 5 Gary Lockyer 2020-04-03 00:34:15 UTC
Comment on attachment 15889 [details]
Proposed patch for master

Ok this patch is obsolete, am going to move tests into asn1_start_tag.
So will get reworked.
Comment 6 Gary Lockyer 2020-04-03 00:38:00 UTC
Yeah that comment is not quite correct will reword it.
Comment 7 Andrew Bartlett 2020-04-03 03:18:47 UTC
Created attachment 15893 [details]
a packet for ldap_decode that should fail with the new restriction
Comment 8 Andrew Bartlett 2020-04-05 20:44:51 UTC
Created attachment 15894 [details]
packet with 10,000 OR expressions (crashes Samba with restricted stack)

When samba is started under ulimit -s '120', this packet crashes the LDAP server.

prefork_child_pipe_handler: Parent 3372, Child 3408 terminated with signal 11

There is no current protection in Samba that should mean a larger packet cannot be created to crash a more realistic stack, but larger packets are difficult to create with our client tools.
Comment 9 Andrew Bartlett 2020-04-05 20:45:20 UTC
Created attachment 15895 [details]
'exploit' script
Comment 10 Andrew Bartlett 2020-04-05 20:48:00 UTC
Created attachment 15896 [details]
A script to use as SAMBA_VALGRIND=/tmp/ulimit-samba to run samba under a ulimit trivially

This script helps testing this issue by running 'samba' but not the rest of our selftest system under a restricted stack.
Comment 11 Andrew Bartlett 2020-04-05 22:21:03 UTC
Testing combinations of stack limits and filter complexity, it seems Samba uses up to 600 bytes of stack for each or element, so for each byte of input (an OR is two bytes of ASN.1 as I understand it) we get ~300 bytes of stack uses.

So a 27k packet can use 8.1MB of stack (the default), presumably. 

I got (SIGSEGV with disconnect)

OR    stack (kb)
  450    120
 5000   1200
10000   2400

and SIGSEGV after disconnect (presumably in the talloc_free())

5000    2400
2000    1200
Comment 12 Howard Chu 2020-04-05 23:59:32 UTC
Just fyi, on x86-64 I see 224 bytes of stack per OR in OpenLDAP. That means our crash limit is around 37449 nested ORs with the default thread stack size that we use. I suppose we ought to impose a limit here as well.
Comment 13 Howard Chu 2020-04-06 00:05:42 UTC
What's your timeline for publicizing this? I can patch this pretty quickly in OpenLDAP. When will a patch for this be visible in the Samba source tree, and when will this bug report be public? I'll file a corresponding bug in OpenLDAP
and publish concurrently.
Comment 14 Andrew Bartlett 2020-04-06 00:28:34 UTC
(In reply to Howard Chu from comment #13)
Thanks.  Very happy to co-ordinate.   

Our process is here: https://wiki.samba.org/index.php/Security_release_process

Release dates are selected by our Release Manager (Karolin), but it is safe to say we have a few weeks to run yet.

If 10 days notice be enough for you then you can take your cue from the announcement that will be posted here when we open this up to our vendors.  Otherwise let us know what you need and we will do our best to work with you.
Comment 15 Andrew Bartlett 2020-04-06 02:17:53 UTC
As to dates and deadlines: the next oss-fuzz report to be made public by Google will be on 30 April or so, with a possible 14 day extension possible.
Comment 16 Andrew Bartlett 2020-04-06 02:39:25 UTC
CVSSv3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (7.5)
Comment 17 Andrew Bartlett 2020-04-06 03:28:27 UTC
I've confirmed 389ds does not appear to be impacted, they seem to have had, since the CVS import in 2005, a parameter nsslapd-max-filter-nest-level, which may have a default of 40 (hard to tell exactly with a grep).
Comment 18 Andrew Bartlett 2020-04-06 05:13:15 UTC
Windows 2019 as an AD DC resets the connection with not adverse impacts noticed if more than 500 OR statements are used.  I've got a general query in with them for this limit, but I'm going to assume there is no need to co-ordinate with Microsoft on this issue.
Comment 19 Gary Lockyer 2020-04-14 04:04:54 UTC
Created attachment 15906 [details]
Proposes patch for master v2

Currently running CI
Comment 20 Gary Lockyer 2020-04-14 04:54:08 UTC
Created attachment 15907 [details]
Proposed patch for master V3
Comment 21 Andrew Bartlett 2020-04-14 05:46:19 UTC
Looking really good.

As ldapsrv_check_packet_size() will be called a *lot*, please re-write it so that it calls security_token_is_anonymous() only if the packet is larger than the anonymous limit.  

In ldapsrv_packet_check() remove the talloc_get_type(), while good safety again this is in a very hot path.

I don't really like that in the cmocka test binaries that finding the data file is done by reference to the current working directory, but I can't find a better example.
Comment 22 Gary Lockyer 2020-04-14 21:15:09 UTC
Created attachment 15910 [details]
Proposed patch for master V4

CI running now, incorporates review feedback.
Comment 23 Andrew Bartlett 2020-04-14 21:57:19 UTC
Comment on attachment 15910 [details]
Proposed patch for master V4

Looks great.
Comment 28 Andrew Bartlett 2020-04-16 06:07:12 UTC
Comment on attachment 15917 [details]
Patch for V4.10 (v5)

This looks OK, but I don't see how the Python2 compatibility patch works.

The 'pass' statement is a no-op, implemented as as a syntax aid just like an extra ; in C.  The comment is repeated in the second test.  You mean self.skipTest("Can't run on Python2"), but as it is a no-op, have you instead fixed the test somehow?

If you can look at this again please that would be great. 

Thanks!
Comment 29 Volker Lendecke 2020-04-16 06:14:23 UTC
Question: Shouln't we abort in

@@ -703,6 +713,9 @@ bool asn1_end_tag(struct asn1_data *data)
 {
 	struct nesting *nesting;
 
+	if (data->depth > 0) {
+		data->depth--;
+	}

if data->depth is already 0?

Not for this bug of course, but in a later patch.
Comment 30 Andrew Bartlett 2020-04-16 08:24:35 UTC
Created attachment 15918 [details]
Advisory v1 with release versions
Comment 31 Gary Lockyer 2020-04-16 20:11:23 UTC
(In reply to Andrew Bartlett from comment #28)
It looks like I've attached the wrong patch. I'll take some time this morning and check it in detail.
Comment 32 Gary Lockyer 2020-04-16 20:12:39 UTC
(In reply to Volker Lendecke from comment #29)
Yeah that makes sense, I'll do that once this lot lands.  Am also planning to write some more tests.
Comment 33 Andrew Bartlett 2020-04-16 20:32:17 UTC
Created attachment 15920 [details]
Advisory v2 with release versions
Comment 34 Gary Lockyer 2020-04-16 20:54:23 UTC
Created attachment 15922 [details]
Patch for V4.10 (v6)

CI: https://gitlab.catalyst.net.nz/samba/samba.org-security-patches/pipelines/203092

Patch generated from the correct branch.
Comment 35 Gary Lockyer 2020-04-16 21:29:07 UTC
Created attachment 15923 [details]
Patch for V4.5 (v5)

CI: https://gitlab.catalyst.net.nz/samba/samba.org-security-patches/pipelines/203102

Tests not backported, manually tested that nested queries and large requests were rejected.
Comment 36 Andrew Bartlett 2020-04-17 08:06:36 UTC
Assigning to Karolin for the next security release.
Comment 37 Karolin Seeger 2020-04-18 16:33:36 UTC
Planned release date Tuesday, April 28th 2020.
Opening bug report for vendors.
Comment 38 Karolin Seeger 2020-04-28 10:37:28 UTC
Samba 4.12.2, 4.11.8 and 4.10.15 have been released to address this defect.
Comment 39 Karolin Seeger 2020-04-28 11:00:30 UTC
Pushed to autobuild-master.
Comment 40 Andrew Bartlett 2020-04-29 01:32:34 UTC
Removing embargo, vendors please CC yourself individually as I've removed the samba-vendor CC to avoid spamming you. 

Note a similar issue with OpenLDAP announced with 2.4.50 as ITS#9202 / CVE-2020-12243 here: 

https://lists.openldap.org/hyperkitty/list/openldap-announce@openldap.org/thread/FUOYA6YCHBXMLANBJMSO22JD2NB22WGC/
Comment 41 Karolin Seeger 2020-05-05 06:25:33 UTC
Pushed to all branches.
Closing out bug report.

Thanks!