Blame SOURCES/0029-Issue-4429-NULL-dereference-in-revert_cache.patch

5d2be4
From bc8bdaa57ba9b57671e2921705b99eaa70729ce7 Mon Sep 17 00:00:00 2001
5d2be4
From: Mark Reynolds <mreynolds@redhat.com>
5d2be4
Date: Wed, 11 Nov 2020 11:45:11 -0500
5d2be4
Subject: [PATCH 4/8] Issue 4429 - NULL dereference in revert_cache()
5d2be4
5d2be4
Bug Description:  During a delete, if the DN (with an escaped leading space)
5d2be4
                  of an existing entry fail to parse the server will revert
5d2be4
                  the entry update.  In this case it will lead to a crash
5d2be4
                  becuase ther ldbm inst struct is not set before it attempts
5d2be4
                  the cache revert.
5d2be4
5d2be4
Fix Description:  Check the the ldbm instance struct is not NULL before
5d2be4
                  dereferencing it.
5d2be4
5d2be4
Relates: https://github.com/389ds/389-ds-base/issues/4429
5d2be4
5d2be4
Reviewed by: firstyear & spichugi(Thanks!!)
5d2be4
---
5d2be4
 .../tests/suites/syntax/acceptance_test.py    | 40 +++++++++++++++++++
5d2be4
 ldap/servers/slapd/back-ldbm/cache.c          |  3 ++
5d2be4
 2 files changed, 43 insertions(+)
5d2be4
5d2be4
diff --git a/dirsrvtests/tests/suites/syntax/acceptance_test.py b/dirsrvtests/tests/suites/syntax/acceptance_test.py
5d2be4
index db8f63c7e..543718689 100644
5d2be4
--- a/dirsrvtests/tests/suites/syntax/acceptance_test.py
5d2be4
+++ b/dirsrvtests/tests/suites/syntax/acceptance_test.py
5d2be4
@@ -6,12 +6,14 @@
5d2be4
 # See LICENSE for details.
5d2be4
 # --- END COPYRIGHT BLOCK ---
5d2be4
 
5d2be4
+import ldap
5d2be4
 import logging
5d2be4
 import pytest
5d2be4
 import os
5d2be4
 from lib389.schema import Schema
5d2be4
 from lib389.config import Config
5d2be4
 from lib389.idm.user import UserAccounts
5d2be4
+from lib389.idm.group import Groups
5d2be4
 from lib389._constants import DEFAULT_SUFFIX
5d2be4
 from lib389.topologies import log, topology_st as topo
5d2be4
 
5d2be4
@@ -105,6 +107,44 @@ def test_invalid_uidnumber(topo, validate_syntax_off):
5d2be4
     log.info('Found an invalid entry with wrong uidNumber - Success')
5d2be4
 
5d2be4
 
5d2be4
+def test_invalid_dn_syntax_crash(topo):
5d2be4
+    """Add an entry with an escaped space, restart the server, and try to delete
5d2be4
+    it.  In this case the DN is not correctly parsed and causes cache revert to
5d2be4
+    to dereference a NULL pointer.  So the delete can fail as long as the server
5d2be4
+    does not crash.
5d2be4
+
5d2be4
+    :id: 62d87272-dfb8-4627-9ca1-dbe33082caf8
5d2be4
+    :setup: Standalone Instance
5d2be4
+    :steps:
5d2be4
+        1. Add entry with leading escaped space in the RDN
5d2be4
+        2. Restart the server so the entry is rebuilt from the database
5d2be4
+        3. Delete the entry
5d2be4
+        4. The server should still be running
5d2be4
+    :expectedresults:
5d2be4
+        1. Success
5d2be4
+        2. Success
5d2be4
+        3. Success
5d2be4
+        4. Success
5d2be4
+    """
5d2be4
+
5d2be4
+    # Create group
5d2be4
+    groups = Groups(topo.standalone, DEFAULT_SUFFIX)
5d2be4
+    group = groups.create(properties={'cn': ' test'})
5d2be4
+
5d2be4
+    # Restart the server
5d2be4
+    topo.standalone.restart()
5d2be4
+
5d2be4
+    # Delete group
5d2be4
+    try:
5d2be4
+        group.delete()
5d2be4
+    except ldap.NO_SUCH_OBJECT:
5d2be4
+        # This is okay in this case as we are only concerned about a crash
5d2be4
+        pass
5d2be4
+
5d2be4
+    # Make sure server is still running
5d2be4
+    groups.list()
5d2be4
+
5d2be4
+
5d2be4
 if __name__ == '__main__':
5d2be4
     # Run isolated
5d2be4
     # -s for DEBUG mode
5d2be4
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
5d2be4
index 89f958a35..5ad9ca829 100644
5d2be4
--- a/ldap/servers/slapd/back-ldbm/cache.c
5d2be4
+++ b/ldap/servers/slapd/back-ldbm/cache.c
5d2be4
@@ -614,6 +614,9 @@ flush_hash(struct cache *cache, struct timespec *start_time, int32_t type)
5d2be4
 void
5d2be4
 revert_cache(ldbm_instance *inst, struct timespec *start_time)
5d2be4
 {
5d2be4
+    if (inst == NULL) {
5d2be4
+        return;
5d2be4
+    }
5d2be4
     flush_hash(&inst->inst_cache, start_time, ENTRY_CACHE);
5d2be4
     flush_hash(&inst->inst_dncache, start_time, DN_CACHE);
5d2be4
 }
5d2be4
-- 
5d2be4
2.26.2
5d2be4