Tests for segfaults in python bindings
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Fri, 20 Apr 2018 04:28:29 +0000 (16:28 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 1 Feb 2019 02:36:17 +0000 (03:36 +0100)
These tests run in a child process and are regarded as succeeding if they
don't die by signal.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/segfault.py [new file with mode: 0644]
selftest/knownfail.d/python-segfaults [new file with mode: 0644]
source4/selftest/tests.py

diff --git a/python/samba/tests/segfault.py b/python/samba/tests/segfault.py
new file mode 100644 (file)
index 0000000..38dcb5c
--- /dev/null
@@ -0,0 +1,126 @@
+# Unix SMB/CIFS implementation.
+#
+# Copyright (C) Catalyst.Net Ltd. 2017
+#
+# 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/>.
+#
+
+"""Test whether various python calls segfault when given unexpected input.
+"""
+
+import samba.tests
+import os
+import sys
+from samba.net import Net, LIBNET_JOIN_AUTOMATIC
+from samba.credentials import DONT_USE_KERBEROS
+from samba import NTSTATUSError, ntstatus
+from samba.dcerpc import misc, drsuapi
+from samba import auth, gensec
+from samba.samdb import SamDB
+from samba import netbios
+from samba import registry
+from samba import ldb
+
+import traceback
+
+def segfault_detector(f):
+    def wrapper(*args, **kwargs):
+        pid = os.fork()
+        if pid == 0:
+            try:
+                f(*args, **kwargs)
+            except Exception as e:
+                traceback.print_exc()
+            sys.stderr.flush()
+            sys.stdout.flush()
+            os._exit(0)
+
+        pid2, status = os.waitpid(pid, 0)
+        signal = status & 255
+        if os.WIFSIGNALED(status):
+            signal = os.WTERMSIG(status)
+            raise AssertionError("Failed with signal %d" % signal)
+
+    return wrapper
+
+
+class SegfaultTests(samba.tests.TestCase):
+    def get_lp_et_al(self):
+        server = os.environ["SERVER"]
+        lp = self.get_loadparm()
+
+        creds = self.insta_creds(template=self.get_credentials(),
+                                 kerberos_state=DONT_USE_KERBEROS)
+        return lp, creds, server
+
+    def get_samdb(self):
+        lp, creds, server = self.get_lp_et_al()
+        url = 'ldap://' + server
+        ldb = SamDB(url, credentials=creds, lp=lp)
+        return ldb
+
+    @segfault_detector
+    def test_net_replicate_init__1(self):
+        lp, creds, server = self.get_lp_et_al()
+        net = Net(creds, lp, server=server)
+        net.replicate_init(42, lp, None, misc.GUID())
+
+    @segfault_detector
+    def test_net_replicate_init__3(self):
+        # third argument is also unchecked
+        samdb = self.get_samdb()
+        lp, creds, server = self.get_lp_et_al()
+        net = Net(creds, lp, server=server)
+        net.replicate_init(samdb, lp, 42, misc.GUID())
+
+    @segfault_detector
+    def test_net_replicate_chunk_1(self):
+        lp, creds, server = self.get_lp_et_al()
+        ctr = drsuapi.DsGetNCChangesCtr6()
+        net = Net(creds, lp, server=server)
+        net.replicate_chunk(42, 1, ctr)
+
+    @segfault_detector
+    def test_auth_context_gensec_start_server(self):
+        a = auth.AuthContext(ldb=42, methods=['sam'])
+        # there is no failure yet because the ldb is not actually
+        # dereferenced.
+        g = gensec.Security.start_server(auth_context=a)
+        # and still the ldb is not dereferenced...
+
+    @segfault_detector
+    def test_auth_user_session(self):
+        s = auth.user_session(ldb=42, principal='foo')
+
+    @segfault_detector
+    def test_gensec_start_server(self):
+        gensec.Security.start_server(auth_context=42)
+
+    @segfault_detector
+    def test_netbios_query_name(self):
+        n = netbios.Node()
+        t = n.query_name((42, 'foo'), 'localhost')
+
+    @segfault_detector
+    def test_encrypt_netr_crypt_password(self):
+        lp, creds, server = self.get_lp_et_al()
+        creds.encrypt_netr_crypt_password(42)
+
+    @segfault_detector
+    def test_hive_open_ldb(self):
+        # we don't need to provide a valid path because we segfault first
+        try:
+            registry.open_ldb('', credentials=42)
+        except ldb.LdbError as e:
+            print("failed with %s" % e)
diff --git a/selftest/knownfail.d/python-segfaults b/selftest/knownfail.d/python-segfaults
new file mode 100644 (file)
index 0000000..b1938cd
--- /dev/null
@@ -0,0 +1,8 @@
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_auth_user_session
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_encrypt_netr_crypt_password
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_gensec_start_server
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_hive_open_ldb
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_net_replicate_chunk_1
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_net_replicate_init__1
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_net_replicate_init__3
+samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_netbios_query_name
index 7f2226852c91a68fe5b3c392920ec7dcd5b600e9..8689cbba3a73a09cec578483343c27cbaf07fc8c 100755 (executable)
@@ -774,6 +774,9 @@ planoldpythontestsuite("ad_dc",
                        "samba.tests.net_join",
                        extra_args=['-U"$USERNAME%$PASSWORD"'],
                        py3_compatible=True)
+planoldpythontestsuite("ad_dc",
+                       "samba.tests.segfault",
+                       extra_args=['-U"$USERNAME%$PASSWORD"'])
 # Need to test the password hashing in multiple environments to ensure that
 # all the possible options are covered
 #