CVE-2022-2850 - Sync_repl may crash while managing invalid cookie (#5420) - Issue...
authortbordaz <tbordaz@redhat.com>
Thu, 18 Aug 2022 09:17:30 +0000 (11:17 +0200)
committerAndrej Shadura <andrewsh@debian.org>
Sun, 19 Jan 2025 12:30:31 +0000 (13:30 +0100)
Bug description:
If the servers receives an invalid cookie without separator '#',
it parses it into an empty cookie (Sync_Cookie) instead of a NULL
cookie (failure).
Later it sigsegv when using the empty cookie.

Fix description:
If the parsing fails return NULL

relates: #5418

Reviewed by: Viktor Ashirov, Mark Reynolds, William Brown, Simon
 Pichugin (thanks !)

Origin: backport, commit:513a763b551848e5532ec22bb0086464aa09252f

Gbp-Pq: Name CVE-2022-2850-Sync_repl-may-crash-with-invalid-cookie.patch

dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
ldap/servers/plugins/sync/sync_util.c

index 04c0a09857c1d54bd28d3db3d8245890ce3cc8cc..1ca88c1a2c90f3bff70c9752d44f6bb3e54d8bc7 100644 (file)
@@ -526,3 +526,79 @@ def test_sync_repl_cookie_with_failure(topology, init_sync_repl_plugins, request
         testgroup.delete()
 
     request.addfinalizer(fin)
+
+def test_sync_repl_invalid_cookie(topology, request):
+    """Test sync_repl with invalid cookie
+
+    :id: 8fa4a8f8-acf4-42a5-90f1-6ba1d8080e46
+    :setup: install a standalone instance
+    :steps:
+        1. reset instance to standard (no retroCL, no sync_repl, no dynamic plugin)
+        2. Enable retroCL/content_sync
+        3. Establish a sync_repl connection
+        4. Tests servers results to search with invalid cookie
+        5. Add/delete an user entry to check the server is up and running
+    :expectedresults:
+        1. Should succeeds
+        2. Should succeeds
+        3. Should succeeds
+        4. Should succeeds
+        5. Should succeeds
+    """
+
+    # Reset the instance in a default config
+    # Disable content sync plugin
+    topology.standalone.restart()
+    topology.standalone.plugins.disable(name=PLUGIN_REPL_SYNC)
+
+    # Disable retro changelog
+    topology.standalone.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
+
+    # Disable dynamic plugins
+    topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', b'off')])
+    topology.standalone.restart()
+
+    # Enable retro changelog
+    topology.standalone.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+
+    # Enbale content sync plugin
+    topology.standalone.plugins.enable(name=PLUGIN_REPL_SYNC)
+    topology.standalone.restart()
+
+    # Setup the syncer
+    sync = ISyncRepl(topology.standalone)
+
+    # Test invalid cookies
+    cookies = ('#', '##', 'a#a#a', 'a#a#1', 'foo')
+    for invalid_cookie in cookies:
+        log.info('Testing cookie: %s' % invalid_cookie)
+        try:
+            ldap_search = sync.syncrepl_search(base=DEFAULT_SUFFIX,
+                                               scope=ldap.SCOPE_SUBTREE,
+                                               attrlist=['objectclass', 'cn', 'homedirectory', 'sn','uid'],
+                                               filterstr='(|(objectClass=groupofnames)(objectClass=person))',
+                                               mode='refreshOnly',
+                                               cookie=invalid_cookie)
+            poll_result = sync.syncrepl_poll(all=1)
+
+            log.fatal('Invalid cookie accepted!')
+            assert False
+        except Exception as e:
+            log.info('Invalid cookie correctly rejected: {}'.format(e.args[0]['info']))
+            pass
+
+    # check that the server is still up and running
+    users = UserAccounts(topology.standalone, DEFAULT_SUFFIX)
+    user = users.create_test_user(uid=1000)
+
+    # Success
+    log.info('Test complete')
+
+    def fin():
+        topology.standalone.restart()
+        try:
+            user.delete()
+        except:
+            pass
+
+    request.addfinalizer(fin)
index d84705a41ae32e38502c32662a42e9d08ba8946e..5ebf5f2bc3d112123a45ecbf26796dbf86c46649 100644 (file)
@@ -775,6 +775,8 @@ sync_cookie_parse(char *cookie, PRBool *cookie_refresh, PRBool *allow_openldap_c
             } else {
                 goto error_return;
             }
+        } else {
+            goto error_return;
         }
     }
     return (sc);