The branch, master has been updated
       via  f38077ea5ee pidl: Handle obtaining objects from a fixed-size array
       via  1261894ecae pidl/python: allocate objects with ref pointers
       via  7e19779b66d pytests/segfault: pidl inline arrays
       via  272e20adbbb pytests/segfaults: dcerpc ref elements segfault
       via  4dd725b1b59 pytests: rpc echo should not segfault
       via  220cf67776f s4/rpc/dcerpc_connect: no crash on NULL dest_host
      from  963a639101f ctdb-tests: Add tests for cmdline_add() api

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f38077ea5ee0a8d3d18970e3e183c3ee516fa121
Author: Andrew Bartlett <abart...@samba.org>
Date:   Tue Oct 29 21:19:05 2019 +0000

    pidl: Handle obtaining objects from a fixed-size array
    
    Previously we would assume the array head was the talloc context
    however this is not the case if the array is a fixed size inline array
    within the parent struct.
    
    In that case the overall object's talloc context is the correct
    context to reference.
    
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Pair-programmed-with: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Noel Power <npo...@samba.org>
    
    Autobuild-User(master): Noel Power <npo...@samba.org>
    Autobuild-Date(master): Thu Nov 14 17:36:49 UTC 2019 on sn-devel-184

commit 1261894ecaebc1a3340c42e818be25caa69f6364
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Tue Oct 29 11:58:32 2019 +1300

    pidl/python: allocate objects with ref pointers
    
    Struct members that are marked as ref pointers need to have an object
    allocated for them.
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abart...@samba.org>
    Signed-off-by: Andrew Bartlett <abart...@samba.org>
    Reviewed-by: Noel Power <npo...@samba.org>

commit 7e19779b66d7329e4208eaa5801cec0b6feb3754
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Tue Oct 29 22:11:41 2019 +0000

    pytests/segfault: pidl inline arrays
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Noel Power <npo...@samba.org>

commit 272e20adbbbaebd7bbf94c79f44f1ff42d2831d8
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Tue Oct 29 12:02:04 2019 +1300

    pytests/segfaults: dcerpc ref elements segfault
    
    These are just a couple of examples.
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Noel Power <npo...@samba.org>

commit 4dd725b1b599968fb787c93f6eb3a42af007b21c
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Thu Oct 24 10:41:28 2019 +1300

    pytests: rpc echo should not segfault
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Noel Power <npo...@samba.org>

commit 220cf67776f16467488805ecd6d1905c708eaa17
Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
Date:   Wed Jul 24 17:50:35 2019 +1200

    s4/rpc/dcerpc_connect: no crash on NULL dest_host
    
    Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    Reviewed-by: Noel Power <npo...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 pidl/lib/Parse/Pidl/Samba4/Python.pm | 63 ++++++++++++++++++++++++++++++++++--
 python/samba/tests/segfault.py       | 24 +++++++++++++-
 source4/librpc/rpc/dcerpc_connect.c  |  2 +-
 3 files changed, 85 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm 
b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 8d5de31e7bb..161521c6e3a 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -499,7 +499,62 @@ sub PythonFunctionStruct($$$$)
        $self->pidl("static PyObject *py_$name\_new(PyTypeObject *type, 
PyObject *args, PyObject *kwargs)");
        $self->pidl("{");
        $self->indent;
-       $self->pidl("return pytalloc_new($cname, type);");
+
+       # This creates a new, zeroed C structure and python object.
+       # Thse may not be valid or sensible values, but this is as
+       # well as we can do.
+
+       $self->pidl("PyObject *self = pytalloc_new($cname, type);");
+
+       # If there are any children that are ref pointers, we need to
+       # allocate something for them to point to just as the pull
+       # routine will when parsing the stucture from NDR.
+       #
+       # We then make those pointers point to zeroed memory
+       #
+       # A ref pointer is a pointer in the C structure but a scalar
+       # on the wire. It is for a remote function like:
+       #
+       # int foo(int *i)
+       #
+       # This may be called with the pointer by reference eg foo(&i)
+       #
+       # That is why this only goes as far as the next level; deeply
+       # nested pointer chains will end in a NULL.
+
+       my @ref_elements;
+       foreach my $e (@{$fn->{ELEMENTS}}) {
+               if (has_property($e, "ref") && ! has_property($e, "charset")) {
+                       if (!has_property($e, 'in') && !has_property($e, 
'out')) {
+                               die "ref pointer that is not in or out";
+                       }
+                       push @ref_elements, $e;
+               }
+       }
+       if (@ref_elements) {
+               $self->pidl("$cname *_self = ($cname 
*)pytalloc_get_ptr(self);");
+               $self->pidl("TALLOC_CTX *mem_ctx = 
pytalloc_get_mem_ctx(self);");
+               foreach my $e (@ref_elements) {
+                       my $ename = $e->{NAME};
+                       my $t = mapTypeName($e->{TYPE});
+                       my $p = $e->{ORIGINAL}->{POINTERS} // 1;
+                       if ($p > 1) {
+                               $self->pidl("/* a pointer to a NULL pointer 
*/");
+                               $t .= ' ' . '*' x ($p - 1);
+                       }
+
+                       # We checked in the loop above that each ref
+                       # pointer is in or out (or both)
+                       if (has_property($e, 'in')) {
+                               $self->pidl("_self->in.$ename = 
talloc_zero(mem_ctx, $t);");
+                       }
+
+                       if (has_property($e, 'out')) {
+                               $self->pidl("_self->out.$ename = 
talloc_zero(mem_ctx, $t);");
+                       }
+               }
+       }
+       $self->pidl("return self;");
        $self->deindent;
        $self->pidl("}");
        $self->pidl("");
@@ -2234,7 +2289,11 @@ sub ConvertObjectToPythonLevel($$$$$$$)
                        $self->indent;
                        my $member_var = "py_$e->{NAME}_$l->{LEVEL_INDEX}";
                        $self->pidl("PyObject *$member_var;");
-                       $self->ConvertObjectToPythonLevel($var_name, $env, $e, 
$nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+                       if (ArrayDynamicallyAllocated($e, $l)) {
+                               $self->ConvertObjectToPythonLevel($var_name, 
$env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+                       } else {
+                               $self->ConvertObjectToPythonLevel($mem_ctx, 
$env, $e, $nl, $var_name."[$counter]", $member_var, $fail, $recurse);
+                       }
                        $self->pidl("PyList_SetItem($py_var, $counter, 
$member_var);");
                        $self->deindent;
                        $self->pidl("}");
diff --git a/python/samba/tests/segfault.py b/python/samba/tests/segfault.py
index 66c0b1004c9..07e2d46d56a 100644
--- a/python/samba/tests/segfault.py
+++ b/python/samba/tests/segfault.py
@@ -25,7 +25,7 @@ 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.dcerpc import misc, drsuapi, samr, unixinfo, dnsserver
 from samba import auth, gensec
 from samba.samdb import SamDB
 from samba import netbios
@@ -152,3 +152,25 @@ class SegfaultTests(samba.tests.TestCase):
     @segfault_detector
     def test_messaging_deregister(self):
         messaging.deregister('s', 's', 's', False)
+
+    @segfault_detector
+    def test_rpcecho(self):
+        from dcerpc import echo
+        echo.rpcecho("")
+
+    @segfault_detector
+    def test_dcerpc_idl_ref_elements(self):
+        """There are many pidl generated functions that crashed on this
+        pattern, where a NULL pointer was created rather than an empty
+        structure."""
+        samr.Connect5().out_info_out = 1
+
+    @segfault_detector
+    def test_dcerpc_idl_unixinfo_elements(self):
+        """Dereferencing is sufficient to crash"""
+        unixinfo.GetPWUid().out_infos
+
+    @segfault_detector
+    def test_dcerpc_idl_inline_arrays(self):
+        """Inline arrays were incorrectly handled."""
+        dnsserver.DNS_RPC_SERVER_INFO_DOTNET().pExtensions
diff --git a/source4/librpc/rpc/dcerpc_connect.c 
b/source4/librpc/rpc/dcerpc_connect.c
index 4c0ed15396f..ad355fc3c4d 100644
--- a/source4/librpc/rpc/dcerpc_connect.c
+++ b/source4/librpc/rpc/dcerpc_connect.c
@@ -226,7 +226,7 @@ static struct composite_context 
*dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT
                target_hostname = conn->in.dest_host;
        }
 
-       if (is_ipaddress(conn->in.dest_host)) {
+       if (conn->in.dest_host != NULL && is_ipaddress(conn->in.dest_host)) {
                dest_address = conn->in.dest_host;
        }
 


-- 
Samba Shared Repository

Reply via email to